home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2001 April
/
PCWorld_2001-04_cd.bin
/
Software
/
TemaCD
/
junkbust
/
win
/
acl.c
next >
Wrap
C/C++ Source or Header
|
1998-10-30
|
4KB
|
245 lines
char *acl_rcs = "$Id: acl.c,v 1.8 1998/01/26 18:52:17 ACJC Exp $";
/* Written and copyright 1997 Anonymous Coders and Junkbusters Corporation.
* Distributed under the GNU General Public License; see the README file.
* This code comes with NO WARRANTY. http://www.junkbusters.com/ht/en/gpl.html
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifdef _WIN32
#include "windows.h"
#else
#include <netinet/in.h>
#endif
#ifdef REGEX
#include "gnu_regex.h"
#endif
#include "jcc.h"
static struct file_list *current_aclfile;
int
block_acl(struct access_control_addr *src, struct access_control_addr *dst, struct client_state *csp)
{
struct file_list *fl;
struct access_control_list *a, *acl;
struct access_control_addr s[1], d[1];
/* if not using an access control list, then permit the connection */
if(((fl = csp->alist) == NULL) || ((acl = fl->f) == NULL)) {
return(0);
}
/* search the list */
for(a = acl->next ; a ; a = a->next) {
*s = *src;
*d = *dst;
s->addr &= a->src->mask;
d->addr &= a->dst->mask;
if((s->addr == a->src->addr)
&& (d->addr == a->dst->addr)
&& ((s->port == a->src->port)
|| (s->port == 0)
|| (a->src->port == 0))
&& ((d->port == a->dst->port)
|| (d->port == 0)
|| (a->dst->port == 0))) {
if(a->action == ACL_PERMIT) {
return(0);
} else {
return(1);
}
}
}
return(1);
}
void
unload_aclfile(struct access_control_list *b)
{
if(b == NULL) return;
unload_aclfile(b->next);
freez(b);
}
int
acl_addr(char *aspec, struct access_control_addr *aca)
{
int i, masklength, port;
char *p;
masklength = 32;
port = 0;
if((p = strchr(aspec, '/'))) {
*p++ = '\0';
if(isdigit(*p) == 0) {
return(-1);
}
masklength = atoi(p);
}
if((masklength < 0)
|| (masklength > 32)) {
return(-1);
}
if((p = strchr(aspec, ':'))) {
*p++ = '\0';
if(isdigit(*p) == 0) {
return(-1);
}
port = atoi(p);
}
aca->port = port;
aca->addr = ntohl(atoip(aspec));
if(aca->addr == -1) {
fprintf(logfp,
"%s: can't resolve address for %s\n",
prog, aspec);
return(-1);
}
/* build the netmask */
aca->mask = 0;
for(i=1; i <= masklength ; i++) {
aca->mask |= (1 << (32 - i));
}
/* now mask off the host portion of the ip address
* (i.e. save on the network portion of the address).
*/
aca->addr = aca->addr & aca->mask;
return(0);
}
int
load_aclfile(struct client_state *csp)
{
FILE *fp;
char buf[BUFSIZ], *v[3], *p;
int i;
struct access_control_list *a, *bl;
struct file_list *fs;
static struct stat prev[1], curr[1];
if(stat(aclfile, curr) < 0) {
goto load_aclfile_error;
}
if(current_aclfile && (prev->st_mtime == curr->st_mtime)) {
csp->alist = current_aclfile;
return(0);
}
fs = (struct file_list *) zalloc(sizeof(*fs));
bl = (struct access_control_list *) zalloc(sizeof(*bl));
if((fs == NULL) || (bl == NULL)) {
goto load_aclfile_error;
}
fs->f = bl;
fs->next = files->next;
files->next = fs;
if(csp) {
csp->alist = fs;
}
fp = fopen(aclfile, "r");
if(fp == NULL) {
fprintf(logfp, "%s: can't open access control list %s\n",
prog, aclfile);
fperror(logfp, "");
goto load_aclfile_error;
}
while(fgets(buf, sizeof(buf), fp)) {
if((p = strpbrk(buf, "#\r\n"))) *p = '\0';
if(*buf == '\0') continue;
i = ssplit(buf, " \t", v, SZ(v), 1, 1);
/* allocate a new node */
a = (struct access_control_list *) zalloc(sizeof(*a));
if(a == NULL) {
fclose(fp);
goto load_aclfile_error;
}
/* add it to the list */
a->next = bl->next;
bl->next = a;
switch(i) {
case 3:
if(acl_addr(v[2], a->dst) < 0) {
goto load_aclfile_error;
}
/* no break */
case 2:
if(acl_addr(v[1], a->src) < 0) {
goto load_aclfile_error;
}
p = v[0];
if(strcmpic(p, "permit") == 0) {
a->action = ACL_PERMIT;
break;
}
if(strcmpic(p, "deny" ) == 0) {
a->action = ACL_DENY;
break;
}
/* no break */
default:
goto load_aclfile_error;
}
}
*prev = *curr;
fclose(fp);
if(current_aclfile) {
current_aclfile->unloader = unload_aclfile;
}
current_aclfile = fs;
return(0);
load_aclfile_error:
fprintf(logfp,
"%s: can't load access control list '%s': ",
prog, aclfile);
fperror(logfp, "");
return(-1);
}