int is_direct_name (const char *name) { int len, i; g_debug("checking %s is for direct?\n", name); name = downcase(strdup(name)); len = strlen(name); if (len < 1) return 0; for (i=0; i<n_direct_addr_list; i++ ) { int neg; const char *dname; dname = direct_addr_list[i].name; if (dname == NULL) continue; neg = direct_addr_list[i].negative; if (domain_match(name, dname)) { //debug("match with: %s%s\n", dname, neg? " (negative)": ""); if (neg) { return 0; } else { return 1; } } } return 0; }
char *mget_cookie_create_request_header(const MGET_IRI *iri) { int it, init = 0; time_t now = time(NULL); mget_buffer_t buf; debug_printf("cookie_create_request_header for host=%s path=%s\n",iri->host,iri->path); pthread_mutex_lock(&cookies_mutex); for (it = 0; it < mget_vector_size(cookies); it++) { MGET_COOKIE *cookie = mget_vector_get(cookies, it); if (((!cookie->host_only && domain_match(cookie->domain, iri->host)) || (cookie->host_only && !strcasecmp(cookie->domain, iri->host))) && (!cookie->expires || cookie->expires >= now) && (!cookie->secure_only || (cookie->secure_only && iri->scheme == IRI_SCHEME_HTTPS)) && path_match(cookie->path, iri->path)) { if (!init) { mget_buffer_init(&buf, NULL, 128); init = 1; } if (buf.length) mget_buffer_printf_append2(&buf, "; %s=%s", cookie->name, cookie->value); else mget_buffer_printf_append2(&buf, "%s=%s", cookie->name, cookie->value); } } pthread_mutex_unlock(&cookies_mutex); return init ? buf.data : NULL; }
/********************************************************************* * * Function : host_matches * * Description : Compares a host against a host pattern. * * Parameters : * 1 : url = The URL to match * 2 : pattern = The URL pattern * * Returns : TRUE for yes, FALSE otherwise. * *********************************************************************/ static int host_matches(const struct http_request *http, const struct pattern_spec *pattern) { assert(http->host != NULL); #ifdef FEATURE_EXTENDED_HOST_PATTERNS return ((NULL == pattern->pattern.url_spec.host_regex) || (0 == regexec(pattern->pattern.url_spec.host_regex, http->host, 0, NULL, 0))); #else return ((NULL == pattern->pattern.url_spec.dbuffer) || (0 == domain_match(pattern, http))); #endif }
static int match_cookie(ParsedURL *pu, struct cookie *cookie, char *domainname) { if (!domainname) return 0; if (!domain_match(domainname, cookie->domain->ptr)) return 0; if (strncmp(cookie->path->ptr, pu->file, cookie->path->length) != 0) return 0; #ifdef USE_SSL if (cookie->flag & COO_SECURE && pu->scheme != SCM_HTTPS) return 0; #else /* not USE_SSL */ if (cookie->flag & COO_SECURE) return 0; #endif /* not USE_SSL */ if (cookie->portl && !port_match(cookie->portl, pu->port)) return 0; return 1; }
int filter_query(uint8_t *buf, int buflen) { ns_msg msg; if (local_ns_initparse(buf, buflen, &msg) < 0) { logger_log(LOG_ERR, "local_ns_initparse"); return -1; } else { int i; const char *host = hostname_from_question(msg); for (i = 0; i < black_list.elements; i++) { int rc = domain_match(host, black_list.domains[i]); if (rc) { logger_log(LOG_INFO, "request %s", host); return 0; } } } return 1; }
int check_avoid_wrong_number_of_dots_domain( Str domain ) { TextListItem *tl; int avoid_wrong_number_of_dots_domain = FALSE; if (Cookie_avoid_wrong_number_of_dots_domains && Cookie_avoid_wrong_number_of_dots_domains->nitem > 0) { for (tl = Cookie_avoid_wrong_number_of_dots_domains->first; tl != NULL; tl = tl->next) { if (domain_match(domain->ptr, tl->ptr)) { avoid_wrong_number_of_dots_domain = TRUE; break; } } } if (avoid_wrong_number_of_dots_domain == TRUE) { return TRUE; } else { return FALSE; } }
// normalize/sanitize and store cookies int mget_cookie_normalize_cookie(const MGET_IRI *iri, MGET_COOKIE *cookie) { /* log_printf("normalize cookie %s=%s\n", cookie->name, cookie->value); log_printf("< %s=%s\n", cookie->name, cookie->value); log_printf("< expires=%ld max-age=%ld\n", cookie->expires, cookie->maxage); log_printf("< domain=%s\n", cookie->domain); log_printf("< path=%s\n", cookie->path); log_printf("< normalized=%d persistent=%d hostonly=%d secure=%d httponly=%d\n", cookie->normalized, cookie->persistent, cookie->host_only, cookie->secure_only, cookie->http_only); */ cookie->normalized = 0; if (cookie->maxage) cookie->expires = cookie->maxage; cookie->persistent = !!cookie->expires; if (cookie->domain) { char *p; // convert domain to lowercase for (p = (char *)cookie->domain; *p; p++) if (isupper(*p)) *p = tolower(*p); } if (iri) { // cookies comes from a HTTP header and needs checking if (!cookie->domain) cookie->domain = strdup(""); // respect http://publicsuffix.org/list/ to avoid "supercookies" if (mget_vector_size(suffixes) > 0 && mget_cookie_suffix_match(cookie->domain)) { info_printf("Supercookie %s not accepted\n", cookie->domain); return 0; } if (*cookie->domain) { if (domain_match(cookie->domain, iri->host)) { cookie->host_only = 0; } else { debug_printf("Domain mismatch: %s %s\n", cookie->domain, iri->host); return 0; // ignore cookie } } else { xfree(cookie->domain); cookie->domain = strdup(iri->host); cookie->host_only = 1; } if (!cookie->path || *cookie->path != '/') { const char *p = iri->path ? strrchr(iri->path, '/') : NULL; if (p && p != iri->path) { cookie->path = strndup(iri->path, p - iri->path); } else { cookie->path = strdup("/"); // err_printf(_("Unexpected URI without '/': %s\n"), iri->path); // return 0; // ignore cookie } } } cookie->normalized = 1; /* log_printf("> %s=%s\n", cookie->name, cookie->value); log_printf("> expires=%ld max-age=%ld\n", cookie->expires, cookie->maxage); log_printf("> domain=%s\n", cookie->domain); log_printf("> path=%s\n", cookie->path); log_printf("> normalized=%d persistent=%d hostonly=%d secure=%d httponly=%d\n", cookie->normalized, cookie->persistent, cookie->host_only, cookie->secure_only, cookie->http_only); */ return 1; }
int add_cookie(ParsedURL *pu, Str name, Str value, time_t expires, Str domain, Str path, int flag, Str comment, int version, Str port, Str commentURL) { struct cookie *p; char *domainname = (version == 0) ? FQDN(pu->host) : pu->host; Str odomain = domain, opath = path; struct portlist *portlist = NULL; int use_security = !(flag & COO_OVERRIDE); #define COOKIE_ERROR(err) if(!((err) & COO_OVERRIDE_OK) || use_security) return (err) #ifdef DEBUG fprintf(stderr, "host: [%s, %s] %d\n", pu->host, pu->file, flag); fprintf(stderr, "cookie: [%s=%s]\n", name->ptr, value->ptr); fprintf(stderr, "expires: [%s]\n", asctime(gmtime(&expires))); if (domain) fprintf(stderr, "domain: [%s]\n", domain->ptr); if (path) fprintf(stderr, "path: [%s]\n", path->ptr); fprintf(stderr, "version: [%d]\n", version); if (port) fprintf(stderr, "port: [%s]\n", port->ptr); #endif /* DEBUG */ /* [RFC 2109] s. 4.3.2 case 2; but this (no request-host) shouldn't happen */ if (!domainname) return COO_ENODOT; if (domain) { char *dp; /* [DRAFT 12] s. 4.2.2 (does not apply in the case that * host name is the same as domain attribute for version 0 * cookie) * I think that this rule has almost the same effect as the * tail match of [NETSCAPE]. */ if (domain->ptr[0] != '.' && (version > 0 || strcasecmp(domainname, domain->ptr) != 0)) domain = Sprintf(".%s", domain->ptr); if (version == 0) { /* [NETSCAPE] rule */ int n = total_dot_number(domain->ptr, domain->ptr + domain->length, 3); if (n < 2) { if (! check_avoid_wrong_number_of_dots_domain(domain)) { COOKIE_ERROR(COO_ESPECIAL); } } else if (n == 2) { char **sdomain; int ok = 0; for (sdomain = special_domain; !ok && *sdomain; sdomain++) { int offset = domain->length - strlen(*sdomain); if (offset >= 0 && strcasecmp(*sdomain, &domain->ptr[offset]) == 0) ok = 1; } if (!ok && ! check_avoid_wrong_number_of_dots_domain(domain)) { COOKIE_ERROR(COO_ESPECIAL); } } } else { /* [DRAFT 12] s. 4.3.2 case 2 */ if (strcasecmp(domain->ptr, ".local") != 0 && contain_no_dots(&domain->ptr[1], &domain->ptr[domain->length])) COOKIE_ERROR(COO_ENODOT); } /* [RFC 2109] s. 4.3.2 case 3 */ if (!(dp = domain_match(domainname, domain->ptr))) COOKIE_ERROR(COO_EDOM); /* [RFC 2409] s. 4.3.2 case 4 */ /* Invariant: dp contains matched domain */ if (version > 0 && !contain_no_dots(domainname, dp)) COOKIE_ERROR(COO_EBADHOST); } if (path) { /* [RFC 2109] s. 4.3.2 case 1 */ if (version > 0 && strncmp(path->ptr, pu->file, path->length) != 0) COOKIE_ERROR(COO_EPATH); } if (port) { /* [DRAFT 12] s. 4.3.2 case 5 */ portlist = make_portlist(port); if (portlist && !port_match(portlist, pu->port)) COOKIE_ERROR(COO_EPORT); } if (!domain) domain = Strnew_charp(domainname); if (!path) { path = Strnew_charp(pu->file); while (path->length > 0 && Strlastchar(path) != '/') Strshrink(path, 1); if (Strlastchar(path) == '/') Strshrink(path, 1); } p = get_cookie_info(domain, path, name); if (!p) { p = New(struct cookie); p->flag = 0; if (default_use_cookie) p->flag |= COO_USE; p->next = First_cookie; First_cookie = p; }