⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 acl.c

📁 -
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * $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 + -