Commit a9a47781 authored by David Woodhouse's avatar David Woodhouse

Stash peer certificate before fetching HTTP response

If the server closes the connection by giving an HTTP 1.0-style response,
then the SSL connection will be gone by the time the GUI auth dialog calls
openconnect_get_peer_cert(). So remember it in order to give it out later.
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 628d2c88
......@@ -693,6 +693,12 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
if (result < 0)
return result;
/* Remember the peer's SSL certificate; it may disconnect during
the response and then we wouldn't be able to find it */
if (vpninfo->peer_cert)
X509_free(vpninfo->peer_cert);
vpninfo->peer_cert = SSL_get_peer_certificate(vpninfo->https_ssl);
buflen = process_http_response(vpninfo, &result, NULL, &form_buf);
if (buflen < 0) {
/* We'll already have complained about whatever offended us */
......
......@@ -99,6 +99,8 @@ void openconnect_vpninfo_free (struct openconnect_info *vpninfo)
if (vpninfo->cert != vpninfo->sslkey)
free((void *)vpninfo->sslkey);
free((void *)vpninfo->cert);
if (vpninfo->peer_cert)
X509_free(vpninfo->peer_cert);
/* No need to free deflate streams; they weren't initialised */
free(vpninfo);
}
......@@ -154,7 +156,7 @@ void openconnect_set_client_cert (struct openconnect_info *vpninfo, char *cert,
struct x509_st *openconnect_get_peer_cert (struct openconnect_info *vpninfo)
{
return SSL_get_peer_certificate(vpninfo->https_ssl);
return vpninfo->peer_cert;
}
int openconnect_get_port (struct openconnect_info *vpninfo)
......
......@@ -135,6 +135,8 @@ struct openconnect_info {
int uid_csd_given;
int no_http_keepalive;
X509 *peer_cert;
char *cookie; /* Pointer to within cookies list */
struct vpn_option *cookies;
struct vpn_option *cstp_options;
......
......@@ -146,7 +146,13 @@ void openconnect_set_xmlsha1 (struct openconnect_info *, char *, int size);
void openconnect_set_cafile (struct openconnect_info *, char *);
void openconnect_setup_csd (struct openconnect_info *, uid_t, int silent, char *wrapper);
void openconnect_set_client_cert (struct openconnect_info *, char *cert, char *sslkey);
/* This is *not* yours and must not be destroyed with X509_free(). It
* will be valid when a cookie has been obtained successfully, and will
* be valid until the connection is destroyed or another attempt it made
* to use it. */
struct x509_st *openconnect_get_peer_cert (struct openconnect_info *);
int openconnect_get_port (struct openconnect_info *);
char *openconnect_get_cookie (struct openconnect_info *);
void openconnect_clear_cookie (struct openconnect_info *);
......
......@@ -1293,6 +1293,10 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
void openconnect_close_https(struct openconnect_info *vpninfo)
{
if (vpninfo->peer_cert) {
X509_free(vpninfo->peer_cert);
vpninfo->peer_cert = NULL;
}
SSL_free(vpninfo->https_ssl);
vpninfo->https_ssl = NULL;
close(vpninfo->ssl_fd);
......
......@@ -17,7 +17,7 @@
<ul>
<li><b>OpenConnect HEAD</b>
<ul>
<li><i>No changelog entries yet</i></li>
<li>Cope with non-keepalive HTTP response on authentication success.</li>
</ul><br/>
</li>
<li><b><a href="ftp://ftp.infradead.org/pub/openconnect/openconnect-3.19.tar.gz">OpenConnect v3.19</a></b>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment