mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
http: Allow overriding of the Host header.
* common/http.c (http_open): Add arg httphost. (http_open_document): Pass NULL for httphost. (send_request): Add arg httphost. If given, use HTTPHOST instead of SERVER. Use https with a proxy if requested. (http_verify_server_credentials): Do not stop at the first error message. * dirmngr/ocsp.c (do_ocsp_request): Adjust call to http_open. * keyserver/curl-shim.c (curl_easy_perform): Ditto. * dirmngr/ks-engine-http.c (ks_http_fetch): Ditto. * dirmngr/ks-engine-hkp.c (ks_hkp_help): Ditto.
This commit is contained in:
parent
25036ec6ab
commit
8b90d79818
@ -168,7 +168,8 @@ static int remove_escapes (char *string);
|
||||
static int insert_escapes (char *buffer, const char *string,
|
||||
const char *special);
|
||||
static uri_tuple_t parse_tuple (char *string);
|
||||
static gpg_error_t send_request (http_t hd, const char *auth,const char *proxy,
|
||||
static gpg_error_t send_request (http_t hd, const char *httphost,
|
||||
const char *auth,const char *proxy,
|
||||
const char *srvtag,strlist_t headers);
|
||||
static char *build_rel_path (parsed_uri_t uri);
|
||||
static gpg_error_t parse_response (http_t hd);
|
||||
@ -643,11 +644,13 @@ http_session_ref (http_session_t sess)
|
||||
}
|
||||
|
||||
|
||||
/* Start a HTTP retrieval and return on success in R_HD a context
|
||||
pointer for completing the the request and to wait for the
|
||||
response. */
|
||||
/* Start a HTTP retrieval and on success store at R_HD a context
|
||||
pointer for completing the request and to wait for the response.
|
||||
If HTTPHOST is not NULL it is used hor the Host header instead of a
|
||||
Host header derived from the URL. */
|
||||
gpg_error_t
|
||||
http_open (http_t *r_hd, http_req_t reqtype, const char *url,
|
||||
const char *httphost,
|
||||
const char *auth, unsigned int flags, const char *proxy,
|
||||
http_session_t session, const char *srvtag, strlist_t headers)
|
||||
{
|
||||
@ -669,7 +672,7 @@ http_open (http_t *r_hd, http_req_t reqtype, const char *url,
|
||||
|
||||
err = parse_uri (&hd->uri, url, 0, !!(flags & HTTP_FLAG_FORCE_TLS));
|
||||
if (!err)
|
||||
err = send_request (hd, auth, proxy, srvtag, headers);
|
||||
err = send_request (hd, httphost, auth, proxy, srvtag, headers);
|
||||
|
||||
if (err)
|
||||
{
|
||||
@ -868,7 +871,7 @@ http_open_document (http_t *r_hd, const char *document,
|
||||
{
|
||||
gpg_error_t err;
|
||||
|
||||
err = http_open (r_hd, HTTP_REQ_GET, document, auth, flags,
|
||||
err = http_open (r_hd, HTTP_REQ_GET, document, NULL, auth, flags,
|
||||
proxy, session, srvtag, headers);
|
||||
if (err)
|
||||
return err;
|
||||
@ -1353,7 +1356,7 @@ parse_tuple (char *string)
|
||||
* Returns 0 if the request was successful
|
||||
*/
|
||||
static gpg_error_t
|
||||
send_request (http_t hd, const char *auth,
|
||||
send_request (http_t hd, const char *httphost, const char *auth,
|
||||
const char *proxy, const char *srvtag, strlist_t headers)
|
||||
{
|
||||
gpg_error_t err;
|
||||
@ -1389,7 +1392,7 @@ send_request (http_t hd, const char *auth,
|
||||
int rc;
|
||||
|
||||
xfree (hd->session->servername);
|
||||
hd->session->servername = xtrystrdup (server);
|
||||
hd->session->servername = xtrystrdup (httphost? httphost : server);
|
||||
if (!hd->session->servername)
|
||||
{
|
||||
err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
|
||||
@ -1549,11 +1552,13 @@ send_request (http_t hd, const char *auth,
|
||||
if (http_proxy && *http_proxy)
|
||||
{
|
||||
request = es_asprintf
|
||||
("%s http://%s:%hu%s%s HTTP/1.0\r\n%s%s",
|
||||
("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s",
|
||||
hd->req_type == HTTP_REQ_GET ? "GET" :
|
||||
hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
|
||||
hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
|
||||
server, port, *p == '/' ? "" : "/", p,
|
||||
hd->uri->use_tls? "https" : "http",
|
||||
httphost? httphost : server,
|
||||
port, *p == '/' ? "" : "/", p,
|
||||
authstr ? authstr : "",
|
||||
proxy_authstr ? proxy_authstr : "");
|
||||
}
|
||||
@ -1571,7 +1576,9 @@ send_request (http_t hd, const char *auth,
|
||||
hd->req_type == HTTP_REQ_GET ? "GET" :
|
||||
hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
|
||||
hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
|
||||
*p == '/' ? "" : "/", p, server, portstr,
|
||||
*p == '/' ? "" : "/", p,
|
||||
httphost? httphost : server,
|
||||
portstr,
|
||||
authstr? authstr:"");
|
||||
}
|
||||
xfree (p);
|
||||
@ -2442,6 +2449,7 @@ http_verify_server_credentials (http_session_t sess)
|
||||
const gnutls_datum_t *certlist;
|
||||
unsigned int certlistlen;
|
||||
gnutls_x509_crt_t cert;
|
||||
gpg_error_t err = 0;
|
||||
|
||||
sess->verify.done = 1;
|
||||
sess->verify.status = 0;
|
||||
@ -2458,27 +2466,35 @@ http_verify_server_credentials (http_session_t sess)
|
||||
if (rc)
|
||||
{
|
||||
log_error ("%s: %s\n", errprefix, gnutls_strerror (rc));
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
if (!err)
|
||||
err = gpg_error (GPG_ERR_GENERAL);
|
||||
}
|
||||
if (status)
|
||||
else if (status)
|
||||
{
|
||||
log_error ("%s: status=0x%04x\n", errprefix, status);
|
||||
sess->verify.status = status;
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
if (!err)
|
||||
err = gpg_error (GPG_ERR_GENERAL);
|
||||
}
|
||||
|
||||
hostname = sess->servername;
|
||||
if (!hostname || !strchr (hostname, '.'))
|
||||
{
|
||||
log_error ("%s: %s\n", errprefix, "hostname missing");
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
if (!err)
|
||||
err = gpg_error (GPG_ERR_GENERAL);
|
||||
}
|
||||
|
||||
certlist = gnutls_certificate_get_peers (sess->tls_session, &certlistlen);
|
||||
if (!certlistlen)
|
||||
{
|
||||
log_error ("%s: %s\n", errprefix, "server did not send a certificate");
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
if (!err)
|
||||
err = gpg_error (GPG_ERR_GENERAL);
|
||||
|
||||
/* Need to stop here. */
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* log_debug ("Server sent %u certs\n", certlistlen); */
|
||||
@ -2502,7 +2518,10 @@ http_verify_server_credentials (http_session_t sess)
|
||||
rc = gnutls_x509_crt_init (&cert);
|
||||
if (rc < 0)
|
||||
{
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
if (!err)
|
||||
err = gpg_error (GPG_ERR_GENERAL);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
rc = gnutls_x509_crt_import (cert, &certlist[0], GNUTLS_X509_FMT_DER);
|
||||
@ -2510,20 +2529,22 @@ http_verify_server_credentials (http_session_t sess)
|
||||
{
|
||||
log_error ("%s: %s: %s\n", errprefix, "error importing certificate",
|
||||
gnutls_strerror (rc));
|
||||
gnutls_x509_crt_deinit (cert);
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
if (!err)
|
||||
err = gpg_error (GPG_ERR_GENERAL);
|
||||
}
|
||||
|
||||
if (!gnutls_x509_crt_check_hostname (cert, hostname))
|
||||
{
|
||||
log_error ("%s: %s\n", errprefix, "hostname does not match");
|
||||
gnutls_x509_crt_deinit (cert);
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
log_info ("(expected '%s')\n", hostname);
|
||||
if (!err)
|
||||
err = gpg_error (GPG_ERR_GENERAL);
|
||||
}
|
||||
|
||||
gnutls_x509_crt_deinit (cert);
|
||||
if (!err)
|
||||
sess->verify.rc = 0;
|
||||
return 0; /* Verification succeeded. */
|
||||
return err;
|
||||
#else /*!HTTP_USE_GNUTLS*/
|
||||
(void)sess;
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
|
@ -110,6 +110,7 @@ gpg_error_t http_raw_connect (http_t *r_hd,
|
||||
|
||||
gpg_error_t http_open (http_t *r_hd, http_req_t reqtype,
|
||||
const char *url,
|
||||
const char *httphost,
|
||||
const char *auth,
|
||||
unsigned int flags,
|
||||
const char *proxy,
|
||||
|
@ -765,6 +765,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
|
||||
err = http_open (&http,
|
||||
post_cb? HTTP_REQ_POST : HTTP_REQ_GET,
|
||||
request,
|
||||
NULL,
|
||||
/* fixme: AUTH */ NULL,
|
||||
httpflags,
|
||||
/* fixme: proxy*/ NULL,
|
||||
|
@ -68,6 +68,7 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
|
||||
err = http_open (&http,
|
||||
HTTP_REQ_GET,
|
||||
url,
|
||||
/* httphost */ NULL,
|
||||
/* fixme: AUTH */ NULL,
|
||||
0,
|
||||
/* fixme: proxy*/ NULL,
|
||||
|
@ -165,7 +165,7 @@ do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md,
|
||||
}
|
||||
|
||||
once_more:
|
||||
err = http_open (&http, HTTP_REQ_POST, url, NULL,
|
||||
err = http_open (&http, HTTP_REQ_POST, url, NULL, NULL,
|
||||
(opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0),
|
||||
opt.http_proxy, NULL, NULL, NULL);
|
||||
if (err)
|
||||
|
@ -298,7 +298,7 @@ skip_options (char *line)
|
||||
}
|
||||
|
||||
|
||||
/* Return an error if the assuan context does not belong to teh owner
|
||||
/* Return an error if the assuan context does not belong to the owner
|
||||
of the process or to root. On error FAILTEXT is set as Assuan
|
||||
error string. */
|
||||
static gpg_error_t
|
||||
|
@ -198,7 +198,7 @@ curl_easy_perform(CURL *curl)
|
||||
|
||||
if(curl->flags.post)
|
||||
{
|
||||
rc = http_open (&curl->hd, HTTP_REQ_POST, curl->url, curl->auth,
|
||||
rc = http_open (&curl->hd, HTTP_REQ_POST, curl->url, NULL, curl->auth,
|
||||
0, proxy, NULL, curl->srvtag,
|
||||
curl->headers?curl->headers->list:NULL);
|
||||
if (!rc)
|
||||
@ -222,7 +222,7 @@ curl_easy_perform(CURL *curl)
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = http_open (&curl->hd, HTTP_REQ_GET, curl->url, curl->auth,
|
||||
rc = http_open (&curl->hd, HTTP_REQ_GET, curl->url, NULL, curl->auth,
|
||||
0, proxy, NULL, curl->srvtag,
|
||||
curl->headers?curl->headers->list:NULL);
|
||||
if (!rc)
|
||||
|
Loading…
x
Reference in New Issue
Block a user