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

📄 acl.c

📁 -
💻 C
📖 第 1 页 / 共 5 页
字号:
	debug(28, 3) ("aclMatchAclList: checking %s%s\n",	    list->op ? null_string : "!", list->acl->name);	if (aclMatchAcl(list->acl, checklist) != list->op) {	    debug(28, 3) ("aclMatchAclList: returning 0\n");	    return 0;	}	list = list->next;    }    debug(28, 3) ("aclMatchAclList: returning 1\n");    return 1;}intaclCheckFast(const acl_access * A, aclCheck_t * checklist){    int allow = 0;    debug(28, 5) ("aclCheckFast: list: %p\n", A);    while (A) {	allow = A->allow;	if (aclMatchAclList(A->acl_list, checklist))	    return allow;	A = A->next;    }    debug(28, 5) ("aclCheckFast: no matches, returning: %d\n", !allow);    return !allow;}static voidaclCheck(aclCheck_t * checklist){    allow_t allow = ACCESS_DENIED;    const acl_access *A;    int match;    ipcache_addrs *ia;    while ((A = checklist->access_list) != NULL) {	/*	 * If the _acl_access is no longer valid (i.e. its been	 * freed because of a reconfigure), then bail on this	 * access check.  For now, return ACCESS_DENIED.	 */	if (!cbdataValid(A)) {	    cbdataUnlock(A);	    break;	}	debug(28, 3) ("aclCheck: checking '%s'\n", A->cfgline);	allow = A->allow;	match = aclMatchAclList(A->acl_list, checklist);	if (checklist->state[ACL_DST_IP] == ACL_LOOKUP_NEEDED) {	    checklist->state[ACL_DST_IP] = ACL_LOOKUP_PENDING;	    ipcache_nbgethostbyname(checklist->request->host,		aclLookupDstIPDone,		checklist);	    return;	} else if (checklist->state[ACL_DST_ASN] == ACL_LOOKUP_NEEDED) {	    checklist->state[ACL_DST_ASN] = ACL_LOOKUP_PENDING;	    ipcache_nbgethostbyname(checklist->request->host,		aclLookupDstIPforASNDone,		checklist);	    return;	} else if (checklist->state[ACL_SRC_DOMAIN] == ACL_LOOKUP_NEEDED) {	    checklist->state[ACL_SRC_DOMAIN] = ACL_LOOKUP_PENDING;	    fqdncache_nbgethostbyaddr(checklist->src_addr,		aclLookupSrcFQDNDone,		checklist);	    return;	} else if (checklist->state[ACL_DST_DOMAIN] == ACL_LOOKUP_NEEDED) {	    ia = ipcacheCheckNumeric(checklist->request->host);	    if (ia == NULL) {		checklist->state[ACL_DST_DOMAIN] = ACL_LOOKUP_DONE;		return;	    }	    checklist->dst_addr = ia->in_addrs[0];	    checklist->state[ACL_DST_DOMAIN] = ACL_LOOKUP_PENDING;	    fqdncache_nbgethostbyaddr(checklist->dst_addr,		aclLookupDstFQDNDone,		checklist);	    return;	} else if (checklist->state[ACL_PROXY_AUTH] == ACL_LOOKUP_NEEDED) {	    debug(28, 3) ("aclCheck: checking password via authenticator\n");	    aclLookupProxyAuthStart(checklist);	    checklist->state[ACL_PROXY_AUTH] = ACL_LOOKUP_PENDING;	    return;	} else if (checklist->state[ACL_PROXY_AUTH] == ACL_PROXY_AUTH_NEEDED) {	    /* Special case. Client is required to resend the request	     * with authentication. The request is denied.	     */	    allow = ACCESS_REQ_PROXY_AUTH;	    match = -1;	}#if USE_IDENT	else if (checklist->state[ACL_IDENT] == ACL_LOOKUP_NEEDED) {	    debug(28, 3) ("aclCheck: Doing ident lookup\n");	    if (cbdataValid(checklist->conn)) {		identStart(&checklist->conn->me, &checklist->conn->peer,		    aclLookupIdentDone, checklist);		checklist->state[ACL_IDENT] = ACL_LOOKUP_PENDING;		return;	    } else {		debug(28, 1) ("aclCheck: Can't start ident lookup. No client connection\n");		cbdataUnlock(checklist->conn);		checklist->conn = NULL;		allow = 0;		match = -1;	    }	}#endif	/*	 * We are done with this _acl_access entry.  Either the request	 * is allowed, denied, requires authentication, or we move on to	 * the next entry.	 */	cbdataUnlock(A);	if (match) {	    debug(28, 3) ("aclCheck: match found, returning %d\n", allow);	    aclCheckCallback(checklist, allow);	    return;	}	checklist->access_list = A->next;	/*	 * Lock the next _acl_access entry	 */	if (A->next)	    cbdataLock(A->next);    }    debug(28, 3) ("aclCheck: NO match found, returning %d\n", !allow);    aclCheckCallback(checklist, !allow);}voidaclChecklistFree(aclCheck_t * checklist){    if (checklist->state[ACL_SRC_DOMAIN] == ACL_LOOKUP_PENDING)	fqdncacheUnregister(checklist->src_addr, checklist);    if (checklist->state[ACL_DST_DOMAIN] == ACL_LOOKUP_PENDING)	fqdncacheUnregister(checklist->dst_addr, checklist);    if (checklist->state[ACL_DST_IP] == ACL_LOOKUP_PENDING)	ipcacheUnregister(checklist->request->host, checklist);    if (checklist->request)	requestUnlink(checklist->request);    checklist->request = NULL;#if USE_IDENT    if (checklist->conn) {	cbdataUnlock(checklist->conn);	checklist->conn = NULL;    }#endif    cbdataFree(checklist);}static voidaclCheckCallback(aclCheck_t * checklist, allow_t answer){    debug(28, 3) ("aclCheckCallback: answer=%d\n", answer);    if (cbdataValid(checklist->callback_data))	checklist->callback(answer, checklist->callback_data);    cbdataUnlock(checklist->callback_data);    checklist->callback = NULL;    checklist->callback_data = NULL;    aclChecklistFree(checklist);}#if USE_IDENTstatic voidaclLookupIdentDone(const char *ident, void *data){    aclCheck_t *checklist = data;    if (ident) {	xstrncpy(checklist->ident, ident, sizeof(checklist->ident));	xstrncpy(checklist->request->user_ident, ident, sizeof(checklist->request->user_ident));    } else {	xstrncpy(checklist->ident, "-", sizeof(checklist->ident));    }    /*     * Cache the ident result in the connection, to avoid redoing ident lookup     * over and over on persistent connections     */    if (cbdataValid(checklist->conn) && !checklist->conn->ident[0])	xstrncpy(checklist->conn->ident, checklist->ident, sizeof(checklist->conn->ident));    aclCheck(checklist);}#endifstatic voidaclLookupDstIPDone(const ipcache_addrs * ia, void *data){    aclCheck_t *checklist = data;    checklist->state[ACL_DST_IP] = ACL_LOOKUP_DONE;    aclCheck(checklist);}static voidaclLookupDstIPforASNDone(const ipcache_addrs * ia, void *data){    aclCheck_t *checklist = data;    checklist->state[ACL_DST_ASN] = ACL_LOOKUP_DONE;    aclCheck(checklist);}static voidaclLookupSrcFQDNDone(const char *fqdn, void *data){    aclCheck_t *checklist = data;    checklist->state[ACL_SRC_DOMAIN] = ACL_LOOKUP_DONE;    aclCheck(checklist);}static voidaclLookupDstFQDNDone(const char *fqdn, void *data){    aclCheck_t *checklist = data;    checklist->state[ACL_DST_DOMAIN] = ACL_LOOKUP_DONE;    aclCheck(checklist);}static voidaclLookupProxyAuthDone(void *data, char *result){    aclCheck_t *checklist = data;    checklist->state[ACL_PROXY_AUTH] = ACL_LOOKUP_DONE;    debug(28, 4) ("aclLookupProxyAuthDone: result = %s\n",	result ? result : "NULL");    if (result && (strncasecmp(result, "OK", 2) == 0))	checklist->auth_user->passwd_ok = 1;    else	checklist->auth_user->passwd_ok = 0;    aclCheck(checklist);}aclCheck_t *aclChecklistCreate(const acl_access * A,    request_t * request,    struct in_addr src_addr,    struct in_addr my_addr,    const char *user_agent,    const char *ident){    int i;    aclCheck_t *checklist = memAllocate(MEM_ACLCHECK_T);    cbdataAdd(checklist, memFree, MEM_ACLCHECK_T);    checklist->access_list = A;    /*     * aclCheck() makes sure checklist->access_list is a valid     * pointer, so lock it.     */    cbdataLock(A);    if (request != NULL)	checklist->request = requestLink(request);    checklist->src_addr = src_addr;    checklist->my_addr = my_addr;    for (i = 0; i < ACL_ENUM_MAX; i++)	checklist->state[i] = ACL_LOOKUP_NONE;    if (user_agent)	xstrncpy(checklist->browser, user_agent, BROWSERNAMELEN);#if USE_IDENT    if (ident)	xstrncpy(checklist->ident, ident, USER_IDENT_SZ);#endif    checklist->auth_user = NULL;	/* init to NULL */    return checklist;}voidaclNBCheck(aclCheck_t * checklist, PF callback, void *callback_data){    checklist->callback = callback;    checklist->callback_data = callback_data;    cbdataLock(callback_data);    aclCheck(checklist);}/*********************//* Destroy functions *//*********************/static voidaclDestroyTimeList(acl_time_data * data){    acl_time_data *next = NULL;    for (; data; data = next) {	next = data->next;	memFree(data, MEM_ACL_TIME_DATA);    }}voidaclDestroyRegexList(relist * data){    relist *next = NULL;    for (; data; data = next) {	next = data->next;	regfree(&data->regex);	safe_free(data->pattern);	memFree(data, MEM_RELIST);    }}static voidaclFreeProxyAuthUser(void *data){    acl_proxy_auth_user *u = data;    xfree(u->user);    xfree(u->passwd);    memFree(u, MEM_ACL_PROXY_AUTH_USER);}static voidaclFreeIpData(void *p){    memFree(p, MEM_ACL_IP_DATA);}voidaclDestroyAcls(acl ** head){    acl *a = NULL;    acl *next = NULL;    for (a = *head; a; a = next) {	next = a->next;	debug(28, 3) ("aclDestroyAcls: '%s'\n", a->cfgline);	switch (a->type) {	case ACL_SRC_IP:	case ACL_DST_IP:	case ACL_MY_IP:	    splay_destroy(a->data, aclFreeIpData);	    break;	case ACL_SRC_ARP:	case ACL_DST_DOMAIN:	case ACL_SRC_DOMAIN:	    splay_destroy(a->data, xfree);	    break;#if SQUID_SNMP	case ACL_SNMP_COMMUNITY:#endif#if USE_IDENT	case ACL_IDENT:#endif	case ACL_PROXY_AUTH:	    wordlistDestroy((wordlist **) & a->data);	    break;	case ACL_TIME:	    aclDestroyTimeList(a->data);	    break;	case ACL_URL_REGEX:	case ACL_URLPATH_REGEX:	case ACL_BROWSER:	case ACL_SRC_DOM_REGEX:	case ACL_DST_DOM_REGEX:	    aclDestroyRegexList(a->data);	    break;	case ACL_PROTO:	case ACL_METHOD:	case ACL_SRC_ASN:	case ACL_DST_ASN:	case ACL_NETDB_SRC_RTT:	    intlistDestroy((intlist **) & a->data);	    break;	case ACL_URL_PORT:	    aclDestroyIntRange(a->data);	    break;	case ACL_NONE:	default:	    debug(28, 1) ("aclDestroyAcls: no case for ACL type %d\n", a->type);	    break;	}	safe_free(a->cfgline);	memFree(a, MEM_ACL);    }    *head = NULL;}static voidaclDestroyAclList(acl_list * list){    acl_list *next = NULL;    for (; list; list = next) {	next = list->next;	memFree(list, MEM_ACL_LIST);    }}voidaclDestroyAccessList(acl_access ** list){    acl_access *l = NULL;    acl_access *next = NULL;    for (l = *list; l; l = next) {	debug(28, 3) ("aclDestroyAccessList: '%s'\n", l->cfgline);	next = l->next;	aclDestroyAclList(l->acl_list);	l->acl_list = NULL;	safe_free(l->cfgline);	cbdataFree(l);    }    *list = NULL;}/* maex@space.net (06.09.1996) *    destroy an _acl_deny_info_list */voidaclDestroyDenyInfoList(acl_deny_info_list ** list){    acl_deny_info_list *a = NULL;    acl_deny_info_list *a_next = NULL;    acl_name_list *l = NULL;    acl_name_list *l_next = NULL;    for (a = *list; a; a = a_next) {	for (l = a->acl_list; l; l = l_next) {	    l_next = l->next;	    safe_free(l);	}	a_next = a->next;	xfree(a->err_page_name);	safe_free(a);    }    *list = NULL;}static voidaclDestroyIntRange(intrange * list){    intrange *w = NULL;    intrange *n = NULL;    for (w = list; w; w = n) {	n = w->next;	safe_free(w);    }}/* general compare functions, these are used for tree search algorithms * so they return <0, 0 or >0 *//* compare two domains */static intaclDomainCompare(const void *data, splayNode * n){    const char *d1 = data;    const char *d2 = n->data;    int l1;    int l2;    while ('.' == *d1)	d1++;    while ('.' == *d2)	d2++;    l1 = strlen(d1);    l2 = strlen(d2);    while (d1[l1] == d2[l2]) {	if ((l1 == 0) && (l2 == 0))	    return 0;		/* d1 == d2 */	l1--;	l2--;	if (0 == l1) {	    if ('.' == d2[l2 - 1]) {		debug(28, 0) ("WARNING: %s is a subdomain of %s\n", d2, d1);		debug(28, 0) ("WARNING: This may break Splay tree searching\n");		debug(28, 0) ("WARNING: You should remove '%s' from the ACL named '%s'\n", d2, AclMatchedName);	    }	    return -1;		/* d1 < d2 */	}	if (0 == l2) {	    if ('.' == d1[l1 - 1]) {		debug(28, 0) ("WARNING: %s is a subdomain of %s\n", d1, d2);		debug(28, 0) ("WARNING: This may break Splay tree searching\n");		debug(28, 0) ("WARNING: You should remove '%s' from the ACL named '%s'\n", d1, AclMatchedName);	    }	    return 1;		/* d1 > d2 */	}    }    return (d1[l1] - d2[l2]);}/* compare a host and a domain */static int

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -