home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / radius-2.zip / src / acct.c next >
C/C++ Source or Header  |  1994-12-27  |  5KB  |  218 lines

  1. /*
  2.  *
  3.  *    RADIUS Accounting
  4.  *    Remote Authentication Dial In User Service
  5.  *
  6.  *
  7.  *    Livingston Enterprises, Inc.
  8.  *    6920 Koll Center Parkway
  9.  *    Pleasanton, CA   94566
  10.  *
  11.  *    Copyright 1992 - 1994 Livingston Enterprises, Inc.
  12.  *
  13.  *    Permission to use, copy, modify, and distribute this software for any
  14.  *    purpose and without fee is hereby granted, provided that this
  15.  *    copyright and permission notice appear on all copies and supporting
  16.  *    documentation, the name of Livingston Enterprises, Inc. not be used
  17.  *    in advertising or publicity pertaining to distribution of the
  18.  *    program without specific prior permission, and notice be given
  19.  *    in supporting documentation that copying and distribution is by
  20.  *    permission of Livingston Enterprises, Inc.   
  21.  *
  22.  *    Livingston Enterprises, Inc. makes no representations about
  23.  *    the suitability of this software for any purpose.  It is
  24.  *    provided "as is" without express or implied warranty.
  25.  *
  26.  */
  27.  
  28. static char sccsid[] =
  29. "@(#)acct.c    1.6  Copyright 1994 Livingston Enterprises Inc";
  30.  
  31. #include    <sys/types.h>
  32. #include    <sys/socket.h>
  33. #include    <sys/time.h>
  34. #include    <sys/file.h>
  35. #include    <netinet/in.h>
  36.  
  37. #include    <stdio.h>
  38. #include    <netdb.h>
  39. #include    <pwd.h>
  40. #include    <time.h>
  41. #include    <ctype.h>
  42. #include    <unistd.h>
  43. #include    <signal.h>
  44. #include    <errno.h>
  45. #include    <sys/wait.h>
  46.  
  47. #include    "radius.h"
  48.  
  49. extern char        recv_buffer[4096];
  50. extern char        send_buffer[4096];
  51. extern char        *progname;
  52. extern int        debug_flag;
  53. extern char        *radacct_dir;
  54. extern char        *radius_dir;
  55. extern UINT4        expiration_seconds;
  56. extern UINT4        warning_seconds;
  57. extern int        errno;
  58.  
  59. UINT4            calctime();
  60.  
  61. rad_accounting(authreq, activefd)
  62. AUTH_REQ    *authreq;
  63. int        activefd;
  64. {
  65.     FILE        *outfd;
  66.     char        *ip_hostname();
  67.     char        clientname[128];
  68.     char        buffer[512];
  69.     VALUE_PAIR    *pair;
  70.     long        curtime;
  71.  
  72.     strcpy(clientname, ip_hostname(authreq->ipaddr));
  73.  
  74.     /*
  75.      * Create a directory for this client.
  76.      */
  77.     sprintf(buffer, "%s/%s", radacct_dir, clientname);
  78.     mkdir(buffer, 0755);
  79.  
  80.     /*
  81.      * Write Detail file.
  82.      */
  83.     sprintf(buffer, "%s/%s/detail", radacct_dir, clientname);
  84.     if((outfd = fopen(buffer, "a")) == (FILE *)NULL) {
  85.         sprintf(buffer,
  86.             "Acct: Couldn't open file %s/%s/detail\n",
  87.             radacct_dir, clientname);
  88.         log_err(buffer);
  89.         /* don't respond if we can't save record */
  90.     } else {
  91.  
  92.         /* Post a timestamp */
  93.         curtime = time(0);
  94.         fputs(ctime(&curtime), outfd);
  95.  
  96.         /* Write each attribute/value to the log file */
  97.         pair = authreq->request;
  98.         while(pair != (VALUE_PAIR *)NULL) {
  99.             fputs("\t", outfd);
  100.             fprint_attr_val(outfd, pair);
  101.             fputs("\n", outfd);
  102.         pair = pair->next;
  103.         }
  104.         fputs("\n", outfd);
  105.         fclose(outfd);
  106.         /* let NAS know it is OK to delete from buffer */
  107.         send_acct_reply(authreq, (VALUE_PAIR *)NULL, 
  108.                 (char *)NULL,activefd);
  109.     }
  110.  
  111.     pairfree(authreq->request);
  112.     memset(authreq, 0, sizeof(AUTH_REQ));
  113.     free(authreq);
  114.     return;
  115. }
  116.  
  117. /*************************************************************************
  118.  *
  119.  *    Function: send_acct_reply
  120.  *
  121.  *    Purpose: Reply to the request with an ACKNOWLEDGE.  Also attach
  122.  *         reply attribute value pairs and any user message provided.
  123.  *
  124.  *************************************************************************/
  125.  
  126. send_acct_reply(authreq, reply, msg, activefd)
  127. AUTH_REQ    *authreq;
  128. VALUE_PAIR    *reply;
  129. char        *msg;
  130. int        activefd;
  131. {
  132.     AUTH_HDR        *auth;
  133.     u_short            total_length;
  134.     struct    sockaddr_in    saremote;
  135.     struct    sockaddr_in    *sin;
  136.     u_char            *ptr;
  137.     int            len;
  138.     UINT4            lvalue;
  139.     u_char            digest[16];
  140.     int            secretlen;
  141.     char            *ip_hostname();
  142.  
  143.     auth = (AUTH_HDR *)send_buffer;
  144.  
  145.     /* Build standard header */
  146.     auth->code = PW_ACCOUNTING_RESPONSE;
  147.     auth->id = authreq->id;
  148.     memcpy(auth->vector, authreq->vector, AUTH_VECTOR_LEN);
  149.  
  150.     DEBUG("Sending Accounting Ack of id %d to %lx (%s)\n",
  151.         authreq->id, authreq->ipaddr, ip_hostname(authreq->ipaddr));
  152.  
  153.     total_length = AUTH_HDR_LEN;
  154.  
  155.     /* Load up the configuration values for the user */
  156.     ptr = auth->data;
  157.     while(reply != (VALUE_PAIR *)NULL) {
  158.         debug_pair(stdout, reply);
  159.         *ptr++ = reply->attribute;
  160.  
  161.         switch(reply->type) {
  162.  
  163.         case PW_TYPE_STRING:
  164.             len = strlen(reply->strvalue);
  165.             *ptr++ = len + 2;
  166.             strcpy(ptr, reply->strvalue);
  167.             ptr += len;
  168.             total_length += len + 2;
  169.             break;
  170.             
  171.         case PW_TYPE_INTEGER:
  172.         case PW_TYPE_IPADDR:
  173.             *ptr++ = sizeof(UINT4) + 2;
  174.             lvalue = htonl(reply->lvalue);
  175.             memcpy(ptr, &lvalue, sizeof(UINT4));
  176.             ptr += sizeof(UINT4);
  177.             total_length += sizeof(UINT4) + 2;
  178.             break;
  179.  
  180.         default:
  181.             break;
  182.         }
  183.  
  184.         reply = reply->next;
  185.     }
  186.  
  187.     /* Append the user message */
  188.     if(msg != (char *)NULL) {
  189.         len = strlen(msg);
  190.         if(len > 0 && len < AUTH_STRING_LEN) {
  191.             *ptr++ = PW_PORT_MESSAGE;
  192.             *ptr++ = len + 2;
  193.             memcpy(ptr, msg, len);
  194.             ptr += len;
  195.             total_length += len + 2;
  196.         }
  197.     }
  198.  
  199.     auth->length = htons(total_length);
  200.  
  201.     /* Calculate the response digest */
  202.     secretlen = strlen(authreq->secret);
  203.     memcpy(send_buffer + total_length, authreq->secret, secretlen);
  204.     md5_calc(digest, (char *)auth, total_length + secretlen);
  205.     memcpy(auth->vector, digest, AUTH_VECTOR_LEN);
  206.     memset(send_buffer + total_length, 0, secretlen);
  207.  
  208.     sin = (struct sockaddr_in *) &saremote;
  209.         memset ((char *) sin, '\0', sizeof (saremote));
  210.     sin->sin_family = AF_INET;
  211.     sin->sin_addr.s_addr = htonl(authreq->ipaddr);
  212.     sin->sin_port = htons(authreq->udp_port);
  213.  
  214.     /* Send it to the user */
  215.     sendto(activefd, (char *)auth, (int)total_length, (int)0,
  216.             (struct sockaddr *) sin, sizeof(struct sockaddr_in));
  217. }
  218.