mirror of
https://github.com/3proxy/3proxy.git
synced 2025-02-24 02:55:40 +08:00
RADIUS accounting added (not optimized yet)
This commit is contained in:
parent
8702a4c7ab
commit
4a553de100
104
src/authradius.c
104
src/authradius.c
@ -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;
|
||||||
@ -476,6 +519,12 @@ int radsend(struct clientparam * param, int auth){
|
|||||||
|
|
||||||
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
|
||||||
|
12
src/conf.c
12
src/conf.c
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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];
|
||||||
|
Loading…
Reference in New Issue
Block a user