root / acct_radius.c @ 597

View | Annotate | Download

1
/* acct_radius.c */
2
3
/* libradius.so */
4
#include <radlib.h>
5
6
#include "aconfig.h"
7
#include "nntpd.h"
8
#include "aprotos.h"
9
10
PROTO void acct_radius(CLIENT *client, CONFIG *cfg, char *args)
11
{
12
        char hostname[128];
13
        char server[128];
14
        char secret[128];
15
        char sessionid[256];
16
        struct servent *rport;
17
        struct rad_handle *rada;
18
        int ret;
19
        int port;
20
        struct in_addr c_ip;
21
        struct sockaddr_in svraddr;
22
        socklen_t svraddrlen = sizeof(svraddr);
23
24
        if ( sscanf(args, "%128[^:]:%s", server, secret) != 2 )
25
        {
26
                syslog(LOG_ERR,"Wrong argument syntax %s for acct_radius", args);
27
                return;
28
        }
29
                            
30
        if ( !(rada = rad_acct_open()) )
31
        {
32
                syslog(LOG_ERR, "acct_radius: rad_acct_open failed");
33
                return;
34
        }
35
36
        if ((rport = getservbyname("radius-acct", "udp")) != NULL ) 
37
                port = ntohs(rport->s_port);
38
        else
39
                port = 1813;
40
41
        /* TODO make config options; 2 = timeout 5 = max_tries */
42
        if (rad_add_server (rada, server, port, secret, 2, 5) < 0)
43
        {
44
                syslog(LOG_ERR, "acct_radius: rad_add_server failed");
45
                return;
46
        }
47
48
        if (rad_create_request(rada, RAD_ACCOUNTING_REQUEST) < 0) 
49
        {
50
                syslog(LOG_ERR, "acct_radius: rad_create_request failed");
51
                return;
52
        }
53
54
        /* create all the accounting attributes */
55
56
        gethostname(hostname, 128);
57
        c_ip.s_addr = htonl((long) client->ip4addr);
58
        sprintf(sessionid, "%u:%u", (int)getpid(), client->id);
59
        getsockname(client->socket, (struct sockaddr *) &svraddr, &svraddrlen);
60
61
        /* TODO  on/off controlled by config.
62
        // Some radius servers require RAD_NAS_PORT(_TYPE) and some forbid it.
63
        */
64
        /* rad_put_int(rada,RAD_NAS_PORT,        client->id + 1 );
65
        // rad_put_int(rada,RAD_NAS_PORT_TYPE,        RAD_VIRTUAL);
66
        */
67
        rad_put_addr(rada,RAD_NAS_IP_ADDRESS,        svraddr.sin_addr);
68
        rad_put_string(rada,RAD_NAS_IDENTIFIER,        hostname);
69
        rad_put_int(rada,RAD_ACCT_STATUS_TYPE,        RAD_STOP);
70
71
        /* Some RADIUS servers drop the accounting packet
72
        // if the RAD_ACCT_AUTHENTIC attribute is not specified.
73
        // RFC 2139 says:
74
        //                 The attribute is optional.
75
        //                Its value could be RAD_AUTH_REMOTE or RADIUS or LOCAL.
76
        //                Users who are delivered service without being authenticated
77
        //                SHOULD NOT generate Accounting records.
78
        */
79
        /* rad_put_int(rada, RAD_ACCT_AUTHENTIC,        RAD_AUTH_RADIUS); */
80
        rad_put_string(rada,RAD_ACCT_SESSION_ID,        sessionid); 
81
        rad_put_string(rada,RAD_USER_NAME,                client->username);
82
        rad_put_addr(rada,RAD_FRAMED_IP_ADDRESS,        c_ip);
83
        rad_put_int(rada,RAD_ACCT_SESSION_TIME,                time(NULL) - client->starttime);
84
        rad_put_int(rada,RAD_ACCT_INPUT_OCTETS,                client->postbytes);
85
        rad_put_int(rada,RAD_ACCT_INPUT_PACKETS,        client->posts);
86
        rad_put_int(rada,RAD_ACCT_OUTPUT_OCTETS,        client->bytes);
87
        rad_put_int(rada,RAD_ACCT_OUTPUT_PACKETS,        client->articles);
88
89
        switch( ret = rad_send_request(rada) ) 
90
        {
91
                case RAD_ACCOUNTING_RESPONSE:
92
                        break;
93
                default:
94
                        syslog(LOG_ERR
95
                                , "acct_radius: accounting vanished"
96
                                ", rad_send_request result was %d", ret);
97
        }
98
}
99