home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 35 Internet
/
35-Internet.zip
/
radius-2.zip
/
src
/
acct.c
next >
Wrap
C/C++ Source or Header
|
1994-12-27
|
5KB
|
218 lines
/*
*
* RADIUS Accounting
* Remote Authentication Dial In User Service
*
*
* Livingston Enterprises, Inc.
* 6920 Koll Center Parkway
* Pleasanton, CA 94566
*
* Copyright 1992 - 1994 Livingston Enterprises, Inc.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose and without fee is hereby granted, provided that this
* copyright and permission notice appear on all copies and supporting
* documentation, the name of Livingston Enterprises, Inc. not be used
* in advertising or publicity pertaining to distribution of the
* program without specific prior permission, and notice be given
* in supporting documentation that copying and distribution is by
* permission of Livingston Enterprises, Inc.
*
* Livingston Enterprises, Inc. makes no representations about
* the suitability of this software for any purpose. It is
* provided "as is" without express or implied warranty.
*
*/
static char sccsid[] =
"@(#)acct.c 1.6 Copyright 1994 Livingston Enterprises Inc";
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <stdio.h>
#include <netdb.h>
#include <pwd.h>
#include <time.h>
#include <ctype.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#include "radius.h"
extern char recv_buffer[4096];
extern char send_buffer[4096];
extern char *progname;
extern int debug_flag;
extern char *radacct_dir;
extern char *radius_dir;
extern UINT4 expiration_seconds;
extern UINT4 warning_seconds;
extern int errno;
UINT4 calctime();
rad_accounting(authreq, activefd)
AUTH_REQ *authreq;
int activefd;
{
FILE *outfd;
char *ip_hostname();
char clientname[128];
char buffer[512];
VALUE_PAIR *pair;
long curtime;
strcpy(clientname, ip_hostname(authreq->ipaddr));
/*
* Create a directory for this client.
*/
sprintf(buffer, "%s/%s", radacct_dir, clientname);
mkdir(buffer, 0755);
/*
* Write Detail file.
*/
sprintf(buffer, "%s/%s/detail", radacct_dir, clientname);
if((outfd = fopen(buffer, "a")) == (FILE *)NULL) {
sprintf(buffer,
"Acct: Couldn't open file %s/%s/detail\n",
radacct_dir, clientname);
log_err(buffer);
/* don't respond if we can't save record */
} else {
/* Post a timestamp */
curtime = time(0);
fputs(ctime(&curtime), outfd);
/* Write each attribute/value to the log file */
pair = authreq->request;
while(pair != (VALUE_PAIR *)NULL) {
fputs("\t", outfd);
fprint_attr_val(outfd, pair);
fputs("\n", outfd);
pair = pair->next;
}
fputs("\n", outfd);
fclose(outfd);
/* let NAS know it is OK to delete from buffer */
send_acct_reply(authreq, (VALUE_PAIR *)NULL,
(char *)NULL,activefd);
}
pairfree(authreq->request);
memset(authreq, 0, sizeof(AUTH_REQ));
free(authreq);
return;
}
/*************************************************************************
*
* Function: send_acct_reply
*
* Purpose: Reply to the request with an ACKNOWLEDGE. Also attach
* reply attribute value pairs and any user message provided.
*
*************************************************************************/
send_acct_reply(authreq, reply, msg, activefd)
AUTH_REQ *authreq;
VALUE_PAIR *reply;
char *msg;
int activefd;
{
AUTH_HDR *auth;
u_short total_length;
struct sockaddr_in saremote;
struct sockaddr_in *sin;
u_char *ptr;
int len;
UINT4 lvalue;
u_char digest[16];
int secretlen;
char *ip_hostname();
auth = (AUTH_HDR *)send_buffer;
/* Build standard header */
auth->code = PW_ACCOUNTING_RESPONSE;
auth->id = authreq->id;
memcpy(auth->vector, authreq->vector, AUTH_VECTOR_LEN);
DEBUG("Sending Accounting Ack of id %d to %lx (%s)\n",
authreq->id, authreq->ipaddr, ip_hostname(authreq->ipaddr));
total_length = AUTH_HDR_LEN;
/* Load up the configuration values for the user */
ptr = auth->data;
while(reply != (VALUE_PAIR *)NULL) {
debug_pair(stdout, reply);
*ptr++ = reply->attribute;
switch(reply->type) {
case PW_TYPE_STRING:
len = strlen(reply->strvalue);
*ptr++ = len + 2;
strcpy(ptr, reply->strvalue);
ptr += len;
total_length += len + 2;
break;
case PW_TYPE_INTEGER:
case PW_TYPE_IPADDR:
*ptr++ = sizeof(UINT4) + 2;
lvalue = htonl(reply->lvalue);
memcpy(ptr, &lvalue, sizeof(UINT4));
ptr += sizeof(UINT4);
total_length += sizeof(UINT4) + 2;
break;
default:
break;
}
reply = reply->next;
}
/* Append the user message */
if(msg != (char *)NULL) {
len = strlen(msg);
if(len > 0 && len < AUTH_STRING_LEN) {
*ptr++ = PW_PORT_MESSAGE;
*ptr++ = len + 2;
memcpy(ptr, msg, len);
ptr += len;
total_length += len + 2;
}
}
auth->length = htons(total_length);
/* Calculate the response digest */
secretlen = strlen(authreq->secret);
memcpy(send_buffer + total_length, authreq->secret, secretlen);
md5_calc(digest, (char *)auth, total_length + secretlen);
memcpy(auth->vector, digest, AUTH_VECTOR_LEN);
memset(send_buffer + total_length, 0, secretlen);
sin = (struct sockaddr_in *) &saremote;
memset ((char *) sin, '\0', sizeof (saremote));
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = htonl(authreq->ipaddr);
sin->sin_port = htons(authreq->udp_port);
/* Send it to the user */
sendto(activefd, (char *)auth, (int)total_length, (int)0,
(struct sockaddr *) sin, sizeof(struct sockaddr_in));
}