RADIUS accounting added (not optimized yet)

This commit is contained in:
z3APA3A 2017-12-19 01:22:07 +03:00
parent 8702a4c7ab
commit 4a553de100
4 changed files with 95 additions and 28 deletions

View File

@ -198,6 +198,9 @@ void md5_calc(unsigned char *output, unsigned char *input,
static uint8_t random_vector_pool[AUTH_VECTOR_LEN*2]; static uint8_t random_vector_pool[AUTH_VECTOR_LEN*2];
static int calc_replydigest(char *packet, char *original, const char *secret, int len) static int calc_replydigest(char *packet, char *original, const char *secret, int len)
{ {
int secretlen; int secretlen;
@ -295,7 +298,7 @@ typedef struct radius_packet_t {
#define RETURN(xxx) { res = xxx; goto CLEANRET; } #define RETURN(xxx) { res = xxx; goto CLEANRET; }
int radsend(struct clientparam * param, int auth){ int radsend(struct clientparam * param, int auth, int stop){
int loop; int loop;
int id; int id;
@ -320,6 +323,7 @@ int radsend(struct clientparam * param, int auth){
uint8_t *attr; uint8_t *attr;
long vendor=0; long vendor=0;
int vendorlen=0; int vendorlen=0;
char buf[64];
if(!radiussecret || !nradservers) { if(!radiussecret || !nradservers) {
@ -328,28 +332,34 @@ int radsend(struct clientparam * param, int auth){
memset(&packet, 0, sizeof(packet)); memset(&packet, 0, sizeof(packet));
pthread_mutex_lock(&rad_mutex); pthread_mutex_lock(&rad_mutex);
random_vector(packet.vector, param); if(auth)random_vector(packet.vector, param);
id = ((ntry++) & 0xff); id = ((ntry++) & 0xff);
pthread_mutex_unlock(&rad_mutex); pthread_mutex_unlock(&rad_mutex);
packet.code = PW_AUTHENTICATION_REQUEST; packet.code = auth?PW_AUTHENTICATION_REQUEST:PW_ACCOUNTING_REQUEST;
packet.id=id; packet.id=id;
ptr = packet.data; ptr = packet.data;
total_length = 0; total_length = 0;
md5_calc(packet.vector, packet.vector,
sizeof(packet.vector));
/* Service Type */ /* Service Type */
*ptr++ = PW_SERVICE_TYPE; *ptr++ = auth?PW_SERVICE_TYPE:PW_ACCT_STATUS_TYPE;
*ptr++ = 6; *ptr++ = 6;
(*(uint32_t *)ptr)=htonl(PW_AUTHENTICATE_ONLY); (*(uint32_t *)ptr)=htonl(auth?PW_AUTHENTICATE_ONLY:stop?PW_STATUS_STOP:PW_STATUS_START);
ptr+=4; ptr+=4;
total_length+=6; total_length+=6;
/* Acct-Session-Id */
sprintf(buf, "%u.%u.%u", (unsigned)param->time_start, (unsigned)param->msec_start, (unsigned)param->threadid);
len = strlen(buf);
*ptr++ = PW_ACCT_SESSION_ID;
*ptr++ = 2+len;
memcpy(ptr, buf, len);
ptr+=len;
total_length+=len+2;
/* NAS-Port-Type */ /* NAS-Port-Type */
*ptr++ = PW_NAS_PORT_TYPE; *ptr++ = PW_NAS_PORT_TYPE;
*ptr++ = 6; *ptr++ = 6;
@ -459,7 +469,40 @@ int radsend(struct clientparam * param, int auth){
total_length += (len+2); total_length += (len+2);
} }
if(param->password){ if(stop){
/* Acct-Input-Octets */
*ptr++ = PW_ACCT_INPUT_OCTETS;
*ptr++ = 6;
(*(uint32_t *)ptr)=htonl((uint32_t)param->statssrv64);
ptr+=4;
total_length+=6;
/* Acct-Output-Octets */
*ptr++ = PW_ACCT_OUTPUT_OCTETS;
*ptr++ = 6;
(*(uint32_t *)ptr)=htonl((uint32_t)param->statscli64);
ptr+=4;
total_length+=6;
/* Acct-Input-Packets */
*ptr++ = PW_ACCT_INPUT_PACKETS;
*ptr++ = 6;
(*(uint32_t *)ptr)=htonl((uint32_t)param->nreads);
ptr+=4;
total_length+=6;
/* Acct-Output-Packets */
*ptr++ = PW_ACCT_OUTPUT_PACKETS;
*ptr++ = 6;
(*(uint32_t *)ptr)=htonl((uint32_t)param->nwrites);
ptr+=4;
total_length+=6;
/* Acct-Session-Time */
*ptr++ = PW_ACCT_SESSION_TIME;
*ptr++ = 6;
(*(uint32_t *)ptr)=htonl((uint32_t)(time(0) - param->time_start));
ptr+=4;
total_length+=6;
}
if(auth && param->password){
len = strlen(param->password); len = strlen(param->password);
if(len > 128) len = 128; if(len > 128) len = 128;
*ptr++ = PW_PASSWORD; *ptr++ = PW_PASSWORD;
@ -473,9 +516,15 @@ int radsend(struct clientparam * param, int auth){
ptr+=len; ptr+=len;
total_length+= (len+2); total_length+= (len+2);
} }
total_length+=(4+AUTH_VECTOR_LEN); total_length+=(4+AUTH_VECTOR_LEN);
packet.length = htons(total_length); packet.length = htons(total_length);
if(!auth){
len = strlen(radiussecret);
memcpy(ptr,radiussecret,len);
md5_calc(packet.vector, (u_char *)&packet, total_length + len);
}
memcpy(vector, packet.vector, AUTH_VECTOR_LEN); memcpy(vector, packet.vector, AUTH_VECTOR_LEN);
for (loop = 0; loop < nradservers && loop < MAXRADIUS; loop++) { for (loop = 0; loop < nradservers && loop < MAXRADIUS; loop++) {
@ -492,15 +541,19 @@ int radsend(struct clientparam * param, int auth){
continue; continue;
} }
#endif #endif
packet.id++;
/*
if(auth) { if(auth) {
*/
if(sockfd >= 0) so._closesocket(sockfd); if(sockfd >= 0) so._closesocket(sockfd);
if ((sockfd = so._socket(SASOCK(&saremote), SOCK_DGRAM, 0)) < 0) { if ((sockfd = so._socket(SASOCK(&saremote), SOCK_DGRAM, 0)) < 0) {
return 4; return 4;
} }
remsock = sockfd; remsock = sockfd;
/*
} }
else remsock = radiuslist[loop].logsock; else remsock = radiuslist[loop].logsock;
*/
len = so._sendto(remsock, (char *)&packet, total_length, 0, len = so._sendto(remsock, (char *)&packet, total_length, 0,
(struct sockaddr *)&saremote, sizeof(saremote)); (struct sockaddr *)&saremote, sizeof(saremote));
if(len != ntohs(packet.length)){ if(len != ntohs(packet.length)){
@ -524,10 +577,13 @@ int radsend(struct clientparam * param, int auth){
continue; continue;
} }
if( rpacket.code != PW_AUTHENTICATION_ACK && if( auth && rpacket.code != PW_AUTHENTICATION_ACK &&
rpacket.code != PW_AUTHENTICATION_REJECT ){ rpacket.code != PW_AUTHENTICATION_REJECT ){
continue; continue;
} }
if( !auth && rpacket.code != PW_ACCOUNTING_RESPONSE){
continue;
}
if (calc_replydigest((char *)&rpacket, packet.vector, radiussecret, if (calc_replydigest((char *)&rpacket, packet.vector, radiussecret,
data_len) ){ data_len) ){
@ -539,6 +595,8 @@ int radsend(struct clientparam * param, int auth){
continue; continue;
} }
if(!auth) RETURN(0);
attr = rpacket.data; attr = rpacket.data;
count = total_length - 20; count = total_length - 20;
vendor_len = 0; vendor_len = 0;
@ -575,18 +633,6 @@ int radsend(struct clientparam * param, int auth){
for(len = 2; len < attr[1] && isdigit(attr[len]); len++) res = (res * 10) + (attr[len] - '0'); for(len = 2; len < attr[1] && isdigit(attr[len]); len++) res = (res * 10) + (attr[len] - '0');
} }
/*
else if (vendor == SANDY && attr[0] == SANDY_MAIL_MAILBOX) {
memcpy (p->drop_name, attr + 2, attr[1] - 2);
}
else if (vendor == SANDY && attr[0] == SANDY_MAIL_MBOXCONTROL) {
if (ntohl(*(int *)(attr+2)) & 1) p->dodeletes = 1;
}
else if (vendor == SANDY && attr[0] == SANDY_MAIL_SERVICE) {
mailservice = ntohl(*(int *)(attr+2)) ;
}
*/
count -= attr[1]; count -= attr[1];
if(vendorlen) { if(vendorlen) {
vendorlen -= attr[1]; vendorlen -= attr[1];
@ -610,8 +656,16 @@ CLEANRET:
} }
int radauth(struct clientparam * param){ int radauth(struct clientparam * param){
return radsend(param, 1); /*radsend(param, 0, 0);*/
return radsend(param, 1, 0);
}
void logradius(struct clientparam * param, const unsigned char *s) {
radsend(param, 0, 1);
if(param->trafcountfunc)(*param->trafcountfunc)(param);
clearstat(param);
} }
#endif #endif

View File

@ -327,6 +327,9 @@ static int h_log(int argc, unsigned char ** argv){
conf.logfunc = logsql; conf.logfunc = logsql;
} }
#endif #endif
else if(!strcmp(argv[1],"radius")){
conf.logfunc = logradius;
}
else { else {
FILE *fp; FILE *fp;
if(argc > 2) { if(argc > 2) {
@ -1272,13 +1275,15 @@ static int h_delimchar(int argc, unsigned char **argv){
static int h_radius(int argc, unsigned char **argv){ static int h_radius(int argc, unsigned char **argv){
unsigned short port;
/*
int oldrad; int oldrad;
#ifdef NOIPV6 #ifdef NOIPV6
struct sockaddr_in bindaddr; struct sockaddr_in bindaddr;
#else #else
struct sockaddr_in6 bindaddr; struct sockaddr_in6 bindaddr;
#endif #endif
unsigned short port;
oldrad = nradservers; oldrad = nradservers;
nradservers = 0; nradservers = 0;
@ -1286,6 +1291,7 @@ static int h_radius(int argc, unsigned char **argv){
if(radiuslist[oldrad].logsock >= 0) so._closesocket(radiuslist[oldrad].logsock); if(radiuslist[oldrad].logsock >= 0) so._closesocket(radiuslist[oldrad].logsock);
radiuslist[oldrad].logsock = -1; radiuslist[oldrad].logsock = -1;
} }
*/
memset(radiuslist, 0, sizeof(radiuslist)); memset(radiuslist, 0, sizeof(radiuslist));
if(strlen(argv[1]) > 63) argv[1][63] = 0; if(strlen(argv[1]) > 63) argv[1][63] = 0;
strcpy(radiussecret, argv[1]); strcpy(radiussecret, argv[1]);
@ -1294,10 +1300,12 @@ static int h_radius(int argc, unsigned char **argv){
if(!*SAPORT(&radiuslist[nradservers].authaddr))*SAPORT(&radiuslist[nradservers].authaddr) = htons(1812); if(!*SAPORT(&radiuslist[nradservers].authaddr))*SAPORT(&radiuslist[nradservers].authaddr) = htons(1812);
port = ntohs(*SAPORT(&radiuslist[nradservers].authaddr)); port = ntohs(*SAPORT(&radiuslist[nradservers].authaddr));
radiuslist[nradservers].logaddr = radiuslist[nradservers].authaddr; radiuslist[nradservers].logaddr = radiuslist[nradservers].authaddr;
*SAPORT(&radiuslist[nradservers].logaddr) = htons(port); *SAPORT(&radiuslist[nradservers].logaddr) = htons(port+1);
/*
bindaddr = conf.intsa; bindaddr = conf.intsa;
if ((radiuslist[nradservers].logsock = so._socket(SASOCK(&radiuslist[nradservers].logaddr), SOCK_DGRAM, 0)) < 0) return 2; if ((radiuslist[nradservers].logsock = so._socket(SASOCK(&radiuslist[nradservers].logaddr), SOCK_DGRAM, 0)) < 0) return 2;
if (so._bind(radiuslist[nradservers].logsock, (struct sockaddr *)&bindaddr, SASIZE(&bindaddr))) return 3; if (so._bind(radiuslist[nradservers].logsock, (struct sockaddr *)&bindaddr, SASIZE(&bindaddr))) return 3;
*/
} }
return 0; return 0;
} }

View File

@ -520,6 +520,7 @@ static void * ef_server_childcount(struct node * node){
static void * ef_server_log(struct node * node){ static void * ef_server_log(struct node * node){
if(((struct srvparam *)node->value) -> logfunc == lognone) return "none"; if(((struct srvparam *)node->value) -> logfunc == lognone) return "none";
else if(((struct srvparam *)node->value) -> logfunc == logradius) return "radius";
else if(((struct srvparam *)node->value) -> logfunc == logstdout) else if(((struct srvparam *)node->value) -> logfunc == logstdout)
return (((struct srvparam *)node->value) -> logtarget)?"file":"stdout"; return (((struct srvparam *)node->value) -> logtarget)?"file":"stdout";
#ifndef _WIN32 #ifndef _WIN32

View File

@ -177,6 +177,8 @@ extern FILE * stdlog;
void logstdout(struct clientparam * param, const unsigned char *s); void logstdout(struct clientparam * param, const unsigned char *s);
void logsyslog(struct clientparam * param, const unsigned char *s); void logsyslog(struct clientparam * param, const unsigned char *s);
void lognone(struct clientparam * param, const unsigned char *s); void lognone(struct clientparam * param, const unsigned char *s);
void logradius(struct clientparam * param, const unsigned char *s);
#ifndef NOSQL #ifndef NOSQL
void logsql(struct clientparam * param, const unsigned char *s); void logsql(struct clientparam * param, const unsigned char *s);
int init_sql(char * s); int init_sql(char * s);
@ -339,7 +341,9 @@ extern struct radserver {
#else #else
struct sockaddr_in6 authaddr, logaddr; struct sockaddr_in6 authaddr, logaddr;
#endif #endif
/*
SOCKET logsock; SOCKET logsock;
*/
} radiuslist[MAXRADIUS]; } radiuslist[MAXRADIUS];
extern char radiussecret[64]; extern char radiussecret[64];