Commit b682fb79 authored by David Woodhouse's avatar David Woodhouse

Don't unregister p11-kit PIN callback until vpninfo is finished with

Unregistering in openconnect_close_https() meant that when we reconnect to
the server, we lose the PIN callback. And then when we connect again, if
GnuTLS is asking us for the PIN on every attempt to touch the key, we fail
because there's no PIN handler.

So add a 'final' flag to openconnect_close_https(). Use this to clean up
library.c::openconnect_close_https() a little, too.
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 3249ec9a
......@@ -230,7 +230,7 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
_("Error fetching HTTPS response\n"));
if (!retried) {
retried = 1;
openconnect_close_https(vpninfo);
openconnect_close_https(vpninfo, 0);
if (openconnect_open_https(vpninfo)) {
vpn_progress(vpninfo, PRG_ERR,
......@@ -526,7 +526,7 @@ int cstp_reconnect(struct openconnect_info *vpninfo)
int timeout;
int interval;
openconnect_close_https(vpninfo);
openconnect_close_https(vpninfo, 0);
/* Requeue the original packet that was deflated */
if (vpninfo->current_ssl_pkt == vpninfo->deflate_pkt) {
......
......@@ -1056,17 +1056,8 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
return 0;
}
void openconnect_close_https(struct openconnect_info *vpninfo)
void openconnect_close_https(struct openconnect_info *vpninfo, int final)
{
#ifdef HAVE_P11KIT
if (!strncmp(vpninfo->cert, "pkcs11:", 7)) {
char pin_source[40];
sprintf(pin_source, "openconnect:%p", vpninfo);
p11_kit_pin_unregister_callback(pin_source, pin_callback, vpninfo);
}
#endif
if (vpninfo->peer_cert) {
gnutls_x509_crt_deinit(vpninfo->peer_cert);
vpninfo->peer_cert = NULL;
......@@ -1082,6 +1073,18 @@ void openconnect_close_https(struct openconnect_info *vpninfo)
FD_CLR(vpninfo->ssl_fd, &vpninfo->select_efds);
vpninfo->ssl_fd = -1;
}
if (final && vpninfo->https_cred) {
gnutls_certificate_free_credentials(vpninfo->https_cred);
vpninfo->https_cred = NULL;
#ifdef HAVE_P11KIT
if (!strncmp(vpninfo->cert, "pkcs11:", 7)) {
char pin_source[40];
sprintf(pin_source, "openconnect:%p", vpninfo);
p11_kit_pin_unregister_callback(pin_source, pin_callback, vpninfo);
}
#endif
}
}
void openconnect_init_ssl(void)
......
......@@ -335,7 +335,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result,
}
if (closeconn || vpninfo->no_http_keepalive)
openconnect_close_https(vpninfo);
openconnect_close_https(vpninfo, 0);
if (body)
body[done] = 0;
......@@ -728,7 +728,7 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
/* Kill the existing connection, and a new one will happen */
free(vpninfo->peer_addr);
vpninfo->peer_addr = NULL;
openconnect_close_https(vpninfo);
openconnect_close_https(vpninfo, 0);
for (opt = vpninfo->cookies; opt; opt = next) {
next = opt->next;
......
......@@ -171,23 +171,11 @@ void openconnect_clear_cookie (struct openconnect_info *vpninfo)
void openconnect_reset_ssl (struct openconnect_info *vpninfo)
{
openconnect_close_https(vpninfo);
openconnect_close_https(vpninfo, 1);
if (vpninfo->peer_addr) {
free(vpninfo->peer_addr);
vpninfo->peer_addr = NULL;
}
#if defined (OPENCONNECT_OPENSSL)
if (vpninfo->https_ctx) {
SSL_CTX_free(vpninfo->https_ctx);
vpninfo->https_ctx = NULL;
}
#elif defined (OPENCONNECT_GNUTLS)
if (vpninfo->https_cred) {
gnutls_certificate_free_credentials(vpninfo->https_cred);
vpninfo->https_cred = NULL;
}
#endif
}
int openconnect_parse_url (struct openconnect_info *vpninfo, char *url)
......
......@@ -321,7 +321,7 @@ int openconnect_SSL_gets(struct openconnect_info *vpninfo, char *buf, size_t len
int openconnect_SSL_write(struct openconnect_info *vpninfo, char *buf, size_t len);
int openconnect_SSL_read(struct openconnect_info *vpninfo, char *buf, size_t len);
int openconnect_open_https(struct openconnect_info *vpninfo);
void openconnect_close_https(struct openconnect_info *vpninfo);
void openconnect_close_https(struct openconnect_info *vpninfo, int final);
int get_cert_md5_fingerprint(struct openconnect_info *vpninfo, OPENCONNECT_X509 *cert,
char *buf);
/* This one is actually OpenSSL-specific */
......
......@@ -1283,7 +1283,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
return 0;
}
void openconnect_close_https(struct openconnect_info *vpninfo)
void openconnect_close_https(struct openconnect_info *vpninfo, int final)
{
if (vpninfo->peer_cert) {
X509_free(vpninfo->peer_cert);
......@@ -1300,6 +1300,10 @@ void openconnect_close_https(struct openconnect_info *vpninfo)
FD_CLR(vpninfo->ssl_fd, &vpninfo->select_efds);
vpninfo->ssl_fd = -1;
}
if (final && vpninfo->https_ctx) {
SSL_CTX_free(vpninfo->https_ctx);
vpninfo->https_ctx = NULL;
}
}
void openconnect_init_ssl(void)
......
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