accessctrl.c
上传用户:eo_sii
上传日期:2007-01-05
资源大小:91k
文件大小:9k
- /*==========================================================
- * Program : accessctrl.c Project : smslink
- * Authors : Philipp Klaus <pklaus@access.ch>.
- * Philippe Andersson.
- * Date : 11/02/99
- * Version : 0.03b
- * Comment : Handling routines for /etc/gsmaccess ACL.
- *
- * Modification History :
- * - 0.01b (27/01/99) : Initial release.
- * - 0.02b (06/02/99) : Introduced a boolean to bypass use of
- * the ACL system. When the ACCESSFILE is not present, the
- * check function always return SUCCESS. Cosmetics.
- * - 0.03b (11/02/99) : Complete rewrite. Start implementing
- * ACL's through "access:network/mask" entries stored in a
- * linked list.
- *========================================================*/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <math.h> /* for pow() */
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <dial/modems.h>
- #include <dial/mdmerrno.h>
- #include "sms_serv.h"
- /*========================================================*/
- /********** GLOBAL VARIABLES ********/
- /*========================================================*/
- int use_acl = TRUE;
- /*========================================================*/
- /********** FUNCTIONS ********/
- /*========================================================*/
- void acl_list_init (acl_list *list)
- {
- list->head = NULL;
- list->tail = NULL;
- } /* acl_list_init () */
- /*========================================================*/
- int empty_acl_list (acl_list list)
- {
- return (list.head == NULL);
- } /* empty_acl_list () */
- /*========================================================*/
- void acl_list_insert (acl_list *list, int action, struct in_addr network,
- unsigned long no_mask)
- {
- /* WARNING : the order of the elements IS relevent - has to
- * be the same as in the access file => avoid inserting at
- * list head. Do it at the tail. */
-
- struct acl_item *element;
- /* alloc memory for new element */
- element = (struct acl_item *) malloc (sizeof (struct acl_item));
- if (!element)
- syserr ("sms_serv: can't malloc() for new ACL entry");
-
- /* initialize fields for new element */
- element->action = action;
- element->network.s_addr = network.s_addr;
- element->nomask = no_mask;
-
- /* chain it in the list */
- if (empty_acl_list (*list)) {
- list->head = element;
- list->tail = element;
- element->next = NULL;
- element->prev = NULL;
- }
- else {
- element->next = NULL;
- element->prev = list->tail;
- list->tail->next = element;
- list->tail = element;
- }
- } /* acl_list_insert () */
- /*========================================================*/
- void free_acl_list (acl_list *list)
- {
- struct acl_item *cursor;
- if (!empty_acl_list (*list)) {
- /* hop to element before last */
- cursor = list->tail->prev;
- /* now go back and clean behind */
- while (cursor != NULL) {
- free (cursor->next);
- cursor->next = NULL;
- list->tail = cursor;
- cursor = cursor->prev;
- } /* while (cursor != NULL) */
- } /* if (!empty_acl_list (... */
- /* now clean last element and reset header */
- free (list->head);
- list->head = NULL;
- list->tail = NULL;
- } /* free_acl_list () */
- /*========================================================*/
- #ifdef INCL_DEBUG_CODE
- void print_acl_list (acl_list list)
- {
- struct acl_item *cursor;
- if (!empty_acl_list (list)) {
- cursor = list.head;
- fprintf (stdout, "%-5s : [%s] / %dn",
- (cursor->action == ACL_ALLOW) ? "ALLOW" : "DENY",
- inet_ntoa (cursor->network),
- cursor->nomask);
- while (cursor->next != NULL) {
- cursor = cursor->next;
- fprintf (stdout, "%-5s : [%s] / %dn",
- (cursor->action == ACL_ALLOW) ? "ALLOW" : "DENY",
- inet_ntoa (cursor->network),
- cursor->nomask);
- }
- }
- else {
- fprintf (stdout, "sms_serv: empty 'ACL' list.n");
- }
- } /* print_acl_list () */
- #endif
- /*========================================================*/
- int read_acl (acl_list *list) {
-
- FILE *aclfile;
- char *buffer;
- int counter = 0; /* valid entries count */
- int act_char;
- int action;
- struct in_addr netorip;
- int netmask; /* as read form file */
- unsigned long nomask;
- char *ptr, *pptr, *err;
-
- /*------------------------------------- Initializations */
- buffer = mdmalloc (BUFFSIZE);
- if (!buffer) {
- mdmerrno = -EMDMEM;
- return (FAILURE);
- }
- /* Open input file */
- if ((aclfile = fopen (ACCESSFILE, "r")) == NULL) {
- use_acl = FALSE;
- syslog ((FACILITY | LOG_WARNING), "access control is DISABLED.");
- return (SUCCESS);
- }
- /*------------------------------------ File upload loop */
- while ((fgets (buffer, BUFFSIZE, aclfile) != NULL) && (counter < MAXACLS)) {
- buffer[strlen (buffer) - 1] = ' ';
- /* ignore blank lines and comments */
- if (buffer[0] == '#' || buffer[0] == ' ' || buffer[0] == 'n')
- continue;
- /* parse the line we read - silently ignore invalid ones */
- #ifdef INCL_DEBUG_CODE
- fprintf (stderr, "now parsing : [%s]n", buffer);
- #endif
- /*.......................................action (int) */
- if ((ptr = strchr (buffer, ':')) == NULL)
- continue;
- *ptr = ' ';
- act_char = toupper (buffer[0]);
- switch (act_char) {
- case 'Y':
- action = ACL_ALLOW;
- break;
- case 'N':
- action = ACL_DENY;
- break;
- default:
- continue;
- } /* switch () */
- ptr++;
- /*................................net. or IP (char *) */
- if ((pptr = strchr (ptr, '/')) == NULL)
- continue;
- *pptr = ' ';
-
- if ((strlen (ptr) < 7) || (strlen (ptr) > 15))
- continue;
-
- /* convert dotted quad to struct in_addr */
- if (!inet_aton (ptr, &netorip)) {
- #ifdef INCL_DEBUG_CODE
- fprintf (stderr, "conversion to s_addr failed for [%s]n", ptr);
- #endif
- continue;
- }
-
- ptr = pptr + 1;
- /*......................................netmask (int) */
- netmask = strtol (ptr, &err, 10);
- if ((*ptr == ' ') || (*err != ' '))
- continue;
-
- if ((netmask < 0) || (netmask > 32))
- continue;
-
- /* invert the mask value */
- netmask = (32 - netmask);
-
- /* build the mask itself (avoiding overflow) */
- if (netmask < 32)
- nomask = (pow (2, netmask) - 1);
- else
- nomask = (unsigned long) 4294967295;
- /* now create entry in the list */
- acl_list_insert (list, action, netorip, htonl (nomask));
-
- counter++;
- } /* while (fgets... */
- syslog ((FACILITY | LOG_NOTICE), "successfully loaded %d ACL entries.",
- counter);
- #ifdef INCL_DEBUG_CODE
- print_acl_list (*list);
- #endif
- mdmfree (buffer);
- return (SUCCESS);
- } /* read_acl () */
- /*========================================================*/
- int check_acl (struct in_addr *address, acl_list list) {
- int rule;
- struct acl_item *cursor;
- if (use_acl) {
- if (!empty_acl_list (list)) {
- cursor = list.head;
- rule = 1;
- if ((cursor->network.s_addr | cursor->nomask) ==
- (address->s_addr | cursor->nomask)) {
- /* we have a match */
- if (cursor->action == ACL_DENY) {
- #ifdef INCL_DEBUG_CODE
- fprintf (stderr, "access denied - rule #%dn", rule);
- #endif
- return (FAILURE);
- }
- else {
- #ifdef INCL_DEBUG_CODE
- fprintf (stderr, "access granted - rule #%dn", rule);
- #endif
- return (SUCCESS);
- }
- }
- while (cursor->next != NULL) {
- cursor = cursor->next;
- rule++;
- if ((cursor->network.s_addr | cursor->nomask) ==
- (address->s_addr | cursor->nomask)) {
- /* we have a match */
- if (cursor->action == ACL_DENY) {
- #ifdef INCL_DEBUG_CODE
- fprintf (stderr, "access denied - rule #%dn", rule);
- #endif
- return (FAILURE);
- }
- else {
- #ifdef INCL_DEBUG_CODE
- fprintf (stderr, "access granted - rule #%dn", rule);
- #endif
- return (SUCCESS);
- }
- }
- } /* while (... */
- /* when nothing matches, defaults to DENY */
- #ifdef INCL_DEBUG_CODE
- fprintf (stderr, "no match found - default denyn");
- #endif
- return (FAILURE);
- }
- else { /* empty list */
- #ifdef INCL_DEBUG_CODE
- fprintf (stderr, "empty list - default denyn");
- #endif
- return (FAILURE);
- }
- }
- else /* access control disabled */
- return (SUCCESS);
- } /* check_acl () */
- /*========================================================*/
- /*==========================================================
- * EOF : accessctrl.c
- *===================*/