home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / ONLINE / IJB20OS2 / SOURCE / ACL.C next >
C/C++ Source or Header  |  1997-09-16  |  3KB  |  184 lines

  1. char *acl_rcs = "$Id: acl.c,v 1.4 1997/08/22 12:47:42 ACJC Exp $";
  2. /* Written and copyright by the Anonymous Coders and Junkbusters Corporation.
  3.  * Will be made available under the GNU General Public License.
  4.  * This software comes with NO WARRANTY.
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <ctype.h>
  13.  
  14. #ifdef _WIN32
  15. #include "windows.h"
  16. #else
  17. #include <netinet/in.h>
  18. #endif
  19.  
  20. #ifdef REGEX
  21. #include "gnu_regex.h"
  22. #endif
  23.  
  24. #include "jcc.h"
  25.  
  26. #define ACL_PERMIT 1
  27. #define ACL_DENY  -1
  28.  
  29. struct access_control_list {
  30.     long    addr;
  31.     long    mask;
  32.     short    action;
  33. };
  34.  
  35. static struct access_control_list acl[256], *acl_end;
  36.  
  37. int
  38. block_acl(long client_addr)
  39. {
  40.     struct access_control_list *a;
  41.     long target;
  42.  
  43.     /* if not using an access control list, then permit the connection */
  44.     if(aclfile == NULL) return(0);
  45.  
  46.     /* search the list backwards */
  47.     for(a = acl_end; a >= acl ; a--) {
  48.  
  49.         target = client_addr & a->mask;
  50.  
  51.         if(target == a->addr) {
  52.             if(a->action == ACL_PERMIT) {
  53.                 return(0);
  54.             } else {
  55.                 return(1);
  56.             }
  57.         }
  58.     }
  59.  
  60.     return(1);
  61. }
  62.  
  63. int
  64. load_aclfile()
  65. {
  66.     FILE *fp;
  67.     char buf[BUFSIZ], line[BUFSIZ], *v[3], *p;
  68.     int lineno = 0;
  69.     int i, masklength;
  70.     struct access_control_list *a, *eol;
  71.     static struct stat prev[1], curr[1];
  72.  
  73.     /* note - this runs in the "single threaded" part of the code
  74.      * so we don't need per-client versions of the access control list
  75.      */
  76.  
  77.     if(stat(aclfile, curr) < 0) {
  78.         goto load_aclfile_error;
  79.     }
  80.  
  81.     if(prev->st_mtime == curr->st_mtime) {
  82.         return(0);
  83.     }
  84.  
  85.     fp = fopen(aclfile, "r");
  86.  
  87.     if(fp == NULL) {
  88.         fprintf(logfp, "%s: can't open access control list %s\n",
  89.             prog, aclfile);
  90.         fperror(logfp, "");
  91.         return(-1);
  92.     }
  93.  
  94.     eol = acl + SZ(acl);
  95.  
  96.     acl_end = acl - 1;
  97.  
  98.     for(a = acl; (fgets(line, sizeof(line), fp)) ; a++) {
  99.  
  100.         lineno++;
  101.  
  102.         strcpy(buf, line);
  103.  
  104.         if((p = strpbrk(buf, "#\r\n"))) *p = '\0';
  105.  
  106.         if(*buf == '\0') continue;
  107.  
  108.         if(a == eol) {
  109.             fprintf(logfp, "%s: access control list overflow\n",
  110.                 prog);
  111.             goto load_aclfile_error;
  112.         }
  113.  
  114.         i = ssplit(buf, "/ \t", v, SZ(v), 1, 1);
  115.  
  116.         masklength = 32;
  117.  
  118.         switch(i) {
  119.         case 3:
  120.             p = v[2];
  121.             if(isdigit(*p) == 0) {
  122.                 goto load_aclfile_error;
  123.             }
  124.             masklength = atoi(p);
  125.             if((masklength < 0)
  126.             || (masklength > 32)) {
  127.                 goto load_aclfile_error;
  128.             }
  129.             /* no break */
  130.         case 2:
  131.             p = v[1];
  132.             a->addr = ntohl(atoip(p));
  133.  
  134.             if(a->addr == -1) {
  135.                 fprintf(logfp,
  136.                     "%s: can't resolve address for %s\n",
  137.                         prog, p);
  138.                 goto load_aclfile_error;
  139.             }
  140.  
  141.             p = v[0];
  142.             if(strcmp(p, "permit") == 0) {
  143.                 a->action = ACL_PERMIT;
  144.                 break;
  145.             }
  146.  
  147.             if(strcmp(p, "deny"  ) == 0) {
  148.                 a->action = ACL_DENY;
  149.                 break;
  150.             }
  151.             /* no break */
  152.         default:
  153.             goto load_aclfile_error;    
  154.         }
  155.  
  156.         /* build the netmask */
  157.         a->mask = 0;
  158.         for(i=1; i <= masklength ; i++) {
  159.             a->mask |= (1 << (32 - i));
  160.         }
  161.  
  162.         /* now mask off the host portion of the ip address
  163.          * (i.e. save on the network portion of the address).
  164.          */
  165.         a->addr = a->addr & a->mask;
  166.         acl_end = a;
  167.     }
  168.  
  169.     *prev = *curr;
  170.  
  171.     fclose(fp);
  172.  
  173.     return(0);
  174.  
  175. load_aclfile_error:
  176.  
  177.     fclose(fp);
  178.  
  179.     fprintf(logfp,
  180.         "%s: invalid access control list '%s' at line %d:\n%s",
  181.             prog, aclfile, lineno, line);
  182.     return(-1);
  183. }
  184.