home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 April / PCWorld_2001-04_cd.bin / Software / TemaCD / junkbust / win / acl.c next >
C/C++ Source or Header  |  1998-10-30  |  4KB  |  245 lines

  1. char *acl_rcs = "$Id: acl.c,v 1.8 1998/01/26 18:52:17 ACJC Exp $";
  2. /* Written and copyright 1997 Anonymous Coders and Junkbusters Corporation.
  3.  * Distributed under the GNU General Public License; see the README file.
  4.  * This code comes with NO WARRANTY. http://www.junkbusters.com/ht/en/gpl.html
  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. static struct file_list *current_aclfile;
  27.  
  28. int
  29. block_acl(struct access_control_addr *src, struct access_control_addr *dst, struct client_state *csp)
  30. {
  31.     struct file_list *fl;
  32.     struct access_control_list *a, *acl;
  33.     struct access_control_addr s[1], d[1];
  34.  
  35.     /* if not using an access control list, then permit the connection */
  36.     if(((fl = csp->alist) == NULL) || ((acl = fl->f) == NULL)) {
  37.         return(0);
  38.     }
  39.  
  40.     /* search the list */
  41.     for(a = acl->next ; a ; a = a->next) {
  42.  
  43.         *s = *src;
  44.         *d = *dst;
  45.  
  46.         s->addr &= a->src->mask;
  47.         d->addr &= a->dst->mask;
  48.  
  49.         if((s->addr  == a->src->addr)
  50.         && (d->addr  == a->dst->addr)
  51.         && ((s->port == a->src->port)
  52.          || (s->port == 0)
  53.          || (a->src->port == 0))
  54.         && ((d->port == a->dst->port)
  55.          || (d->port == 0)
  56.          || (a->dst->port == 0))) {
  57.             if(a->action == ACL_PERMIT) {
  58.                 return(0);
  59.             } else {
  60.                 return(1);
  61.             }
  62.         }
  63.     }
  64.  
  65.     return(1);
  66. }
  67.  
  68. void
  69. unload_aclfile(struct access_control_list *b)
  70. {
  71.     if(b == NULL) return;
  72.  
  73.     unload_aclfile(b->next);
  74.  
  75.     freez(b);
  76. }
  77.  
  78. int
  79. acl_addr(char *aspec, struct access_control_addr *aca)
  80. {
  81.     int i, masklength, port;
  82.     char *p;
  83.  
  84.     masklength = 32;
  85.     port       =  0;
  86.  
  87.     if((p = strchr(aspec, '/'))) {
  88.         *p++ = '\0';
  89.  
  90.         if(isdigit(*p) == 0) {
  91.             return(-1);
  92.         }
  93.         masklength = atoi(p);
  94.     }
  95.  
  96.     if((masklength < 0)
  97.     || (masklength > 32)) {
  98.         return(-1);
  99.     }
  100.  
  101.     if((p = strchr(aspec, ':'))) {
  102.         *p++ = '\0';
  103.  
  104.         if(isdigit(*p) == 0) {
  105.             return(-1);
  106.         }
  107.         port = atoi(p);
  108.     }
  109.  
  110.     aca->port = port;
  111.  
  112.     aca->addr = ntohl(atoip(aspec));
  113.  
  114.     if(aca->addr == -1) {
  115.         fprintf(logfp,
  116.             "%s: can't resolve address for %s\n",
  117.                 prog, aspec);
  118.         return(-1);
  119.     }
  120.  
  121.     /* build the netmask */
  122.     aca->mask = 0;
  123.     for(i=1; i <= masklength ; i++) {
  124.         aca->mask |= (1 << (32 - i));
  125.     }
  126.  
  127.     /* now mask off the host portion of the ip address
  128.      * (i.e. save on the network portion of the address).
  129.      */
  130.     aca->addr = aca->addr & aca->mask;
  131.  
  132.     return(0);
  133. }
  134.  
  135. int
  136. load_aclfile(struct client_state *csp)
  137. {
  138.     FILE *fp;
  139.     char buf[BUFSIZ], *v[3], *p;
  140.     int i;
  141.     struct access_control_list *a, *bl;
  142.     struct file_list *fs;
  143.     static struct stat prev[1], curr[1];
  144.  
  145.     if(stat(aclfile, curr) < 0) {
  146.         goto load_aclfile_error;
  147.     }
  148.  
  149.     if(current_aclfile && (prev->st_mtime == curr->st_mtime)) {
  150.         csp->alist = current_aclfile;
  151.         return(0);
  152.     }
  153.  
  154.     fs = (struct file_list           *) zalloc(sizeof(*fs));
  155.     bl = (struct access_control_list *) zalloc(sizeof(*bl));
  156.  
  157.     if((fs == NULL) || (bl == NULL)) {
  158.         goto load_aclfile_error;
  159.     }
  160.  
  161.     fs->f = bl;
  162.  
  163.     fs->next = files->next;
  164.     files->next = fs;
  165.  
  166.     if(csp) {
  167.         csp->alist = fs;
  168.     }
  169.  
  170.     fp = fopen(aclfile, "r");
  171.  
  172.     if(fp == NULL) {
  173.         fprintf(logfp, "%s: can't open access control list %s\n",
  174.             prog, aclfile);
  175.         fperror(logfp, "");
  176.         goto load_aclfile_error;
  177.     }
  178.  
  179.     while(fgets(buf, sizeof(buf), fp)) {
  180.  
  181.         if((p = strpbrk(buf, "#\r\n"))) *p = '\0';
  182.  
  183.         if(*buf == '\0') continue;
  184.  
  185.         i = ssplit(buf, " \t", v, SZ(v), 1, 1);
  186.  
  187.         /* allocate a new node */
  188.         a = (struct access_control_list *) zalloc(sizeof(*a));
  189.  
  190.         if(a == NULL) {
  191.             fclose(fp);
  192.             goto load_aclfile_error;
  193.         }
  194.  
  195.         /* add it to the list */
  196.         a->next  = bl->next;
  197.         bl->next = a;
  198.  
  199.         switch(i) {
  200.         case 3:
  201.             if(acl_addr(v[2], a->dst) < 0) {
  202.                 goto load_aclfile_error;
  203.             }
  204.             /* no break */
  205.         case 2:
  206.             if(acl_addr(v[1], a->src) < 0) {
  207.                 goto load_aclfile_error;
  208.             }
  209.  
  210.             p = v[0];
  211.             if(strcmpic(p, "permit") == 0) {
  212.                 a->action = ACL_PERMIT;
  213.                 break;
  214.             }
  215.  
  216.             if(strcmpic(p, "deny"  ) == 0) {
  217.                 a->action = ACL_DENY;
  218.                 break;
  219.             }
  220.             /* no break */
  221.         default:
  222.             goto load_aclfile_error;    
  223.         }
  224.     }
  225.  
  226.     *prev = *curr;
  227.  
  228.     fclose(fp);
  229.  
  230.     if(current_aclfile) {
  231.         current_aclfile->unloader = unload_aclfile;
  232.     }
  233.  
  234.     current_aclfile = fs;
  235.  
  236.     return(0);
  237.  
  238. load_aclfile_error:
  239.     fprintf(logfp,
  240.         "%s: can't load access control list '%s': ",
  241.             prog, aclfile);
  242.     fperror(logfp, "");
  243.     return(-1);
  244. }
  245.