home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Spezial
/
SPEZIAL2_97.zip
/
SPEZIAL2_97.iso
/
ANWEND
/
ONLINE
/
IJB20OS2
/
SOURCE
/
ACL.C
next >
Wrap
C/C++ Source or Header
|
1997-09-16
|
3KB
|
184 lines
char *acl_rcs = "$Id: acl.c,v 1.4 1997/08/22 12:47:42 ACJC Exp $";
/* Written and copyright by the Anonymous Coders and Junkbusters Corporation.
* Will be made available under the GNU General Public License.
* This software comes with NO WARRANTY.
*/
#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"
#define ACL_PERMIT 1
#define ACL_DENY -1
struct access_control_list {
long addr;
long mask;
short action;
};
static struct access_control_list acl[256], *acl_end;
int
block_acl(long client_addr)
{
struct access_control_list *a;
long target;
/* if not using an access control list, then permit the connection */
if(aclfile == NULL) return(0);
/* search the list backwards */
for(a = acl_end; a >= acl ; a--) {
target = client_addr & a->mask;
if(target == a->addr) {
if(a->action == ACL_PERMIT) {
return(0);
} else {
return(1);
}
}
}
return(1);
}
int
load_aclfile()
{
FILE *fp;
char buf[BUFSIZ], line[BUFSIZ], *v[3], *p;
int lineno = 0;
int i, masklength;
struct access_control_list *a, *eol;
static struct stat prev[1], curr[1];
/* note - this runs in the "single threaded" part of the code
* so we don't need per-client versions of the access control list
*/
if(stat(aclfile, curr) < 0) {
goto load_aclfile_error;
}
if(prev->st_mtime == curr->st_mtime) {
return(0);
}
fp = fopen(aclfile, "r");
if(fp == NULL) {
fprintf(logfp, "%s: can't open access control list %s\n",
prog, aclfile);
fperror(logfp, "");
return(-1);
}
eol = acl + SZ(acl);
acl_end = acl - 1;
for(a = acl; (fgets(line, sizeof(line), fp)) ; a++) {
lineno++;
strcpy(buf, line);
if((p = strpbrk(buf, "#\r\n"))) *p = '\0';
if(*buf == '\0') continue;
if(a == eol) {
fprintf(logfp, "%s: access control list overflow\n",
prog);
goto load_aclfile_error;
}
i = ssplit(buf, "/ \t", v, SZ(v), 1, 1);
masklength = 32;
switch(i) {
case 3:
p = v[2];
if(isdigit(*p) == 0) {
goto load_aclfile_error;
}
masklength = atoi(p);
if((masklength < 0)
|| (masklength > 32)) {
goto load_aclfile_error;
}
/* no break */
case 2:
p = v[1];
a->addr = ntohl(atoip(p));
if(a->addr == -1) {
fprintf(logfp,
"%s: can't resolve address for %s\n",
prog, p);
goto load_aclfile_error;
}
p = v[0];
if(strcmp(p, "permit") == 0) {
a->action = ACL_PERMIT;
break;
}
if(strcmp(p, "deny" ) == 0) {
a->action = ACL_DENY;
break;
}
/* no break */
default:
goto load_aclfile_error;
}
/* build the netmask */
a->mask = 0;
for(i=1; i <= masklength ; i++) {
a->mask |= (1 << (32 - i));
}
/* now mask off the host portion of the ip address
* (i.e. save on the network portion of the address).
*/
a->addr = a->addr & a->mask;
acl_end = a;
}
*prev = *curr;
fclose(fp);
return(0);
load_aclfile_error:
fclose(fp);
fprintf(logfp,
"%s: invalid access control list '%s' at line %d:\n%s",
prog, aclfile, lineno, line);
return(-1);
}