📄 acl.c
字号:
splayNode **Top = curlist; acl_ip_data *q = NULL; while ((t = strtokFile())) { q = aclParseIpData(t); while (q != NULL) { *Top = splay_insert(q, *Top, aclIpNetworkCompare); q = q->next; } }}static voidaclParseTimeSpec(void *curlist){ acl_time_data *q = NULL; acl_time_data **Tail; int h1, m1, h2, m2; char *t = NULL; for (Tail = curlist; *Tail; Tail = &((*Tail)->next)); q = memAllocate(MEM_ACL_TIME_DATA); while ((t = strtokFile())) { if (*t < '0' || *t > '9') { /* assume its day-of-week spec */ while (*t) { switch (*t++) { case 'S': q->weekbits |= ACL_SUNDAY; break; case 'M': q->weekbits |= ACL_MONDAY; break; case 'T': q->weekbits |= ACL_TUESDAY; break; case 'W': q->weekbits |= ACL_WEDNESDAY; break; case 'H': q->weekbits |= ACL_THURSDAY; break; case 'F': q->weekbits |= ACL_FRIDAY; break; case 'A': q->weekbits |= ACL_SATURDAY; break; case 'D': q->weekbits |= ACL_WEEKDAYS; break; case '-': /* ignore placeholder */ break; default: debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseTimeSpec: Bad Day '%c'\n", *t); break; } } } else { /* assume its time-of-day spec */ if (sscanf(t, "%d:%d-%d:%d", &h1, &m1, &h2, &m2) < 4) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseTimeSpec: IGNORING Bad time range\n"); xfree(q); return; } q->start = h1 * 60 + m1; q->stop = h2 * 60 + m2; if (q->start > q->stop) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseTimeSpec: IGNORING Reversed time range\n"); xfree(q); return; } } } if (q->start == 0 && q->stop == 0) q->stop = 23 * 60 + 59; if (q->weekbits == 0) q->weekbits = ACL_ALLWEEK; *(Tail) = q; Tail = &q->next;}voidaclParseRegexList(void *curlist){ relist **Tail; relist *q = NULL; char *t = NULL; regex_t comp; int errcode; int flags = REG_EXTENDED | REG_NOSUB; for (Tail = curlist; *Tail; Tail = &((*Tail)->next)); while ((t = strtokFile())) { if (strcmp(t, "-i") == 0) { flags |= REG_ICASE; continue; } if (strcmp(t, "+i") == 0) { flags &= ~REG_ICASE; continue; } if ((errcode = regcomp(&comp, t, flags)) != 0) { char errbuf[256]; regerror(errcode, &comp, errbuf, sizeof errbuf); debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseRegexList: Invalid regular expression '%s': %s\n", t, errbuf); continue; } q = memAllocate(MEM_RELIST); q->pattern = xstrdup(t); q->regex = comp; *(Tail) = q; Tail = &q->next; }}static voidaclParseWordList(void *curlist){ char *t = NULL; while ((t = strtokFile())) wordlistAdd(curlist, t);}/**********************//* aclParseDomainList *//**********************/static voidaclParseDomainList(void *curlist){ char *t = NULL; splayNode **Top = curlist; while ((t = strtokFile())) { Tolower(t); *Top = splay_insert(xstrdup(t), *Top, aclDomainCompare); }}voidaclParseAclLine(acl ** head){ /* we're already using strtok() to grok the line */ char *t = NULL; acl *A = NULL; LOCAL_ARRAY(char, aclname, ACL_NAME_SZ); squid_acl acltype; int new_acl = 0; /* snarf the ACL name */ if ((t = strtok(NULL, w_space)) == NULL) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseAclLine: missing ACL name.\n"); return; } xstrncpy(aclname, t, ACL_NAME_SZ); /* snarf the ACL type */ if ((t = strtok(NULL, w_space)) == NULL) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseAclLine: missing ACL type.\n"); return; } if ((acltype = aclStrToType(t)) == ACL_NONE) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseAclLine: Invalid ACL type '%s'\n", t); return; } if ((A = aclFindByName(aclname)) == NULL) { debug(28, 3) ("aclParseAclLine: Creating ACL '%s'\n", aclname); A = memAllocate(MEM_ACL); xstrncpy(A->name, aclname, ACL_NAME_SZ); A->type = acltype; A->cfgline = xstrdup(config_input_line); new_acl = 1; } else { if (acltype != A->type) { debug(28, 0) ("aclParseAclLine: ACL '%s' already exists with different type, skipping.\n", A->name); return; } debug(28, 3) ("aclParseAclLine: Appending to '%s'\n", aclname); new_acl = 0; } /* * Here we set AclMatchedName in case we need to use it in a * warning message in aclDomainCompare(). */ AclMatchedName = aclname; /* ugly */ switch (A->type) { case ACL_SRC_IP: case ACL_DST_IP: case ACL_MY_IP: aclParseIpList(&A->data); break; case ACL_SRC_DOMAIN: case ACL_DST_DOMAIN: aclParseDomainList(&A->data); break; case ACL_TIME: aclParseTimeSpec(&A->data); break; case ACL_URL_REGEX: case ACL_URLPATH_REGEX: case ACL_BROWSER: case ACL_SRC_DOM_REGEX: case ACL_DST_DOM_REGEX: aclParseRegexList(&A->data); break; case ACL_SRC_ASN: case ACL_DST_ASN: case ACL_NETDB_SRC_RTT: aclParseIntlist(&A->data); break; case ACL_URL_PORT: aclParseIntRange(&A->data); break;#if USE_IDENT case ACL_IDENT: aclParseWordList(&A->data); break;#endif case ACL_PROTO: aclParseProtoList(&A->data); break; case ACL_METHOD: aclParseMethodList(&A->data); break; case ACL_PROXY_AUTH: aclParseWordList(&A->data); if (!proxy_auth_cache) { /* First time around, 7921 should be big enough */ proxy_auth_cache = hash_create((HASHCMP *) strcmp, 7921, hash_string); assert(proxy_auth_cache); } break;#if SQUID_SNMP case ACL_SNMP_COMMUNITY: aclParseWordList(&A->data); break;#endif#if USE_ARP_ACL case ACL_SRC_ARP: aclParseArpList(&A->data); break;#endif case ACL_NONE: default: fatal("Bad ACL type"); break; } /* * Clear AclMatchedName from our temporary hack */ AclMatchedName = NULL; /* ugly */ if (!new_acl) return; if (A->data == NULL) { debug(28, 0) ("aclParseAclLine: IGNORING invalid ACL: %s\n", A->cfgline); xfree(A); return; } /* append */ while (*head) head = &(*head)->next; *head = A;}/* does name lookup, returns page_id */intaclGetDenyInfoPage(acl_deny_info_list ** head, const char *name){ acl_deny_info_list *A = NULL; acl_name_list *L = NULL; A = *head; if (NULL == *head) /* empty list */ return -1; while (A) { L = A->acl_list; if (NULL == L) /* empty list should never happen, but in case */ continue; while (L) { if (!strcmp(name, L->name)) return A->err_page_id; L = L->next; } A = A->next; } return -1;}/* does name lookup, returns if it is a proxy_auth acl */intaclIsProxyAuth(const char *name){ acl *a = aclFindByName(name); if (a) return a->type == ACL_PROXY_AUTH; return 0;}/* maex@space.net (05.09.96) * get the info for redirecting "access denied" to info pages * TODO (probably ;-) * currently there is no optimization for * - more than one deny_info line with the same url * - a check, whether the given acl really is defined * - a check, whether an acl is added more than once for the same url */voidaclParseDenyInfoLine(acl_deny_info_list ** head){ char *t = NULL; acl_deny_info_list *A = NULL; acl_deny_info_list *B = NULL; acl_deny_info_list **T = NULL; acl_name_list *L = NULL; acl_name_list **Tail = NULL; /* first expect a page name */ if ((t = strtok(NULL, w_space)) == NULL) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseDenyInfoLine: missing 'error page' parameter.\n"); return; } A = xcalloc(1, sizeof(acl_deny_info_list)); A->err_page_id = errorReservePageId(t); A->err_page_name = xstrdup(t); A->next = (acl_deny_info_list *) NULL; /* next expect a list of ACL names */ Tail = &A->acl_list; while ((t = strtok(NULL, w_space))) { L = xcalloc(1, sizeof(acl_name_list)); xstrncpy(L->name, t, ACL_NAME_SZ); *Tail = L; Tail = &L->next; } if (A->acl_list == NULL) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseDenyInfoLine: deny_info line contains no ACL's, skipping\n"); xfree(A); return; } for (B = *head, T = head; B; T = &B->next, B = B->next); /* find the tail */ *T = A;}voidaclParseAccessLine(acl_access ** head){ char *t = NULL; acl_access *A = NULL; acl_access *B = NULL; acl_access **T = NULL; acl_list *L = NULL; acl_list **Tail = NULL; acl *a = NULL; /* first expect either 'allow' or 'deny' */ if ((t = strtok(NULL, w_space)) == NULL) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseAccessLine: missing 'allow' or 'deny'.\n"); return; } A = memAllocate(MEM_ACL_ACCESS); if (!strcmp(t, "allow")) A->allow = 1; else if (!strcmp(t, "deny")) A->allow = 0; else { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseAccessLine: expecting 'allow' or 'deny', got '%s'.\n", t); xfree(A); return; } /* next expect a list of ACL names, possibly preceeded * by '!' for negation */ Tail = &A->acl_list; while ((t = strtok(NULL, w_space))) { L = memAllocate(MEM_ACL_LIST); L->op = 1; /* defaults to non-negated */ if (*t == '!') { /* negated ACL */ L->op = 0; t++; } debug(28, 3) ("aclParseAccessLine: looking for ACL name '%s'\n", t); a = aclFindByName(t); if (a == NULL) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseAccessLine: ACL name '%s' not found.\n", t); xfree(L); continue; } L->acl = a; *Tail = L; Tail = &L->next; } if (A->acl_list == NULL) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseAccessLine: Access line contains no ACL's, skipping\n"); xfree(A); return; } A->cfgline = xstrdup(config_input_line); /* Append to the end of this list */ for (B = *head, T = head; B; T = &B->next, B = B->next); *T = A; /* We lock _acl_access structures in aclCheck() */ cbdataAdd(A, memFree, MEM_ACL_ACCESS);}/**************//* aclMatchIp *//**************/static intaclMatchIp(void *dataptr, struct in_addr c){ splayNode **Top = dataptr; *Top = splay_splay(&c, *Top, aclIpNetworkCompare); debug(28, 3) ("aclMatchIp: '%s' %s\n", inet_ntoa(c), splayLastResult ? "NOT found" : "found"); return !splayLastResult;}/**********************//* aclMatchDomainList *//**********************/static intaclMatchDomainList(void *dataptr, const char *host){ splayNode **Top = dataptr; if (host == NULL) return 0; debug(28, 3) ("aclMatchDomainList: checking '%s'\n", host); *Top = splay_splay(host, *Top, aclHostDomainCompare); debug(28, 3) ("aclMatchDomainList: '%s' %s\n", host, splayLastResult ? "NOT found" : "found"); return !splayLastResult;}intaclMatchRegex(relist * data, const char *word){ relist *first, *prev; if (word == NULL) return 0; debug(28, 3) ("aclMatchRegex: checking '%s'\n", word); first = data; prev = NULL; while (data) { debug(28, 3) ("aclMatchRegex: looking for '%s'\n", data->pattern); if (regexec(&data->regex, word, 0, 0, 0) == 0) { if (prev != NULL) { /* shift the element just found to the second position * in the list */ prev->next = data->next; data->next = first->next; first->next = data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -