[PATCH] dirmngr: fix handling of HTTP redirections

Damien Goutte-Gattat dgouttegattat at incenp.org
Sun May 29 16:55:42 CEST 2016

> So it does look like a bug in the handling of HTTP redirections.

I dug a little further, and I came up with a possible fix.

When following a redirection, the failure point is the call to
gnutls_handshake in dirmngr/http.c (send_request). If I
understood correctly, that call is unexpected by GnuTLS at that
point, because the TLS connection that was established to send
the initial request is still opened.

The patch below provides a crude fix: it forcibly closes the
session and create a whole new session object before attempting
to follow the redirection.

This works, but at the expense of destroying the first session
only to re-create a new one immediately. We could probably do
something more clever.

In particular, we could check whether the redirect URL points
toward the same host as the original URL--in that case, we should
be able to reuse the initial connection without attempting a
second handshake.

-- >8 --
Subject: [PATCH] dirmngr: fix handling of HTTP redirections

* dirmngr/ks-engine-http.c (ks_http_fetch): Reinitialize HTTP session
when following a HTTP redirection.

Signed-off-by: Damien Goutte-Gattat <dgouttegattat at incenp.org>
 dirmngr/ks-engine-http.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c
index 00d0c4b..193b808 100644
--- a/dirmngr/ks-engine-http.c
+++ b/dirmngr/ks-engine-http.c
@@ -73,6 +73,7 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
   estream_t fp = NULL;
   char *request_buffer = NULL;
   /* Note that we only use the system provided certificates with the
    * fetch command.  */
   err = http_session_new (&session, NULL, NULL, HTTP_FLAG_TRUST_SYS);
@@ -81,7 +82,6 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
   http_session_set_log_cb (session, cert_log_cb);
   *r_fp = NULL;
- once_more:
   err = http_open (&http,
@@ -146,6 +146,7 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
                 url = request_buffer;
                 http_close (http, 0);
                 http = NULL;
+                http_session_release (session);
                 goto once_more;
             err = gpg_error_from_syserror ();

More information about the Gnupg-devel mailing list