/* * Check whether a URL scheme is downloadable. * Return: 1 enabled, 0 disabled. */ int a_Cache_download_enabled(const DilloUrl *url) { if (!dStrAsciiCasecmp(URL_SCHEME(url), "http") || !dStrAsciiCasecmp(URL_SCHEME(url), "https") || !dStrAsciiCasecmp(URL_SCHEME(url), "ftp")) return 1; return 0; }
/* * Return the host that contains a URL, or NULL if there is no such host. */ static AuthHost_t *Auth_host_by_url(const DilloUrl *url) { AuthHost_t *host; int i; for (i = 0; (host = dList_nth_data(auth_hosts, i)); i++) if (((dStrAsciiCasecmp(URL_SCHEME(url), host->scheme) == 0) && (dStrAsciiCasecmp(URL_AUTHORITY(url), host->authority) == 0))) return host; return NULL; }
/* * Test proxy settings and check the no_proxy domains list * Return value: whether to use proxy or not. */ static int Http_must_use_proxy(const DilloUrl *url) { char *np, *p, *tok; int ret = 0; if (HTTP_Proxy) { ret = 1; if (prefs.no_proxy) { const char *host = URL_HOST(url); size_t host_len = strlen(host); np = dStrdup(prefs.no_proxy); for (p = np; (tok = dStrsep(&p, " ")); ) { int start = host_len - strlen(tok); if (start >= 0 && dStrAsciiCasecmp(host + start, tok) == 0) { /* no_proxy token is suffix of host string */ ret = 0; break; } } dFree(np); } } _MSG("Http_must_use_proxy: %s\n %s\n", URL_STR(url), ret ? "YES":"NO"); return ret; }
/* * Compare function for searching a domain node by domain */ static int Domain_node_by_domain_cmp(const void *v1, const void *v2) { const DomainNode *node = v1; const char *domain = v2; return dStrAsciiCasecmp(node->domain, domain); }
static int Auth_parse_basic_challenge_cb(AuthParse_t *auth_parse, char *token, const char *value) { if (dStrAsciiCasecmp("realm", token) == 0) { if (!auth_parse->realm) auth_parse->realm = strdup(value); return 0; /* end parsing */ } else MSG("Auth_parse_basic_challenge_cb: Ignoring unknown parameter: %s = " "'%s'\n", token, value); return 1; }
/* * Initialize transfer decoder. Currently handles "chunked". */ Decode *a_Decode_transfer_init(const char *format) { Decode *dc = NULL; if (format && !dStrAsciiCasecmp(format, "chunked")) { int *chunk_remaining = dNew(int, 1); *chunk_remaining = 0; dc = dNew(Decode, 1); dc->leftover = dStr_new(""); dc->state = chunk_remaining; dc->decode = Decode_chunked; dc->free = Decode_chunked_free; dc->buffer = NULL; /* not used */ _MSG("chunked!\n"); }
static HostConnection_t *Http_host_connection_get(const char *host) { int i; HostConnection_t *hc; for (i = 0; i < dList_length(host_connections); i++) { hc = (HostConnection_t*) dList_nth_data(host_connections, i); if (dStrAsciiCasecmp(host, hc->host) == 0) return hc; } hc = dNew0(HostConnection_t, 1); Http_socket_queue_init(&hc->queue); hc->host = dStrdup(host); dList_append(host_connections, hc); return hc; }
static int Auth_parse_digest_challenge_cb(AuthParse_t *auth_parse, char *token, const char *value) { const char *const fn = "Auth_parse_digest_challenge_cb"; if (!dStrAsciiCasecmp("realm", token) && !auth_parse->realm) auth_parse->realm = strdup(value); else if (!strcmp("domain", token) && !auth_parse->domain) auth_parse->domain = strdup(value); else if (!strcmp("nonce", token) && !auth_parse->nonce) auth_parse->nonce = strdup(value); else if (!strcmp("opaque", token) && !auth_parse->opaque) auth_parse->opaque = strdup(value); else if (strcmp("stale", token) == 0) { if (dStrAsciiCasecmp("true", value) == 0) auth_parse->stale = 1; else if (dStrAsciiCasecmp("false", value) == 0) auth_parse->stale = 0; else { MSG("%s: Invalid stale value: %s\n", fn, value); return 0; } } else if (strcmp("algorithm", token) == 0) { if (strcmp("MD5", value) == 0) auth_parse->algorithm = MD5; else if (strcmp("MD5-sess", value) == 0) { /* auth_parse->algorithm = MD5SESS; */ MSG("%s: MD5-sess algorithm disabled (not tested because 'not " "correctly implemented yet' in Apache 2.2)\n", fn); return 0; } else { MSG("%s: Unknown algorithm: %s\n", fn, value); return 0; } } else if (strcmp("qop", token) == 0) { while (*value) { int len = strcspn(value, ", \t"); if (len == 4 && strncmp("auth", value, 4) == 0) { auth_parse->qop = AUTH; break; } if (len == 8 && strncmp("auth-int", value, 8) == 0) { /* auth_parse->qop = AUTHINT; */ /* Keep searching; maybe we'll find an "auth" yet. */ MSG("%s: auth-int qop disabled (not tested because 'not " "implemented yet' in Apache 2.2)\n", fn); } else { MSG("%s: Unknown qop value in %s\n", fn, value); } value += len; while (*value == ' ' || *value == '\t') value++; if (*value == ',') value++; while (*value == ' ' || *value == '\t') value++; } } else { MSG("%s: Ignoring unknown parameter: %s = '%s'\n", fn, token, value); } return 1; }
/* * Compare function for searching a domain node */ static int Domain_node_cmp(const void *v1, const void *v2) { const DomainNode *n1 = v1, *n2 = v2; return dStrAsciiCasecmp(n1->domain, n2->domain); }
/* * Scan, allocate, and set things according to header info. * (This function needs the whole header to work) */ static void Cache_parse_header(CacheEntry_t *entry) { char *header = entry->Header->str; char *Length, *Type, *location_str, *encoding; #ifndef DISABLE_COOKIES Dlist *Cookies; #endif Dlist *warnings; void *data; int i; _MSG("Cache_parse_header\n"); if (entry->Header->len > 12) { if (header[9] == '1' && header[10] == '0' && header[11] == '0') { /* 100: Continue. The "real" header has not come yet. */ MSG("An actual 100 Continue header!\n"); entry->Flags &= ~CA_GotHeader; dStr_free(entry->Header, 1); entry->Header = dStr_new(""); return; } if (header[9] == '3' && header[10] == '0' && (location_str = Cache_parse_field(header, "Location"))) { /* 30x: URL redirection */ DilloUrl *location_url = a_Url_new(location_str,URL_STR_(entry->Url)); if (prefs.filter_auto_requests == PREFS_FILTER_SAME_DOMAIN && !a_Url_same_organization(entry->Url, location_url)) { /* don't redirect; just show body like usual (if any) */ MSG("Redirection not followed from %s to %s\n", URL_HOST(entry->Url), URL_STR(location_url)); a_Url_free(location_url); } else { entry->Flags |= CA_Redirect; if (header[11] == '1') entry->Flags |= CA_ForceRedirect; /* 301 Moved Permanently */ else if (header[11] == '2') entry->Flags |= CA_TempRedirect; /* 302 Temporary Redirect */ if (URL_FLAGS(location_url) & (URL_Post + URL_Get) && dStrAsciiCasecmp(URL_SCHEME(location_url), "dpi") == 0 && dStrAsciiCasecmp(URL_SCHEME(entry->Url), "dpi") != 0) { /* Forbid dpi GET and POST from non dpi-generated urls */ MSG("Redirection Denied! '%s' -> '%s'\n", URL_STR(entry->Url), URL_STR(location_url)); a_Url_free(location_url); } else { entry->Location = location_url; } } dFree(location_str); } else if (strncmp(header + 9, "401", 3) == 0) { entry->Auth = Cache_parse_multiple_fields(header, "WWW-Authenticate"); } else if (strncmp(header + 9, "404", 3) == 0) { entry->Flags |= CA_NotFound; } } if ((warnings = Cache_parse_multiple_fields(header, "Warning"))) { for (i = 0; (data = dList_nth_data(warnings, i)); ++i) { MSG_HTTP("%s\n", (char *)data); dFree(data); } dList_free(warnings); } /* * Get Transfer-Encoding and initialize decoder */ encoding = Cache_parse_field(header, "Transfer-Encoding"); entry->TransferDecoder = a_Decode_transfer_init(encoding); if ((Length = Cache_parse_field(header, "Content-Length")) != NULL) { if (encoding) { /* * If Transfer-Encoding is present, Content-Length must be ignored. * If the Transfer-Encoding is non-identity, it is an error. */ if (dStrAsciiCasecmp(encoding, "identity")) MSG_HTTP("Content-Length and non-identity Transfer-Encoding " "headers both present.\n"); } else { entry->Flags |= CA_GotLength; entry->ExpectedSize = MAX(strtol(Length, NULL, 10), 0); } dFree(Length); } dFree(encoding); /* free Transfer-Encoding */ #ifndef DISABLE_COOKIES if ((Cookies = Cache_parse_multiple_fields(header, "Set-Cookie"))) { CacheClient_t *client; for (i = 0; (client = dList_nth_data(ClientQueue, i)); ++i) { if (client->Url == entry->Url) { DilloWeb *web = client->Web; if (!web->requester || a_Url_same_organization(entry->Url, web->requester)) { char *server_date = Cache_parse_field(header, "Date"); a_Cookies_set(Cookies, entry->Url, server_date); dFree(server_date); break; } } } if (i >= dList_length(ClientQueue)) { MSG("Cache: cookies not accepted from '%s'\n", URL_STR(entry->Url)); } for (i = 0; (data = dList_nth_data(Cookies, i)); ++i) dFree(data); dList_free(Cookies); } #endif /* !DISABLE_COOKIES */ /* * Get Content-Encoding and initialize decoder */ encoding = Cache_parse_field(header, "Content-Encoding"); entry->ContentDecoder = a_Decode_content_init(encoding); dFree(encoding); if (entry->ExpectedSize > 0) { if (entry->ExpectedSize > HUGE_FILESIZE) { entry->Flags |= CA_HugeFile; } /* Avoid some reallocs. With MAX_INIT_BUF we avoid a SEGFAULT * with huge files (e.g. iso files). * Note: the buffer grows automatically. */ dStr_free(entry->Data, 1); entry->Data = dStr_sized_new(MIN(entry->ExpectedSize, MAX_INIT_BUF)); } /* Get Content-Type */ if ((Type = Cache_parse_field(header, "Content-Type"))) { /* This HTTP Content-Type is not trusted. It's checked against real data * in Cache_process_queue(); only then CA_GotContentType becomes true. */ a_Cache_set_content_type(entry->Url, Type, "http"); _MSG("TypeHdr {%s} {%s}\n", Type, URL_STR(entry->Url)); _MSG("TypeMeta {%s}\n", entry->TypeMeta); dFree(Type); } Cache_ref_data(entry); }
int Cookies_rc_check() { const int line_maxlen = 4096; FILE *stream; char *filename; char line[line_maxlen]; bool_t default_deny = TRUE; /* Get a file pointer */ filename = dStrconcat(dGethomedir(), "/.dillo/cookiesrc", NULL); stream = fopen(filename, "r"); dFree(filename); if (!stream) { MSG_ERR("Cannot run test; cannot open cookiesrc.\n"); return 1; } /* Get all lines in the file */ while (!feof(stream)) { char *rc; line[0] = '\0'; rc = fgets(line, line_maxlen, stream); if (!rc && ferror(stream)) { MSG_ERR("Error while reading rule from cookiesrc: %s\n", dStrerror(errno)); fclose(stream); return 2; } /* Remove leading and trailing whitespaces */ dStrstrip(line); if (line[0] != '\0' && line[0] != '#') { int domain_end, i = 0; const char *rule; /* Get the domain */ while (line[i] != '\0' && !dIsspace(line[i])) i++; domain_end = i; /* Skip past whitespace */ while (dIsspace(line[i])) i++; line[domain_end] = '\0'; /* Get the rule */ rule = line + i; while (line[i] != '\0' && !dIsspace(line[i])) i++; line[i] = '\0'; if (!dStrAsciiCasecmp(line, "DEFAULT")) { if (!dStrAsciiCasecmp(rule, "ACCEPT") || !dStrAsciiCasecmp(rule, "ACCEPT_SESSION")) default_deny = FALSE; } else { if (!dStrAsciiCasecmp(rule, "DENY")) MSG_WARN("DENY rules in cookiesrc can interfere with test.\n"); } } } fclose(stream); if (default_deny) { MSG_ERR("Cannot run test with cookiesrc default of deny.\n"); return 1; } else { return 0; } }