Skip to content

Commit

Permalink
GnuTLS: Cache token PIN
Browse files Browse the repository at this point in the history
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: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Jun 10, 2012
1 parent 5c46ae2 commit 929b7da
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 3 deletions.
45 changes: 42 additions & 3 deletions gnutls.c
Expand Up @@ -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
}
Expand Down Expand Up @@ -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;
Expand All @@ -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");
Expand All @@ -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;
}
Expand Down
7 changes: 7 additions & 0 deletions openconnect-internal.h
Expand Up @@ -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

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 929b7da

Please sign in to comment.