diff options
author | Justus Winter <[email protected]> | 2015-11-18 14:06:48 +0000 |
---|---|---|
committer | Justus Winter <[email protected]> | 2015-11-18 14:06:48 +0000 |
commit | eb54fca4bf3ef8e0cd50b01df5b40e0d6d318d7e (patch) | |
tree | 18917c92bd1bdb4f8c8180bca75f4eaee2605fae | |
parent | tools: Fix option parsing for gpg-zip. (diff) | |
download | gnupg-fix-1950.tar.gz gnupg-fix-1950.zip |
dirmngr: Gracefully handle premature termination of TLS streams.fix-1950
* dirmngr/http.c (close_tls_session): New function.
(session_unref): Use the new function to close the TLS stream.
(cookie_read): If the stream terminated prematurely, close it and
return a short read.
--
With this patch, I was able to update all the keys in the Debian
keyring over hkps.
Signed-off-by: Justus Winter <[email protected]>
GnuPG-bug-id: 1950
-rw-r--r-- | dirmngr/http.c | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/dirmngr/http.c b/dirmngr/http.c index e33a59436..60dc45f4d 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -511,6 +511,27 @@ http_register_tls_ca (const char *fname) } +#ifdef USE_TLS +/* Free the TLS session associated with SESS, if any. */ +static void +close_tls_session (http_session_t sess) +{ + if (sess->tls_session) + { +# ifdef HTTP_USE_GNUTLS + my_socket_t sock = gnutls_transport_get_ptr (sess->tls_session); + my_socket_unref (sock, NULL, NULL); + gnutls_deinit (sess->tls_session); + if (sess->certcred) + gnutls_certificate_free_credentials (sess->certcred); +# endif /*HTTP_USE_GNUTLS*/ + xfree (sess->servername); + sess->tls_session = NULL; + } +} +#endif /*USE_TLS*/ + + /* Release a session. Take care not to release it while it is being used by a http context object. */ static void @@ -527,17 +548,7 @@ session_unref (int lnr, http_session_t sess) return; #ifdef USE_TLS -# ifdef HTTP_USE_GNUTLS - if (sess->tls_session) - { - my_socket_t sock = gnutls_transport_get_ptr (sess->tls_session); - my_socket_unref (sock, NULL, NULL); - gnutls_deinit (sess->tls_session); - } - if (sess->certcred) - gnutls_certificate_free_credentials (sess->certcred); -# endif /*HTTP_USE_GNUTLS*/ - xfree (sess->servername); + close_tls_session (sess); #endif /*USE_TLS*/ xfree (sess); @@ -2447,6 +2458,13 @@ cookie_read (void *cookie, void *buffer, size_t size) } if (nread == GNUTLS_E_REHANDSHAKE) goto again; /* A client is allowed to just ignore this request. */ + if (nread == GNUTLS_E_PREMATURE_TERMINATION) + { + /* The server terminated the connection. Close the TLS + session, and indicate EOF using a short read. */ + close_tls_session (c->session); + return 0; + } log_info ("TLS network read failed: %s\n", gnutls_strerror (nread)); gpg_err_set_errno (EIO); return -1; |