#include "config.h" #include #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_SYS_TYPES_H #include #endif /* HAVE_SYS_TYPES_H */ #include #include #include "acl.h" #include "parse.h" #include "log.h" /* ================================================================= */ ACL::ACL() { next = 0; } void ACL::debug() { } /* ================================================================= */ ACLList::ACLList() { top = nextacl = 0; } ACLList::~ACLList() { if (top) { ACL *cp = top; while (cp) { if (cp == nextacl) break; ACL *np = cp->next; delete cp; cp = np; } } } void ACLList::regist(ACL *acl) { acl->next = top; top = acl; } void ACLList::debug() { ACL *cp = top; while (cp) { cp->debug(); cp = cp->next; } } /* ----------------------------------------------------------------- * =NAME= ACLList::set - set ACL data =SYOPSIS= int ACLList::set(char *s, int val) =DESCRIPTION= Analize follow format . := [ - ] [ / ] := | := | =RETURN= TRUE or FALSE * ----------------------------------------------------------------- */ int ACLList::set(char *p, int val) { char sname1[NAME_MAX + 1]; char sname2[NAME_MAX + 1]; char smask[NAME_MAX + 1]; DWORD addr1, addr2, mask; char c; *sname1 = *sname2 = *smask = 0; addr1 = addr2 = 0; mask = 0xffffffffl; c = *p; if (c >= '0' && c <= '9') getTokenStrUntil(&p, sname1, FILENAMELEN, '-'); else getTokenStr(&p, sname1, FILENAMELEN); if (!STRCMP(sname1, "ALL")) { addr1 = 0; addr2 = 0; mask = 0; goto ACLList_set_parse_end; } if (!STRCMP(sname2, "NONE")) { addr1 = 1; addr2 = 0; mask = 0; goto ACLList_set_parse_end; } if (!getHost(sname1, &addr1)) return FALSE; skipSpace(&p); if (*p == '-') { p++; skipSpace(&p); getTokenStrUntil(&p, sname2, FILENAMELEN, '/'); skipSpace(&p); if (!getHost(sname2, &addr2)) return FALSE; } if (*p == '/') { p++; skipSpace(&p); getTokenStr(&p, smask, FILENAMELEN); if (!getNetwork(smask, &mask)) return FALSE; } ACLList_set_parse_end: if (!addr2) { regist(new ACLNetwork(addr1, mask, val)); } else { regist(new ACLNetworkRange(addr1, addr2, mask, val)); } return TRUE; } /* ================================================================= */ int ACLNetwork::isMatch(DWORD ip) { return ((ip & netmask) == network) ? value : 0; } void ACLNetwork::debug() { PUTERR(0, ("(ACL Network)\n")); PUTERR(0, ("\t(network, mask, allow?) = (%08lx, %08lx, %d)\n", network, netmask, value)); } /* ================================================================= */ int ACLNetworkRange::isMatch(DWORD ip) { int i; UCHAR work, n1, n2; int match = 3;/* bit 0:net1 1:net2 */ int newmatch = 3; ip &= netmask; for (i = 0; i < count; i++) { work = ip & 0xff; n1 = net1[i]; n2 = net2[i]; if (work != n1) newmatch = match & 0xfe; if (work != n2) newmatch = match & 0xfd; switch(match) { case 1: /* match net1 only */ if (newmatch) break; if (work < n1) return 0; /* ip is a value less than net1 */ return value; /* ip is a range of net1 and net2 */ case 2: /* match net2 only */ if (newmatch) break; if (work > n2) return 0; /*ip is a value greater than net2 */ return value; /* ip is a range of net1 and net2 */ case 3: if (newmatch) break; if (work < n1 || work > n2) return 0; return value; } match = newmatch; ip >>= 8; } return value; } void ACLNetworkRange::debug() { int i; PUTERR(0, ("(ACL NetworkRange)\n")); PUTERR(0, ("\t(mask, count, allow?) = (%08ulx, %d, %d)\n", netmask, count, value)); for(i = 0; i < 4; i++) { PUTERR(0, ("\t(%08x, %08x)\n", net1[i], net2[i])); } }