diff --git a/agent/agent.h b/agent/agent.h index 687635dc7..0d5cf4f1c 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -451,6 +451,7 @@ int agent_clear_passphrase (ctrl_t ctrl, /*-- cache.c --*/ void initialize_module_cache (void); void deinitialize_module_cache (void); +void agent_cache_housekeeping (void); void agent_flush_cache (void); int agent_put_cache (const char *key, cache_mode_t cache_mode, const char *data, int ttl); diff --git a/agent/cache.c b/agent/cache.c index 80d5f8d1e..ed5c97cd2 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -258,6 +258,26 @@ housekeeping (void) } +void +agent_cache_housekeeping (void) +{ + int res; + + if (DBG_CACHE) + log_debug ("agent_cache_housekeeping\n"); + + res = npth_mutex_lock (&cache_lock); + if (res) + log_fatal ("failed to acquire cache mutex: %s\n", strerror (res)); + + housekeeping (); + + res = npth_mutex_unlock (&cache_lock); + if (res) + log_fatal ("failed to release cache mutex: %s\n", strerror (res)); +} + + void agent_flush_cache (void) { diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index a1964ece8..bd9a471e8 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -2398,6 +2398,9 @@ handle_tick (void) } #endif + /* Need to check for expired cache entries. */ + agent_cache_housekeeping (); + /* Check whether the homedir is still available. */ if (!shutdown_pending && (!have_homedir_inotify || !reliable_homedir_inotify) diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index 4a0b08f4f..a9bb93666 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -1353,6 +1353,8 @@ handle_send_request_error (ctrl_t ctrl, gpg_error_t err, const char *request, case GPG_ERR_UNKNOWN_HOST: case GPG_ERR_NETWORK: case GPG_ERR_EIO: /* Sometimes used by estream cookie functions. */ + case GPG_ERR_EADDRNOTAVAIL: /* e.g. when IPv6 is disabled */ + case GPG_ERR_EAFNOSUPPORT: /* e.g. when IPv6 is not compiled in */ if (mark_host_dead (request) && *tries_left) retry = 1; break; diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 3e8bd894d..4781bbdca 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -403,7 +403,10 @@ control this behavior but this command line option takes precedence. Set the time a cache entry is valid to @var{n} seconds. The default is 600 seconds. Each time a cache entry is accessed, the entry's timer is reset. To set an entry's maximum lifetime, use -@command{max-cache-ttl}. +@command{max-cache-ttl}. Note that a cached passphrase may not +evicted immediately from memory if no client requests a cache +operation. This is due to an internal housekeeping function which is +only run every few seconds. @item --default-cache-ttl-ssh @var{n} @opindex default-cache-ttl diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 37a535366..93ae56efe 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -256,7 +256,7 @@ fingerprints or keygrips. @item --export-secret-key-p12 @var{key-id} @opindex export-secret-key-p12 -Export the private key and the certificate identified by @var{key-id} in +Export the private key and the certificate identified by @var{key-id} using the PKCS#12 format. When used with the @code{--armor} option a few informational lines are prepended to the output. Note, that the PKCS#12 format is not very secure and proper transport security should be used diff --git a/g10/call-agent.c b/g10/call-agent.c index 61d06c663..b1f589bbc 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -381,10 +381,11 @@ unhexify_fpr (const char *hexstr, unsigned char *fpr) for (s=hexstr, n=0; hexdigitp (s); s++, n++) ; - if (*s || (n != 40)) + if ((*s && *s != ' ') || (n != 40)) return 0; /* no fingerprint (invalid or wrong length). */ - for (s=hexstr, n=0; *s; s += 2, n++) + for (s=hexstr, n=0; *s && n < 20; s += 2, n++) fpr[n] = xtoi_2 (s); + return 1; /* okay */ } @@ -625,6 +626,24 @@ learn_status_cb (void *opaque, const char *line) else if (no == 3) parm->fpr3time = strtoul (line, NULL, 10); } + else if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen)) + { + const char *hexgrp = line; + int no; + + while (*line && !spacep (line)) + line++; + while (spacep (line)) + line++; + if (strncmp (line, "OPENPGP.", 8)) + ; + else if ((no = atoi (line+8)) == 1) + unhexify_fpr (hexgrp, parm->grp1); + else if (no == 2) + unhexify_fpr (hexgrp, parm->grp2); + else if (no == 3) + unhexify_fpr (hexgrp, parm->grp3); + } else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen)) { int no = atoi (line); diff --git a/g10/call-agent.h b/g10/call-agent.h index f45b64d90..53775c5c8 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -47,6 +47,9 @@ struct agent_card_info_s u32 fpr1time; u32 fpr2time; u32 fpr3time; + char grp1[20]; /* The keygrip for OPENPGP.1 */ + char grp2[20]; /* The keygrip for OPENPGP.2 */ + char grp3[20]; /* The keygrip for OPENPGP.3 */ unsigned long sig_counter; int chv1_cached; /* True if a PIN is not required for each signing. Note that the gpg-agent might cache diff --git a/g10/card-util.c b/g10/card-util.c index 4c1ab03a1..f8a1bb831 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -263,6 +263,21 @@ print_sha1_fpr_colon (estream_t fp, const unsigned char *fpr) } +static void +print_keygrip (estream_t fp, const unsigned char *grp) +{ + int i; + + if (opt.with_keygrip) + { + tty_fprintf (fp, " keygrip ....: "); + for (i=0; i < 20 ; i++, grp++) + es_fprintf (fp, "%02X", *grp); + tty_fprintf (fp, "\n"); + } +} + + static void print_name (estream_t fp, const char *text, const char *name) { @@ -517,6 +532,11 @@ current_card_status (ctrl_t ctrl, estream_t fp, es_fprintf (fp, "fprtime:%lu:%lu:%lu:\n", (unsigned long)info.fpr1time, (unsigned long)info.fpr2time, (unsigned long)info.fpr3time); + es_fputs ("grp:", fp); + print_sha1_fpr_colon (fp, info.grp1); + print_sha1_fpr_colon (fp, info.grp2); + print_sha1_fpr_colon (fp, info.grp3); + es_putc ('\n', fp); } else { @@ -593,18 +613,27 @@ current_card_status (ctrl_t ctrl, estream_t fp, tty_fprintf (fp, "Signature key ....:"); print_sha1_fpr (fp, info.fpr1valid? info.fpr1:NULL); if (info.fpr1valid && info.fpr1time) - tty_fprintf (fp, " created ....: %s\n", - isotimestamp (info.fpr1time)); + { + tty_fprintf (fp, " created ....: %s\n", + isotimestamp (info.fpr1time)); + print_keygrip (fp, info.grp1); + } tty_fprintf (fp, "Encryption key....:"); print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL); if (info.fpr2valid && info.fpr2time) - tty_fprintf (fp, " created ....: %s\n", - isotimestamp (info.fpr2time)); + { + tty_fprintf (fp, " created ....: %s\n", + isotimestamp (info.fpr2time)); + print_keygrip (fp, info.grp2); + } tty_fprintf (fp, "Authentication key:"); print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL); if (info.fpr3valid && info.fpr3time) - tty_fprintf (fp, " created ....: %s\n", - isotimestamp (info.fpr3time)); + { + tty_fprintf (fp, " created ....: %s\n", + isotimestamp (info.fpr3time)); + print_keygrip (fp, info.grp2); + } tty_fprintf (fp, "General key info..: "); thefpr = (info.fpr1valid? info.fpr1 : info.fpr2valid? info.fpr2 : diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 099f43952..924f90785 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -2076,7 +2076,9 @@ get_config_filename (gc_component_t component, gc_backend_t backend) #elif defined(HAVE_DOSISH_SYSTEM) if (!(filename[0] && filename[1] == ':' - && (filename[2] == '/' || filename[2] == '\\'))) + && (filename[2] == '/' || filename[2] == '\\')) /* x:\ or x:/ */ + && !((filename[0] == '\\' && filename[1] == '\\') + || (filename[0] == '/' && filename[1] == '/'))) /* \\server */ #else if (filename[0] != '/') #endif