/* * Make the HTTP header's Referer line according to preferences * (default is "host" i.e. "scheme://hostname/" ) */ static char *Http_get_referer(const DilloUrl *url) { char *referer = NULL; if (!strcmp(prefs.http_referer, "host")) { referer = dStrconcat("Referer: ", URL_SCHEME(url), "://", URL_AUTHORITY(url), "/", "\r\n", NULL); } else if (!strcmp(prefs.http_referer, "path")) { referer = dStrconcat("Referer: ", URL_SCHEME(url), "://", URL_AUTHORITY(url), URL_PATH_(url) ? URL_PATH(url) : "/", "\r\n", NULL); } if (!referer) referer = dStrdup(""); _MSG("http, referer='%s'\n", referer); return referer; }
/* * 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; }
/* * Return a new string for the request used to tunnel HTTPS through a proxy. * As of 2009, the best reference appears to be section 5 of RFC 2817. */ char *a_Http_make_connect_str(const DilloUrl *url) { Dstr *dstr; const char *auth1; int auth_len; char *auth2, *proxy_auth, *retstr; dReturn_val_if_fail(Http_must_use_proxy(url), NULL); dstr = dStr_new(""); auth1 = URL_AUTHORITY(url); auth_len = strlen(auth1); if (auth_len > 0 && !isdigit(auth1[auth_len - 1])) /* if no port number, add HTTPS port */ auth2 = dStrconcat(auth1, ":443", NULL); else auth2 = dStrdup(auth1); proxy_auth = HTTP_Proxy_Auth_base64 ? dStrconcat ("Proxy-Authorization: Basic ", HTTP_Proxy_Auth_base64, "\r\n", NULL) : dStrdup(""); dStr_sprintfa( dstr, "CONNECT %s HTTP/1.1\r\n" "Host: %s\r\n" "%s" "\r\n", auth2, auth2, proxy_auth); dFree(auth2); dFree(proxy_auth); retstr = dstr->str; dStr_free(dstr, 0); return retstr; }
static void Auth_do_auth_dialog_cb(const char *user, const char *password, void *vData) { AuthDialogData_t *data; AuthHost_t *host; AuthRealm_t *realm; data = (AuthDialogData_t *)vData; /* find or create the host */ if (!(host = Auth_host_by_url(data->url))) { /* create a new host */ host = dNew(AuthHost_t, 1); host->scheme = dStrdup(URL_SCHEME(data->url)); host->authority = dStrdup(URL_AUTHORITY(data->url)); host->realms = dList_new(1); dList_append(auth_hosts, host); } /* find or create the realm */ if (!(realm = Auth_realm_by_name(host, data->auth_parse->realm))) { realm = dNew0(AuthRealm_t, 1); realm->name = dStrdup(data->auth_parse->realm); realm->paths = dList_new(1); dList_append(host->realms, realm); } realm->type = data->auth_parse->type; dFree(realm->authorization); realm->authorization = NULL; Auth_realm_add_path(realm, URL_PATH(data->url)); if (realm->type == BASIC) { char *user_password = dStrconcat(user, ":", password, NULL); char *response = a_Misc_encode_base64(user_password); char *authorization = dStrconcat("Authorization: Basic ", response, "\r\n", NULL); dFree(realm->authorization); realm->authorization = authorization; dFree(response); dStrshred(user_password); dFree(user_password); } else if (realm->type == DIGEST) { dFree(realm->username); realm->username = dStrdup(user); realm->nonce_count = 0; dFree(realm->nonce); realm->nonce = dStrdup(data->auth_parse->nonce); dFree(realm->opaque); realm->opaque = dStrdup(data->auth_parse->opaque); realm->algorithm = data->auth_parse->algorithm; dFree(realm->domain); realm->domain = dStrdup(data->auth_parse->domain); realm->qop = data->auth_parse->qop; dFree(realm->cnonce); if (realm->qop != QOPNOTSET) realm->cnonce = a_Digest_create_cnonce(); if (!a_Digest_compute_digest(realm, user, password)) { MSG("Auth_do_auth_dialog_cb: a_Digest_compute_digest failed.\n"); dList_remove_fast(host->realms, realm); Auth_realm_delete(realm); } } else { MSG("Auth_do_auth_dialog_cb: Unknown auth type: %i\n", realm->type); } dStrshred((char *)password); }
/* * Make the http query string */ Dstr *a_Http_make_query_str(const DilloUrl *url, const DilloUrl *requester, bool_t use_proxy) { char *ptr, *cookies, *referer, *auth; Dstr *query = dStr_new(""), *request_uri = dStr_new(""), *proxy_auth = dStr_new(""); if (use_proxy) { dStr_sprintfa(request_uri, "%s%s", URL_STR(url), (URL_PATH_(url) || URL_QUERY_(url)) ? "" : "/"); if ((ptr = strrchr(request_uri->str, '#'))) dStr_truncate(request_uri, ptr - request_uri->str); if (HTTP_Proxy_Auth_base64) dStr_sprintf(proxy_auth, "Proxy-Authorization: Basic %s\r\n", HTTP_Proxy_Auth_base64); } else { dStr_sprintfa(request_uri, "%s%s%s%s", URL_PATH(url), URL_QUERY_(url) ? "?" : "", URL_QUERY(url), (URL_PATH_(url) || URL_QUERY_(url)) ? "" : "/"); } cookies = a_Cookies_get_query(url, requester); auth = a_Auth_get_auth_str(url, request_uri->str); referer = Http_get_referer(url); if (URL_FLAGS(url) & URL_Post) { Dstr *content_type = Http_make_content_type(url); dStr_sprintfa( query, "POST %s HTTP/1.1\r\n" "Connection: close\r\n" "Accept: text/*,image/*,*/*;q=0.2\r\n" "Accept-Charset: utf-8,*;q=0.8\r\n" "Accept-Encoding: gzip\r\n" "%s" /* language */ "%s" /* auth */ "Host: %s\r\n" "%s" "%s" "User-Agent: %s\r\n" "Content-Length: %ld\r\n" "Content-Type: %s\r\n" "%s" /* cookies */ "\r\n", request_uri->str, HTTP_Language_hdr, auth ? auth : "", URL_AUTHORITY(url), proxy_auth->str, referer, prefs.http_user_agent, (long)URL_DATA(url)->len, content_type->str, cookies); dStr_append_l(query, URL_DATA(url)->str, URL_DATA(url)->len); dStr_free(content_type, TRUE); } else { dStr_sprintfa( query, "GET %s HTTP/1.1\r\n" "%s" "Connection: close\r\n" "Accept: text/*,image/*,*/*;q=0.2\r\n" "Accept-Charset: utf-8,*;q=0.8\r\n" "Accept-Encoding: gzip\r\n" "%s" /* language */ "%s" /* auth */ "Host: %s\r\n" "%s" "%s" "User-Agent: %s\r\n" "%s" /* cookies */ "\r\n", request_uri->str, (URL_FLAGS(url) & URL_E2EQuery) ? "Cache-Control: no-cache\r\nPragma: no-cache\r\n" : "", HTTP_Language_hdr, auth ? auth : "", URL_AUTHORITY(url), proxy_auth->str, referer, prefs.http_user_agent, cookies); } dFree(referer); dFree(cookies); dFree(auth); dStr_free(request_uri, TRUE); dStr_free(proxy_auth, TRUE); _MSG("Query: {%s}\n", dStr_printable(query, 8192)); return query; }