?? accessctrl.c
字號:
/*========================================================== * 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_CODEvoid print_acl_list (acl_list list){ struct acl_item *cursor; if (!empty_acl_list (list)) { cursor = list.head; fprintf (stdout, "%-5s : [%s] / %d\n", (cursor->action == ACL_ALLOW) ? "ALLOW" : "DENY", inet_ntoa (cursor->network), cursor->nomask); while (cursor->next != NULL) { cursor = cursor->next; fprintf (stdout, "%-5s : [%s] / %d\n", (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] = '\0'; /* ignore blank lines and comments */ if (buffer[0] == '#' || buffer[0] == '\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 = '\0'; 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 = '\0'; 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 == '\0') || (*err != '\0')) 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 #%d\n", rule);#endif return (FAILURE); } else {#ifdef INCL_DEBUG_CODE fprintf (stderr, "access granted - rule #%d\n", 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 #%d\n", rule);#endif return (FAILURE); } else {#ifdef INCL_DEBUG_CODE fprintf (stderr, "access granted - rule #%d\n", rule);#endif return (SUCCESS); } } } /* while (... */ /* when nothing matches, defaults to DENY */#ifdef INCL_DEBUG_CODE fprintf (stderr, "no match found - default deny\n");#endif return (FAILURE); } else { /* empty list */#ifdef INCL_DEBUG_CODE fprintf (stderr, "empty list - default deny\n");#endif return (FAILURE); } } else /* access control disabled */ return (SUCCESS);} /* check_acl () *//*========================================================*//*========================================================== * EOF : accessctrl.c *===================*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -