accessctrl.c
上传用户:eo_sii
上传日期:2007-01-05
资源大小:91k
文件大小:9k
源码类别:

手机短信编程

开发平台:

Unix_Linux

  1. /*==========================================================
  2.  * Program : accessctrl.c                  Project : smslink
  3.  * Authors : Philipp Klaus <pklaus@access.ch>.
  4.  *           Philippe Andersson.
  5.  * Date    : 11/02/99
  6.  * Version : 0.03b
  7.  * Comment : Handling routines for /etc/gsmaccess ACL.
  8.  *
  9.  * Modification History :
  10.  * - 0.01b (27/01/99) : Initial release.
  11.  * - 0.02b (06/02/99) : Introduced a boolean to bypass use of
  12.  *   the ACL system. When the ACCESSFILE is not present, the
  13.  *   check function always return SUCCESS. Cosmetics.
  14.  * - 0.03b (11/02/99) : Complete rewrite. Start implementing
  15.  *   ACL's through "access:network/mask" entries stored in a
  16.  *   linked list.
  17.  *========================================================*/
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <ctype.h>
  22. #include <math.h>                            /* for pow() */
  23. #include <sys/socket.h>
  24. #include <netinet/in.h>
  25. #include <arpa/inet.h>
  26. #include <dial/modems.h>
  27. #include <dial/mdmerrno.h>
  28. #include "sms_serv.h"
  29. /*========================================================*/
  30. /**********           GLOBAL VARIABLES             ********/
  31. /*========================================================*/
  32. int use_acl = TRUE;
  33. /*========================================================*/
  34. /**********               FUNCTIONS                ********/
  35. /*========================================================*/
  36. void acl_list_init (acl_list *list)
  37. {
  38.   list->head = NULL;
  39.   list->tail = NULL;
  40. }                                     /* acl_list_init () */
  41. /*========================================================*/
  42. int empty_acl_list (acl_list list)
  43. {
  44.   return (list.head == NULL);
  45. }                                    /* empty_acl_list () */
  46. /*========================================================*/
  47. void acl_list_insert (acl_list *list, int action, struct in_addr network,
  48.                       unsigned long no_mask)
  49. {
  50.   /* WARNING : the order of the elements IS relevent - has to
  51.    * be the same as in the access file => avoid inserting at
  52.    * list head. Do it at the tail. */
  53.   
  54.   struct acl_item *element;
  55.   /* alloc memory for new element */
  56.   element = (struct acl_item *) malloc (sizeof (struct acl_item));
  57.   if (!element)
  58.     syserr ("sms_serv: can't malloc() for new ACL entry");
  59.   
  60.   /* initialize fields for new element */
  61.   element->action = action;
  62.   element->network.s_addr = network.s_addr;
  63.   element->nomask = no_mask;
  64.   
  65.   /* chain it in the list */
  66.   if (empty_acl_list (*list)) {
  67.     list->head = element;
  68.     list->tail = element;
  69.     element->next = NULL;
  70.     element->prev = NULL;
  71.   }
  72.   else {
  73.     element->next = NULL;
  74.     element->prev = list->tail;
  75.     list->tail->next = element;
  76.     list->tail = element;
  77.   }
  78. }                                   /* acl_list_insert () */
  79. /*========================================================*/
  80. void free_acl_list (acl_list *list)
  81. {
  82.   struct acl_item *cursor;
  83.   if (!empty_acl_list (*list)) {
  84.     /* hop to element before last */
  85.     cursor = list->tail->prev;
  86.     /* now go back and clean behind */
  87.     while (cursor != NULL) {
  88.       free (cursor->next);
  89.       cursor->next = NULL;
  90.       list->tail = cursor;
  91.       cursor = cursor->prev;
  92.     }                           /* while (cursor != NULL) */
  93.   }                           /* if (!empty_acl_list (... */
  94.   /* now clean last element and reset header */
  95.   free (list->head);
  96.   list->head = NULL;
  97.   list->tail = NULL;
  98. }                                     /* free_acl_list () */
  99. /*========================================================*/
  100. #ifdef INCL_DEBUG_CODE
  101. void print_acl_list (acl_list list)
  102. {
  103.   struct acl_item *cursor;
  104.   if (!empty_acl_list (list)) {
  105.     cursor = list.head;
  106.     fprintf (stdout, "%-5s : [%s] / %dn", 
  107.             (cursor->action == ACL_ALLOW) ? "ALLOW" : "DENY", 
  108.     inet_ntoa (cursor->network),
  109.             cursor->nomask);
  110.     while (cursor->next != NULL) {
  111.       cursor = cursor->next;
  112.       fprintf (stdout, "%-5s : [%s] / %dn", 
  113.               (cursor->action == ACL_ALLOW) ? "ALLOW" : "DENY", 
  114.       inet_ntoa (cursor->network),
  115.               cursor->nomask);
  116.     }
  117.   }
  118.   else {
  119.     fprintf (stdout, "sms_serv: empty 'ACL' list.n");
  120.   }
  121. }                                    /* print_acl_list () */
  122. #endif
  123. /*========================================================*/
  124. int read_acl (acl_list *list) {
  125.   FILE *aclfile;
  126.   char *buffer;
  127.   int counter = 0;                 /* valid entries count */
  128.   int act_char;
  129.   int action;
  130.   struct in_addr netorip;
  131.   int netmask;                       /* as read form file */
  132.   unsigned long nomask;
  133.   char *ptr, *pptr, *err;
  134.   /*------------------------------------- Initializations */
  135.   buffer = mdmalloc (BUFFSIZE);
  136.   if (!buffer) {
  137.     mdmerrno = -EMDMEM;
  138.     return (FAILURE);
  139.   }
  140.   /* Open input file */
  141.   if ((aclfile = fopen (ACCESSFILE, "r")) == NULL) {
  142.     use_acl = FALSE;
  143.     syslog ((FACILITY | LOG_WARNING), "access control is DISABLED.");
  144.     return (SUCCESS);
  145.   }
  146.   /*------------------------------------ File upload loop */
  147.   while ((fgets (buffer, BUFFSIZE, aclfile) != NULL) && (counter < MAXACLS)) {
  148.     buffer[strlen (buffer) - 1] = '';
  149.     /* ignore blank lines and comments */
  150.     if (buffer[0] == '#' || buffer[0] == '' || buffer[0] == 'n')
  151.       continue;
  152.     /* parse the line we read - silently ignore invalid ones */
  153. #ifdef INCL_DEBUG_CODE
  154.    fprintf (stderr, "now parsing : [%s]n", buffer);
  155. #endif
  156.     /*.......................................action (int) */
  157.     if ((ptr = strchr (buffer, ':')) == NULL)
  158.       continue;
  159.     *ptr = '';
  160.     act_char = toupper (buffer[0]);
  161.     switch (act_char) {
  162.       case 'Y':
  163.         action = ACL_ALLOW;
  164. break;
  165.       case 'N':
  166.         action = ACL_DENY;
  167. break;
  168.       default:
  169.         continue;
  170.     } /* switch () */
  171.     ptr++;
  172.     /*................................net. or IP (char *) */
  173.     if ((pptr = strchr (ptr, '/')) == NULL)
  174.       continue;
  175.     *pptr = '';
  176.     
  177.     if ((strlen (ptr) < 7) || (strlen (ptr) > 15))
  178.       continue;
  179.     
  180.     /* convert dotted quad to struct in_addr */
  181.     if (!inet_aton (ptr, &netorip)) {
  182. #ifdef INCL_DEBUG_CODE
  183.       fprintf (stderr, "conversion to s_addr failed for [%s]n", ptr);
  184. #endif
  185.       continue;
  186.     }
  187.       
  188.     ptr = pptr + 1;
  189.     /*......................................netmask (int) */
  190.     netmask = strtol (ptr, &err, 10);
  191.     if ((*ptr == '') || (*err != ''))
  192.       continue;
  193.     
  194.     if ((netmask < 0) || (netmask > 32))
  195.       continue;
  196.       
  197.     /* invert the mask value */
  198.     netmask = (32 - netmask);
  199.     
  200.     /* build the mask itself (avoiding overflow) */
  201.     if (netmask < 32)
  202.       nomask = (pow (2, netmask) - 1);
  203.     else
  204.       nomask = (unsigned long) 4294967295;
  205.     /* now create entry in the list */
  206.     acl_list_insert (list, action, netorip, htonl (nomask));
  207.     
  208.     counter++;
  209.   }                                    /* while (fgets... */
  210.   syslog ((FACILITY | LOG_NOTICE), "successfully loaded %d ACL entries.",
  211.          counter);
  212. #ifdef INCL_DEBUG_CODE
  213.   print_acl_list (*list);
  214. #endif
  215.   mdmfree (buffer);
  216.   return (SUCCESS);
  217. }                                          /* read_acl () */
  218. /*========================================================*/
  219. int check_acl (struct in_addr *address, acl_list list) {
  220.   int rule;
  221.   struct acl_item *cursor;
  222.   if (use_acl) {
  223.     if (!empty_acl_list (list)) {
  224.       cursor = list.head;
  225.       rule = 1;
  226.       if ((cursor->network.s_addr | cursor->nomask) ==
  227.          (address->s_addr | cursor->nomask)) {
  228.         /* we have a match */
  229. if (cursor->action == ACL_DENY) {
  230. #ifdef INCL_DEBUG_CODE
  231.   fprintf (stderr, "access denied - rule #%dn", rule);
  232. #endif
  233.           return (FAILURE);
  234. }
  235. else {
  236. #ifdef INCL_DEBUG_CODE
  237.   fprintf (stderr, "access granted - rule #%dn", rule);
  238. #endif
  239.           return (SUCCESS);
  240. }
  241.       }
  242.       while (cursor->next != NULL) {
  243.         cursor = cursor->next;
  244. rule++;
  245.         if ((cursor->network.s_addr | cursor->nomask) ==
  246.            (address->s_addr | cursor->nomask)) {
  247.           /* we have a match */
  248.   if (cursor->action == ACL_DENY) {
  249. #ifdef INCL_DEBUG_CODE
  250.     fprintf (stderr, "access denied - rule #%dn", rule);
  251. #endif
  252.             return (FAILURE);
  253.   }
  254.   else {
  255. #ifdef INCL_DEBUG_CODE
  256.     fprintf (stderr, "access granted - rule #%dn", rule);
  257. #endif
  258.             return (SUCCESS);
  259.   }
  260.         }
  261.       }                                     /* while (... */
  262.       /* when nothing matches, defaults to DENY */
  263. #ifdef INCL_DEBUG_CODE
  264.       fprintf (stderr, "no match found - default denyn");
  265. #endif
  266.       return (FAILURE);
  267.     }
  268.     else {                                  /* empty list */
  269. #ifdef INCL_DEBUG_CODE
  270.       fprintf (stderr, "empty list - default denyn");
  271. #endif
  272.       return (FAILURE);
  273.     }
  274.   }
  275.   else                         /* access control disabled */
  276.     return (SUCCESS);
  277. }                                         /* check_acl () */
  278. /*========================================================*/
  279. /*==========================================================
  280.  * EOF : accessctrl.c
  281.  *===================*/