mirror of
git://git.gnupg.org/gnupg.git
synced 2024-11-10 21:38:50 +01:00
agent: First changes to support a PIN cache for scdaemon.
* agent/agent.h (CACHE_MODE_PIN): New. * agent/cache.c (housekeeping): Special handling of new new mode. (agent_flush_cache): Ditto. Add arg 'pincache_only' and change caller. (agent_put_cache): Support new mode. (agent_get_cache): Ditto. * agent/call-scd.c (wait_child_thread): Flush the entire PIN cache. (start_scd): Ditto. (agent_card_killscd): Ditto. (handle_pincache_put): New. Uses a dummy encryption key for now. (pincache_put_cb): New. (inq_needpin): Prepare for PINCACHE_GET inquiry. (learn_status_cb): Handle the PINENTRY_PUT status line. (get_serialno_cb): Ditto (agent_card_pksign): Ditto. (padding_info_cb): Ditto. (agent_card_readcert): Ditto. (agent_card_readkey): Ditto. (agent_card_writekey): Ditto. (card_getattr_cb): Ditto. (card_cardlist_cb): Ditto. (card_keyinfo_cb): Ditto. (pass_status_thru): Ditto. -- Take care: This is not finished. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
41a8824436
commit
d5c00354bb
@ -322,6 +322,7 @@ typedef enum
|
|||||||
CACHE_MODE_USER, /* GET_PASSPHRASE related cache. */
|
CACHE_MODE_USER, /* GET_PASSPHRASE related cache. */
|
||||||
CACHE_MODE_SSH, /* SSH related cache. */
|
CACHE_MODE_SSH, /* SSH related cache. */
|
||||||
CACHE_MODE_NONCE, /* This is a non-predictable nonce. */
|
CACHE_MODE_NONCE, /* This is a non-predictable nonce. */
|
||||||
|
CACHE_MODE_PIN, /* PINs stored/retrieved by scdaemon. */
|
||||||
CACHE_MODE_DATA /* Arbitrary data. */
|
CACHE_MODE_DATA /* Arbitrary data. */
|
||||||
}
|
}
|
||||||
cache_mode_t;
|
cache_mode_t;
|
||||||
@ -479,7 +480,7 @@ int agent_clear_passphrase (ctrl_t ctrl,
|
|||||||
void initialize_module_cache (void);
|
void initialize_module_cache (void);
|
||||||
void deinitialize_module_cache (void);
|
void deinitialize_module_cache (void);
|
||||||
void agent_cache_housekeeping (void);
|
void agent_cache_housekeeping (void);
|
||||||
void agent_flush_cache (void);
|
void agent_flush_cache (int pincache_only);
|
||||||
int agent_put_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode,
|
int agent_put_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode,
|
||||||
const char *data, int ttl);
|
const char *data, int ttl);
|
||||||
char *agent_get_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode);
|
char *agent_get_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode);
|
||||||
|
@ -204,7 +204,9 @@ housekeeping (void)
|
|||||||
/* First expire the actual data */
|
/* First expire the actual data */
|
||||||
for (r=thecache; r; r = r->next)
|
for (r=thecache; r; r = r->next)
|
||||||
{
|
{
|
||||||
if (r->pw && r->ttl >= 0 && r->accessed + r->ttl < current)
|
if (r->cache_mode == CACHE_MODE_PIN)
|
||||||
|
; /* Don't let it expire - scdaemon explictly flushes them. */
|
||||||
|
else if (r->pw && r->ttl >= 0 && r->accessed + r->ttl < current)
|
||||||
{
|
{
|
||||||
if (DBG_CACHE)
|
if (DBG_CACHE)
|
||||||
log_debug (" expired '%s'.%d (%ds after last access)\n",
|
log_debug (" expired '%s'.%d (%ds after last access)\n",
|
||||||
@ -226,6 +228,7 @@ housekeeping (void)
|
|||||||
switch (r->cache_mode)
|
switch (r->cache_mode)
|
||||||
{
|
{
|
||||||
case CACHE_MODE_DATA:
|
case CACHE_MODE_DATA:
|
||||||
|
case CACHE_MODE_PIN:
|
||||||
continue; /* No MAX TTL here. */
|
continue; /* No MAX TTL here. */
|
||||||
case CACHE_MODE_SSH: maxttl = opt.max_cache_ttl_ssh; break;
|
case CACHE_MODE_SSH: maxttl = opt.max_cache_ttl_ssh; break;
|
||||||
default: maxttl = opt.max_cache_ttl; break;
|
default: maxttl = opt.max_cache_ttl; break;
|
||||||
@ -288,13 +291,13 @@ agent_cache_housekeeping (void)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
agent_flush_cache (void)
|
agent_flush_cache (int pincache_only)
|
||||||
{
|
{
|
||||||
ITEM r;
|
ITEM r;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (DBG_CACHE)
|
if (DBG_CACHE)
|
||||||
log_debug ("agent_flush_cache\n");
|
log_debug ("agent_flush_cache%s\n", pincache_only?" (pincache only)":"");
|
||||||
|
|
||||||
res = npth_mutex_lock (&cache_lock);
|
res = npth_mutex_lock (&cache_lock);
|
||||||
if (res)
|
if (res)
|
||||||
@ -302,6 +305,8 @@ agent_flush_cache (void)
|
|||||||
|
|
||||||
for (r=thecache; r; r = r->next)
|
for (r=thecache; r; r = r->next)
|
||||||
{
|
{
|
||||||
|
if (pincache_only && r->cache_mode != CACHE_MODE_PIN)
|
||||||
|
continue;
|
||||||
if (r->pw)
|
if (r->pw)
|
||||||
{
|
{
|
||||||
if (DBG_CACHE)
|
if (DBG_CACHE)
|
||||||
@ -361,6 +366,7 @@ agent_put_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode,
|
|||||||
{
|
{
|
||||||
case CACHE_MODE_SSH: ttl = opt.def_cache_ttl_ssh; break;
|
case CACHE_MODE_SSH: ttl = opt.def_cache_ttl_ssh; break;
|
||||||
case CACHE_MODE_DATA: ttl = DEF_CACHE_TTL_DATA; break;
|
case CACHE_MODE_DATA: ttl = DEF_CACHE_TTL_DATA; break;
|
||||||
|
case CACHE_MODE_PIN: ttl = -1; break;
|
||||||
default: ttl = opt.def_cache_ttl; break;
|
default: ttl = opt.def_cache_ttl; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -369,11 +375,24 @@ agent_put_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode,
|
|||||||
|
|
||||||
for (r=thecache; r; r = r->next)
|
for (r=thecache; r; r = r->next)
|
||||||
{
|
{
|
||||||
if (((cache_mode != CACHE_MODE_USER
|
if (cache_mode == CACHE_MODE_PIN && data)
|
||||||
&& cache_mode != CACHE_MODE_NONCE)
|
{
|
||||||
|| cache_mode_equal (r->cache_mode, cache_mode))
|
/* PIN mode is special because it is only used by scdaemon. */
|
||||||
&& r->restricted == restricted
|
if (!strcmp (r->key, key))
|
||||||
&& !strcmp (r->key, key))
|
break;
|
||||||
|
}
|
||||||
|
else if (cache_mode == CACHE_MODE_PIN)
|
||||||
|
{
|
||||||
|
/* FIXME: Parse the structure of the key and delete several
|
||||||
|
* cached PINS. */
|
||||||
|
if (!strcmp (r->key, key))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (((cache_mode != CACHE_MODE_USER
|
||||||
|
&& cache_mode != CACHE_MODE_NONCE)
|
||||||
|
|| cache_mode_equal (r->cache_mode, cache_mode))
|
||||||
|
&& r->restricted == restricted
|
||||||
|
&& !strcmp (r->key, key))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (r) /* Replace. */
|
if (r) /* Replace. */
|
||||||
@ -437,6 +456,7 @@ agent_get_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode)
|
|||||||
int res;
|
int res;
|
||||||
int last_stored = 0;
|
int last_stored = 0;
|
||||||
int restricted = ctrl? ctrl->restricted : -1;
|
int restricted = ctrl? ctrl->restricted : -1;
|
||||||
|
int yes;
|
||||||
|
|
||||||
if (cache_mode == CACHE_MODE_IGNORE)
|
if (cache_mode == CACHE_MODE_IGNORE)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -461,12 +481,19 @@ agent_get_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode)
|
|||||||
|
|
||||||
for (r=thecache; r; r = r->next)
|
for (r=thecache; r; r = r->next)
|
||||||
{
|
{
|
||||||
if (r->pw
|
if (cache_mode == CACHE_MODE_PIN)
|
||||||
&& ((cache_mode != CACHE_MODE_USER
|
yes = (r->pw && !strcmp (r->key, key));
|
||||||
&& cache_mode != CACHE_MODE_NONCE)
|
else if (r->pw
|
||||||
|| cache_mode_equal (r->cache_mode, cache_mode))
|
&& ((cache_mode != CACHE_MODE_USER
|
||||||
&& r->restricted == restricted
|
&& cache_mode != CACHE_MODE_NONCE)
|
||||||
&& !strcmp (r->key, key))
|
|| cache_mode_equal (r->cache_mode, cache_mode))
|
||||||
|
&& r->restricted == restricted
|
||||||
|
&& !strcmp (r->key, key))
|
||||||
|
yes = 1;
|
||||||
|
else
|
||||||
|
yes = 0;
|
||||||
|
|
||||||
|
if (yes)
|
||||||
{
|
{
|
||||||
/* Note: To avoid races KEY may not be accessed anymore
|
/* Note: To avoid races KEY may not be accessed anymore
|
||||||
* below. Note also that we don't update the accessed time
|
* below. Note also that we don't update the accessed time
|
||||||
|
186
agent/call-scd.c
186
agent/call-scd.c
@ -246,6 +246,8 @@ wait_child_thread (void *arg)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
agent_flush_cache (1); /* Flush the PIN cache. */
|
||||||
|
|
||||||
err = npth_mutex_lock (&start_scd_lock);
|
err = npth_mutex_lock (&start_scd_lock);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
@ -389,6 +391,8 @@ start_scd (ctrl_t ctrl)
|
|||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_info ("no running SCdaemon - starting it\n");
|
log_info ("no running SCdaemon - starting it\n");
|
||||||
|
|
||||||
|
agent_flush_cache (1); /* Make sure the PIN cache is flushed. */
|
||||||
|
|
||||||
if (fflush (NULL))
|
if (fflush (NULL))
|
||||||
{
|
{
|
||||||
#ifndef HAVE_W32_SYSTEM
|
#ifndef HAVE_W32_SYSTEM
|
||||||
@ -625,11 +629,137 @@ agent_reset_scd (ctrl_t ctrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* This handler is a helper for pincache_put_cb but may also be called
|
||||||
|
* directly for that status code with ARGS being the arguments after
|
||||||
|
* the status keyword (and with white space removed). */
|
||||||
|
static gpg_error_t
|
||||||
|
handle_pincache_put (const char *args)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
const char *s, *key, *hexwrappedpin;
|
||||||
|
char *keybuf = NULL;
|
||||||
|
unsigned char *wrappedpin = NULL;
|
||||||
|
size_t keylen, hexwrappedpinlen, wrappedpinlen;
|
||||||
|
char *value = NULL;
|
||||||
|
size_t valuelen;
|
||||||
|
gcry_cipher_hd_t cipherhd = NULL;
|
||||||
|
|
||||||
|
key = s = args;
|
||||||
|
while (*s && !spacep (s))
|
||||||
|
s++;
|
||||||
|
keylen = s - key;
|
||||||
|
if (keylen < 3)
|
||||||
|
{
|
||||||
|
/* At least we need 2 slashes and slot number. */
|
||||||
|
log_error ("%s: ignoring invalid key\n", __func__);
|
||||||
|
err = 0;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
keybuf = xtrymalloc (keylen+1);
|
||||||
|
if (!keybuf)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
memcpy (keybuf, key, keylen);
|
||||||
|
keybuf[keylen] = 0;
|
||||||
|
key = keybuf;
|
||||||
|
|
||||||
|
while (spacep (s))
|
||||||
|
s++;
|
||||||
|
hexwrappedpin = s;
|
||||||
|
while (*s && !spacep (s))
|
||||||
|
s++;
|
||||||
|
hexwrappedpinlen = s - hexwrappedpin;
|
||||||
|
if (!hexwrappedpinlen)
|
||||||
|
{
|
||||||
|
/* Flush the cache. The cache module knows aboput the structure
|
||||||
|
* of the key to flush only parts. */
|
||||||
|
log_debug ("%s: flushing cache '%s'\n", __func__, key);
|
||||||
|
agent_put_cache (NULL, key, CACHE_MODE_PIN, NULL, -1);
|
||||||
|
err = 0;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hexwrappedpinlen < 2*24)
|
||||||
|
{
|
||||||
|
log_error ("%s: ignoring request with too short cryptogram\n", __func__);
|
||||||
|
err = 0;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
wrappedpinlen = hexwrappedpinlen / 2;
|
||||||
|
wrappedpin = xtrymalloc (wrappedpinlen);
|
||||||
|
if (!wrappedpin)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
if (hex2bin (hexwrappedpin, wrappedpin, wrappedpinlen) == -1)
|
||||||
|
{
|
||||||
|
log_error ("%s: invalid hex length\n", __func__);
|
||||||
|
err = gpg_error (GPG_ERR_INV_LENGTH);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
valuelen = wrappedpinlen - 8;
|
||||||
|
value = xtrymalloc_secure (valuelen+1);
|
||||||
|
if (!value)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
|
||||||
|
GCRY_CIPHER_MODE_AESWRAP, 0);
|
||||||
|
if (!err)
|
||||||
|
err = gcry_cipher_setkey (cipherhd, "1234567890123456", 16);
|
||||||
|
if (!err)
|
||||||
|
err = gcry_cipher_decrypt (cipherhd, value, valuelen,
|
||||||
|
wrappedpin, wrappedpinlen);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error ("%s: error decrypting the cryptogram: %s\n",
|
||||||
|
__func__, gpg_strerror (err));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_debug ("%s: caching '%s'->'%s'\n", __func__, key, value);
|
||||||
|
agent_put_cache (NULL, key, CACHE_MODE_PIN, value, -1);
|
||||||
|
|
||||||
|
leave:
|
||||||
|
xfree (keybuf);
|
||||||
|
xfree (value);
|
||||||
|
xfree (wrappedpin);
|
||||||
|
gcry_cipher_close (cipherhd);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This status callback is to intercept the PINCACHE_PUT status messages. */
|
||||||
|
static gpg_error_t
|
||||||
|
pincache_put_cb (void *opaque, const char *line)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
(void)opaque;
|
||||||
|
|
||||||
|
s = has_leading_keyword (line, "PINCACHE_PUT");
|
||||||
|
if (s)
|
||||||
|
return handle_pincache_put (s);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
learn_status_cb (void *opaque, const char *line)
|
learn_status_cb (void *opaque, const char *line)
|
||||||
{
|
{
|
||||||
struct learn_parm_s *parm = opaque;
|
struct learn_parm_s *parm = opaque;
|
||||||
|
gpg_error_t err = 0;
|
||||||
const char *keyword = line;
|
const char *keyword = line;
|
||||||
int keywordlen;
|
int keywordlen;
|
||||||
|
|
||||||
@ -645,12 +775,14 @@ learn_status_cb (void *opaque, const char *line)
|
|||||||
{
|
{
|
||||||
parm->kpinfo_cb (parm->kpinfo_cb_arg, line);
|
parm->kpinfo_cb (parm->kpinfo_cb_arg, line);
|
||||||
}
|
}
|
||||||
|
else if (keywordlen == 12 && !memcmp (keyword, "PINCACHE_PUT", keywordlen))
|
||||||
|
err = handle_pincache_put (line);
|
||||||
else if (keywordlen && *line)
|
else if (keywordlen && *line)
|
||||||
{
|
{
|
||||||
parm->sinfo_cb (parm->sinfo_cb_arg, keyword, keywordlen, line);
|
parm->sinfo_cb (parm->sinfo_cb_arg, keyword, keywordlen, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform the LEARN command and return a list of all private keys
|
/* Perform the LEARN command and return a list of all private keys
|
||||||
@ -692,6 +824,7 @@ agent_card_learn (ctrl_t ctrl,
|
|||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
get_serialno_cb (void *opaque, const char *line)
|
get_serialno_cb (void *opaque, const char *line)
|
||||||
{
|
{
|
||||||
|
gpg_error_t err = 0;
|
||||||
char **serialno = opaque;
|
char **serialno = opaque;
|
||||||
const char *keyword = line;
|
const char *keyword = line;
|
||||||
const char *s;
|
const char *s;
|
||||||
@ -716,8 +849,10 @@ get_serialno_cb (void *opaque, const char *line)
|
|||||||
memcpy (*serialno, line, n);
|
memcpy (*serialno, line, n);
|
||||||
(*serialno)[n] = 0;
|
(*serialno)[n] = 0;
|
||||||
}
|
}
|
||||||
|
else if (keywordlen == 12 && !memcmp (keyword, "PINCACHE_PUT", keywordlen))
|
||||||
|
err = handle_pincache_put (line);
|
||||||
|
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the serial number of the card or an appropriate error. The
|
/* Return the serial number of the card or an appropriate error. The
|
||||||
@ -787,6 +922,12 @@ inq_needpin (void *opaque, const char *line)
|
|||||||
rc = parm->getpin_cb (parm->getpin_cb_arg, parm->getpin_cb_desc,
|
rc = parm->getpin_cb (parm->getpin_cb_arg, parm->getpin_cb_desc,
|
||||||
"", NULL, 0);
|
"", NULL, 0);
|
||||||
}
|
}
|
||||||
|
else if ((s = has_leading_keyword (line, "PINCACHE_GET")))
|
||||||
|
{
|
||||||
|
/* rc = parm->getpin_cb (parm->getpin_cb_arg, parm->getpin_cb_desc, */
|
||||||
|
/* "", NULL, 0); */
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
else if (parm->passthru)
|
else if (parm->passthru)
|
||||||
{
|
{
|
||||||
unsigned char *value;
|
unsigned char *value;
|
||||||
@ -876,7 +1017,7 @@ agent_card_pksign (ctrl_t ctrl,
|
|||||||
bin2hex (indata, indatalen, stpcpy (line, "SETDATA "));
|
bin2hex (indata, indatalen, stpcpy (line, "SETDATA "));
|
||||||
|
|
||||||
rc = assuan_transact (ctrl->scd_local->ctx, line,
|
rc = assuan_transact (ctrl->scd_local->ctx, line,
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
NULL, NULL, NULL, NULL, pincache_put_cb, NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
return unlock_scd (ctrl, rc);
|
return unlock_scd (ctrl, rc);
|
||||||
|
|
||||||
@ -897,7 +1038,7 @@ agent_card_pksign (ctrl_t ctrl,
|
|||||||
rc = assuan_transact (ctrl->scd_local->ctx, line,
|
rc = assuan_transact (ctrl->scd_local->ctx, line,
|
||||||
put_membuf_cb, &data,
|
put_membuf_cb, &data,
|
||||||
inq_needpin, &inqparm,
|
inq_needpin, &inqparm,
|
||||||
NULL, NULL);
|
pincache_put_cb, NULL);
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -918,6 +1059,7 @@ agent_card_pksign (ctrl_t ctrl,
|
|||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
padding_info_cb (void *opaque, const char *line)
|
padding_info_cb (void *opaque, const char *line)
|
||||||
{
|
{
|
||||||
|
gpg_error_t err = 0;
|
||||||
int *r_padding = opaque;
|
int *r_padding = opaque;
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
@ -925,8 +1067,10 @@ padding_info_cb (void *opaque, const char *line)
|
|||||||
{
|
{
|
||||||
*r_padding = atoi (s);
|
*r_padding = atoi (s);
|
||||||
}
|
}
|
||||||
|
else if ((s=has_leading_keyword (line, "PINCACHE_PUT")))
|
||||||
|
err = handle_pincache_put (line);
|
||||||
|
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1023,7 +1167,7 @@ agent_card_readcert (ctrl_t ctrl,
|
|||||||
rc = assuan_transact (ctrl->scd_local->ctx, line,
|
rc = assuan_transact (ctrl->scd_local->ctx, line,
|
||||||
put_membuf_cb, &data,
|
put_membuf_cb, &data,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
NULL, NULL);
|
pincache_put_cb, NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
xfree (get_membuf (&data, &len));
|
xfree (get_membuf (&data, &len));
|
||||||
@ -1058,7 +1202,7 @@ agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf)
|
|||||||
rc = assuan_transact (ctrl->scd_local->ctx, line,
|
rc = assuan_transact (ctrl->scd_local->ctx, line,
|
||||||
put_membuf_cb, &data,
|
put_membuf_cb, &data,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
NULL, NULL);
|
pincache_put_cb, NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
xfree (get_membuf (&data, &len));
|
xfree (get_membuf (&data, &len));
|
||||||
@ -1122,7 +1266,8 @@ agent_card_writekey (ctrl_t ctrl, int force, const char *serialno,
|
|||||||
parms.keydatalen = keydatalen;
|
parms.keydatalen = keydatalen;
|
||||||
|
|
||||||
err = assuan_transact (ctrl->scd_local->ctx, line, NULL, NULL,
|
err = assuan_transact (ctrl->scd_local->ctx, line, NULL, NULL,
|
||||||
inq_writekey_parms, &parms, NULL, NULL);
|
inq_writekey_parms, &parms,
|
||||||
|
pincache_put_cb, NULL);
|
||||||
return unlock_scd (ctrl, err);
|
return unlock_scd (ctrl, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1140,6 +1285,7 @@ struct card_getattr_parm_s {
|
|||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
card_getattr_cb (void *opaque, const char *line)
|
card_getattr_cb (void *opaque, const char *line)
|
||||||
{
|
{
|
||||||
|
gpg_error_t err = 0;
|
||||||
struct card_getattr_parm_s *parm = opaque;
|
struct card_getattr_parm_s *parm = opaque;
|
||||||
const char *keyword = line;
|
const char *keyword = line;
|
||||||
int keywordlen;
|
int keywordlen;
|
||||||
@ -1159,8 +1305,10 @@ card_getattr_cb (void *opaque, const char *line)
|
|||||||
if (!parm->data)
|
if (!parm->data)
|
||||||
parm->error = errno;
|
parm->error = errno;
|
||||||
}
|
}
|
||||||
|
else if (keywordlen == 12 && !memcmp (keyword, "PINCACHE_PUT", keywordlen))
|
||||||
|
err = handle_pincache_put (line);
|
||||||
|
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1221,6 +1369,7 @@ struct card_cardlist_parm_s {
|
|||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
card_cardlist_cb (void *opaque, const char *line)
|
card_cardlist_cb (void *opaque, const char *line)
|
||||||
{
|
{
|
||||||
|
gpg_error_t err = 0;
|
||||||
struct card_cardlist_parm_s *parm = opaque;
|
struct card_cardlist_parm_s *parm = opaque;
|
||||||
const char *keyword = line;
|
const char *keyword = line;
|
||||||
int keywordlen;
|
int keywordlen;
|
||||||
@ -1243,8 +1392,10 @@ card_cardlist_cb (void *opaque, const char *line)
|
|||||||
else
|
else
|
||||||
add_to_strlist (&parm->list, line);
|
add_to_strlist (&parm->list, line);
|
||||||
}
|
}
|
||||||
|
else if (keywordlen == 12 && !memcmp (keyword, "PINCACHE_PUT", keywordlen))
|
||||||
|
err = handle_pincache_put (line);
|
||||||
|
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call the scdaemon to retrieve list of available cards. On success
|
/* Call the scdaemon to retrieve list of available cards. On success
|
||||||
@ -1290,6 +1441,7 @@ struct card_keyinfo_parm_s {
|
|||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
card_keyinfo_cb (void *opaque, const char *line)
|
card_keyinfo_cb (void *opaque, const char *line)
|
||||||
{
|
{
|
||||||
|
gpg_error_t err = 0;
|
||||||
struct card_keyinfo_parm_s *parm = opaque;
|
struct card_keyinfo_parm_s *parm = opaque;
|
||||||
const char *keyword = line;
|
const char *keyword = line;
|
||||||
int keywordlen;
|
int keywordlen;
|
||||||
@ -1378,8 +1530,10 @@ card_keyinfo_cb (void *opaque, const char *line)
|
|||||||
|
|
||||||
*l_p = keyinfo;
|
*l_p = keyinfo;
|
||||||
}
|
}
|
||||||
|
else if (keywordlen == 12 && !memcmp (keyword, "PINCACHE_PUT", keywordlen))
|
||||||
|
err = handle_pincache_put (line);
|
||||||
|
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1435,6 +1589,7 @@ agent_card_keyinfo (ctrl_t ctrl, const char *keygrip,
|
|||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
pass_status_thru (void *opaque, const char *line)
|
pass_status_thru (void *opaque, const char *line)
|
||||||
{
|
{
|
||||||
|
gpg_error_t err = 0;
|
||||||
assuan_context_t ctx = opaque;
|
assuan_context_t ctx = opaque;
|
||||||
char keyword[200];
|
char keyword[200];
|
||||||
int i;
|
int i;
|
||||||
@ -1459,9 +1614,13 @@ pass_status_thru (void *opaque, const char *line)
|
|||||||
while (spacep (line))
|
while (spacep (line))
|
||||||
line++;
|
line++;
|
||||||
|
|
||||||
assuan_write_status (ctx, keyword, line);
|
/* We do not want to pass PINCACHE_PUT through. */
|
||||||
|
if (!strcmp (keyword, "PINCACHE_PUT"))
|
||||||
|
err = handle_pincache_put (line);
|
||||||
|
else
|
||||||
|
assuan_write_status (ctx, keyword, line);
|
||||||
}
|
}
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
@ -1523,4 +1682,5 @@ agent_card_killscd (void)
|
|||||||
return;
|
return;
|
||||||
assuan_transact (primary_scd_ctx, "KILLSCD",
|
assuan_transact (primary_scd_ctx, "KILLSCD",
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
agent_flush_cache (1); /* Flush the PIN cache. */
|
||||||
}
|
}
|
||||||
|
@ -2434,7 +2434,7 @@ agent_sighup_action (void)
|
|||||||
log_info ("SIGHUP received - "
|
log_info ("SIGHUP received - "
|
||||||
"re-reading configuration and flushing cache\n");
|
"re-reading configuration and flushing cache\n");
|
||||||
|
|
||||||
agent_flush_cache ();
|
agent_flush_cache (0);
|
||||||
reread_configuration ();
|
reread_configuration ();
|
||||||
agent_reload_trustlist ();
|
agent_reload_trustlist ();
|
||||||
/* We flush the module name cache so that after installing a
|
/* We flush the module name cache so that after installing a
|
||||||
|
Loading…
Reference in New Issue
Block a user