Commit 929b7da8 authored by David Woodhouse's avatar David Woodhouse

GnuTLS: Cache token PIN

Otherwise we get prompted for it about four times in the course of a single
connection, which is going to make users unhappy.

GnuTLS has been fixed not to do it on decent tokens that can have more than
one active session, but on the crap tokens it's still needed.
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 5c46ae20
......@@ -1261,6 +1261,16 @@ void openconnect_close_https(struct openconnect_info *vpninfo, int final)
sprintf(pin_source, "openconnect:%p", vpninfo);
p11_kit_pin_unregister_callback(pin_source, pin_callback, vpninfo);
while (vpninfo->pin_cache) {
struct pin_cache *cache = vpninfo->pin_cache;
free(cache->token);
memset(cache->pin, 0x5a, strlen(cache->pin));
free(cache->pin);
vpninfo->pin_cache = cache->next;
free(cache);
}
}
#endif
}
......@@ -1316,15 +1326,43 @@ static P11KitPin *pin_callback(const char *pin_source, P11KitUri *pin_uri,
void *_vpninfo)
{
struct openconnect_info *vpninfo = _vpninfo;
struct pin_cache **cache = &vpninfo->pin_cache;
struct oc_auth_form f;
struct oc_form_opt o;
char message[1024];
char *uri;
P11KitPin *pin;
int ret;
if (!vpninfo || !vpninfo->process_auth_form)
return NULL;
if (p11_kit_uri_format(pin_uri, P11_KIT_URI_FOR_TOKEN, &uri))
return NULL;
while (*cache) {
if (!strcmp(uri, (*cache)->token)) {
free(uri);
uri = NULL;
if ((*cache)->pin) {
if ((flags & P11_KIT_PIN_FLAGS_RETRY) != P11_KIT_PIN_FLAGS_RETRY)
return p11_kit_pin_new_for_string((*cache)->pin);
memset((*cache)->pin, 0x5a, strlen((*cache)->pin));
free((*cache)->pin);
(*cache)->pin = NULL;
}
break;
}
}
if (!*cache) {
*cache = calloc(1, sizeof(struct pin_cache));
if (!*cache) {
free(uri);
return NULL;
}
(*cache)->token = uri;
}
memset(&f, 0, sizeof(f));
f.auth_id = (char *)"pkcs11_pin";
f.opts = &o;
......@@ -1334,9 +1372,10 @@ static P11KitPin *pin_callback(const char *pin_source, P11KitUri *pin_uri,
f.message = message;
/*
* p11-kit flags are *odd*.
* In p11-kit <= 0.12, these flags are *odd*.
* RETRY is 0xa, FINAL_TRY is 0x14 and MANY_TRIES is 0x28.
* So don't treat it like a sane bitmask.
* So don't treat it like a sane bitmask. Fixed in
* http://cgit.freedesktop.org/p11-glue/p11-kit/commit/?id=59774b11
*/
if ((flags & P11_KIT_PIN_FLAGS_RETRY) == P11_KIT_PIN_FLAGS_RETRY)
f.error = _("Wrong PIN");
......@@ -1357,7 +1396,7 @@ static P11KitPin *pin_callback(const char *pin_source, P11KitUri *pin_uri,
return NULL;
pin = p11_kit_pin_new_for_string(o.value);
free(o.value);
(*cache)->pin = o.value;
return pin;
}
......
......@@ -95,6 +95,12 @@ struct split_include {
struct split_include *next;
};
struct pin_cache {
struct pin_cache *next;
char *token;
char *pin;
};
#define RECONNECT_INTERVAL_MIN 10
#define RECONNECT_INTERVAL_MAX 100
......@@ -159,6 +165,7 @@ struct openconnect_info {
#elif defined(OPENCONNECT_GNUTLS)
gnutls_session_t https_sess;
gnutls_certificate_credentials_t https_cred;
struct pin_cache *pin_cache;
#endif
struct keepalive_info ssl_times;
int owe_ssl_dpd_response;
......
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