📄 acl.c
字号:
/* * $Id: acl.c,v 1.197.2.10 1999/07/07 02:12:48 wessels Exp $ * * DEBUG: section 28 Access Control * AUTHOR: Duane Wessels * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * * Squid is the result of efforts by numerous individuals from the * Internet community. Development is led by Duane Wessels of the * National Laboratory for Applied Network Research and funded by the * National Science Foundation. Squid is Copyrighted (C) 1998 by * Duane Wessels and the University of California San Diego. Please * see the COPYRIGHT file for full details. Squid incorporates * software developed and/or copyrighted by other sources. Please see * the CREDITS file for full details. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */#include "squid.h"#include "splay.h"static int aclFromFile = 0;static FILE *aclFile;static hash_table *proxy_auth_cache = NULL;static void aclParseDomainList(void *curlist);static void aclParseIpList(void *curlist);static void aclParseIntlist(void *curlist);static void aclParseWordList(void *curlist);static void aclParseProtoList(void *curlist);static void aclParseMethodList(void *curlist);static void aclParseTimeSpec(void *curlist);static void aclParseIntRange(void *curlist);static char *strtokFile(void);static void aclDestroyAclList(acl_list * list);static void aclDestroyTimeList(acl_time_data * data);static void aclDestroyIntRange(intrange *);static FREE aclFreeProxyAuthUser;static struct _acl *aclFindByName(const char *name);static int aclMatchAcl(struct _acl *, aclCheck_t *);static int aclMatchIntegerRange(intrange * data, int i);static int aclMatchTime(acl_time_data * data, time_t when);static int aclMatchUser(wordlist * data, const char *ident);static int aclMatchIp(void *dataptr, struct in_addr c);static int aclMatchDomainList(void *dataptr, const char *);static int aclMatchIntegerRange(intrange * data, int i);#if SQUID_SNMPstatic int aclMatchWordList(wordlist *, const char *);#endifstatic squid_acl aclStrToType(const char *s);static int decode_addr(const char *, struct in_addr *, struct in_addr *);static void aclCheck(aclCheck_t * checklist);static void aclCheckCallback(aclCheck_t * checklist, allow_t answer);#if USE_IDENTstatic IDCB aclLookupIdentDone;#endifstatic IPH aclLookupDstIPDone;static IPH aclLookupDstIPforASNDone;static FQDNH aclLookupSrcFQDNDone;static FQDNH aclLookupDstFQDNDone;static void aclLookupProxyAuthStart(aclCheck_t * checklist);static void aclLookupProxyAuthDone(void *data, char *result);static wordlist *aclDumpIpList(void *);static wordlist *aclDumpDomainList(void *data);static wordlist *aclDumpTimeSpecList(acl_time_data *);static wordlist *aclDumpRegexList(relist * data);static wordlist *aclDumpIntlistList(intlist * data);static wordlist *aclDumpIntRangeList(intrange * data);static wordlist *aclDumpProtoList(intlist * data);static wordlist *aclDumpMethodList(intlist * data);static SPLAYCMP aclIpNetworkCompare;static SPLAYCMP aclHostDomainCompare;static SPLAYCMP aclDomainCompare;static SPLAYWALKEE aclDumpIpListWalkee;static SPLAYWALKEE aclDumpDomainListWalkee;static SPLAYFREE aclFreeIpData;#if USE_ARP_ACLstatic void aclParseArpList(void *curlist);static int decode_eth(const char *asc, char *eth);static int aclMatchArp(void *dataptr, struct in_addr c);static wordlist *aclDumpArpList(void *);static SPLAYCMP aclArpCompare;static SPLAYWALKEE aclDumpArpListWalkee;#endifstatic char *strtokFile(void){ char *t, *fn; LOCAL_ARRAY(char, buf, 256); strtok_again: if (!aclFromFile) { t = (strtok(NULL, w_space)); if (t && (*t == '\"' || *t == '\'')) { /* quote found, start reading from file */ fn = ++t; while (*t && *t != '\"' && *t != '\'') t++; *t = '\0'; if ((aclFile = fopen(fn, "r")) == NULL) { debug(28, 0) ("strtokFile: %s not found\n", fn); return (NULL); } aclFromFile = 1; } else { return t; } } /* aclFromFile */ if (fgets(buf, 256, aclFile) == NULL) { /* stop reading from file */ fclose(aclFile); aclFromFile = 0; goto strtok_again; } else { t = buf; /* skip leading and trailing white space */ t += strspn(buf, w_space); t[strcspn(t, w_space)] = '\0'; /* skip comments */ if (*t == '#') goto strtok_again; /* skip blank lines */ if (!*t) goto strtok_again; return t; }}static squid_aclaclStrToType(const char *s){ if (!strcmp(s, "src")) return ACL_SRC_IP; if (!strcmp(s, "dst")) return ACL_DST_IP; if (!strcmp(s, "myip")) return ACL_MY_IP; if (!strcmp(s, "domain")) return ACL_DST_DOMAIN; if (!strcmp(s, "dstdomain")) return ACL_DST_DOMAIN; if (!strcmp(s, "srcdomain")) return ACL_SRC_DOMAIN; if (!strcmp(s, "dstdom_regex")) return ACL_DST_DOM_REGEX; if (!strcmp(s, "srcdom_regex")) return ACL_SRC_DOM_REGEX; if (!strcmp(s, "time")) return ACL_TIME; if (!strcmp(s, "pattern")) return ACL_URLPATH_REGEX; if (!strcmp(s, "urlpath_regex")) return ACL_URLPATH_REGEX; if (!strcmp(s, "url_regex")) return ACL_URL_REGEX; if (!strcmp(s, "port")) return ACL_URL_PORT;#if USE_IDENT if (!strcmp(s, "ident")) return ACL_IDENT;#endif if (!strncmp(s, "proto", 5)) return ACL_PROTO; if (!strcmp(s, "method")) return ACL_METHOD; if (!strcmp(s, "browser")) return ACL_BROWSER; if (!strcmp(s, "proxy_auth")) return ACL_PROXY_AUTH; if (!strcmp(s, "src_as")) return ACL_SRC_ASN; if (!strcmp(s, "dst_as")) return ACL_DST_ASN;#if SQUID_SNMP if (!strcmp(s, "snmp_community")) return ACL_SNMP_COMMUNITY;#endif if (!strcmp(s, "src_rtt")) return ACL_NETDB_SRC_RTT;#if USE_ARP_ACL if (!strcmp(s, "arp")) return ACL_SRC_ARP;#endif return ACL_NONE;}const char *aclTypeToStr(squid_acl type){ if (type == ACL_SRC_IP) return "src"; if (type == ACL_DST_IP) return "dst"; if (type == ACL_MY_IP) return "myip"; if (type == ACL_DST_DOMAIN) return "dstdomain"; if (type == ACL_SRC_DOMAIN) return "srcdomain"; if (type == ACL_DST_DOM_REGEX) return "dstdom_regex"; if (type == ACL_SRC_DOM_REGEX) return "srcdom_regex"; if (type == ACL_TIME) return "time"; if (type == ACL_URLPATH_REGEX) return "urlpath_regex"; if (type == ACL_URL_REGEX) return "url_regex"; if (type == ACL_URL_PORT) return "port";#if USE_IDENT if (type == ACL_IDENT) return "ident";#endif if (type == ACL_PROTO) return "proto"; if (type == ACL_METHOD) return "method"; if (type == ACL_BROWSER) return "browser"; if (type == ACL_PROXY_AUTH) return "proxy_auth"; if (type == ACL_SRC_ASN) return "src_as"; if (type == ACL_DST_ASN) return "dst_as";#if SQUID_SNMP if (type == ACL_SNMP_COMMUNITY) return "snmp_community";#endif if (type == ACL_NETDB_SRC_RTT) return "src_rtt";#if USE_ARP_ACL if (type == ACL_SRC_ARP) return "arp";#endif return "ERROR";}static acl *aclFindByName(const char *name){ acl *a; for (a = Config.aclList; a; a = a->next) if (!strcasecmp(a->name, name)) return a; return NULL;}static voidaclParseIntlist(void *curlist){ intlist **Tail; intlist *q = NULL; char *t = NULL; for (Tail = curlist; *Tail; Tail = &((*Tail)->next)); while ((t = strtokFile())) { q = memAllocate(MEM_INTLIST); q->i = atoi(t); *(Tail) = q; Tail = &q->next; }}static voidaclParseIntRange(void *curlist){ intrange **Tail; intrange *q = NULL; char *t = NULL; for (Tail = curlist; *Tail; Tail = &((*Tail)->next)); while ((t = strtokFile())) { q = xcalloc(1, sizeof(intrange)); q->i = atoi(t); t = strchr(t, '-'); if (t && *(++t)) q->j = atoi(t); else q->j = q->i; *(Tail) = q; Tail = &q->next; }}static voidaclParseProtoList(void *curlist){ intlist **Tail; intlist *q = NULL; char *t = NULL; for (Tail = curlist; *Tail; Tail = &((*Tail)->next)); while ((t = strtokFile())) { q = memAllocate(MEM_INTLIST); q->i = (int) urlParseProtocol(t); *(Tail) = q; Tail = &q->next; }}static voidaclParseMethodList(void *curlist){ intlist **Tail; intlist *q = NULL; char *t = NULL; for (Tail = curlist; *Tail; Tail = &((*Tail)->next)); while ((t = strtokFile())) { q = memAllocate(MEM_INTLIST); q->i = (int) urlParseMethod(t); if (q->i == METHOD_PURGE) Config.onoff.enable_purge = 1; *(Tail) = q; Tail = &q->next; }}/* * Decode a ascii representation (asc) of a IP adress, and place * adress and netmask information in addr and mask. * This function should NOT be called if 'asc' is a hostname! */static intdecode_addr(const char *asc, struct in_addr *addr, struct in_addr *mask){ u_num32 a; int a1 = 0, a2 = 0, a3 = 0, a4 = 0; switch (sscanf(asc, "%d.%d.%d.%d", &a1, &a2, &a3, &a4)) { case 4: /* a dotted quad */ if (!safe_inet_addr(asc, addr)) { debug(28, 0) ("decode_addr: unsafe IP address: '%s'\n", asc); fatal("decode_addr: unsafe IP address"); } break; case 1: /* a significant bits value for a mask */ if (a1 >= 0 && a1 < 33) { addr->s_addr = a1 ? htonl(0xfffffffful << (32 - a1)) : 0; break; } default: debug(28, 0) ("decode_addr: Invalid IP address '%s'\n", asc); return 0; /* This is not valid address */ } if (mask != NULL) { /* mask == NULL if called to decode a netmask */ /* Guess netmask */ a = (u_num32) ntohl(addr->s_addr); if (!(a & 0xFFFFFFFFul)) mask->s_addr = htonl(0x00000000ul); else if (!(a & 0x00FFFFFF)) mask->s_addr = htonl(0xFF000000ul); else if (!(a & 0x0000FFFF)) mask->s_addr = htonl(0xFFFF0000ul); else if (!(a & 0x000000FF)) mask->s_addr = htonl(0xFFFFFF00ul); else mask->s_addr = htonl(0xFFFFFFFFul); } return 1;}#define SCAN_ACL1 "%[0123456789.]-%[0123456789.]/%[0123456789.]"#define SCAN_ACL2 "%[0123456789.]-%[0123456789.]"#define SCAN_ACL3 "%[0123456789.]/%[0123456789.]"#define SCAN_ACL4 "%[0123456789.]"static acl_ip_data *aclParseIpData(const char *t){ LOCAL_ARRAY(char, addr1, 256); LOCAL_ARRAY(char, addr2, 256); LOCAL_ARRAY(char, mask, 256); acl_ip_data *q = memAllocate(MEM_ACL_IP_DATA); acl_ip_data *r; acl_ip_data **Q; struct hostent *hp; char **x; debug(28, 5) ("aclParseIpData: %s\n", t); if (!strcasecmp(t, "all")) { q->addr1.s_addr = 0; q->addr2.s_addr = 0; q->mask.s_addr = 0; return q; } if (sscanf(t, SCAN_ACL1, addr1, addr2, mask) == 3) { (void) 0; } else if (sscanf(t, SCAN_ACL2, addr1, addr2) == 2) { mask[0] = '\0'; } else if (sscanf(t, SCAN_ACL3, addr1, mask) == 2) { addr2[0] = '\0'; } else if (sscanf(t, SCAN_ACL4, addr1) == 1) { addr2[0] = '\0'; mask[0] = '\0'; } else if (sscanf(t, "%[^/]/%s", addr1, mask) == 2) { addr2[0] = '\0'; } else if (sscanf(t, "%s", addr1) == 1) { /* * Note, must use plain gethostbyname() here because at startup * ipcache hasn't been initialized */ if ((hp = gethostbyname(addr1)) == NULL) { debug(28, 0) ("aclParseIpData: Bad host/IP: '%s'\n", t); safe_free(q); return NULL; } Q = &q; for (x = hp->h_addr_list; x != NULL && *x != NULL; x++) { if ((r = *Q) == NULL) r = *Q = memAllocate(MEM_ACL_IP_DATA); xmemcpy(&r->addr1.s_addr, *x, sizeof(r->addr1.s_addr)); r->addr2.s_addr = 0; r->mask.s_addr = no_addr.s_addr; /* 255.255.255.255 */ Q = &r->next; debug(28, 3) ("%s --> %s\n", addr1, inet_ntoa(r->addr1)); } return q; } else { debug(28, 0) ("aclParseIpData: Bad host/IP: '%s'\n", t); safe_free(q); return NULL; } /* Decode addr1 */ if (!decode_addr(addr1, &q->addr1, &q->mask)) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseIpData: Ignoring invalid IP acl entry: unknown first address '%s'\n", addr1); safe_free(q); return NULL; } /* Decode addr2 */ if (*addr2 && !decode_addr(addr2, &q->addr2, &q->mask)) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseIpData: Ignoring invalid IP acl entry: unknown second address '%s'\n", addr2); safe_free(q); return NULL; } /* Decode mask */ if (*mask && !decode_addr(mask, &q->mask, NULL)) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseIpData: Ignoring invalid IP acl entry: unknown netmask '%s'\n", mask); safe_free(q); return NULL; } q->addr1.s_addr &= q->mask.s_addr; q->addr2.s_addr &= q->mask.s_addr; /* 1.2.3.4/255.255.255.0 --> 1.2.3.0 */ return q;}/******************//* aclParseIpList *//******************/static voidaclParseIpList(void *curlist){ char *t = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -