From a873951b721b4161cbe3fadf01296139f7e7a23d Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Thu, 22 Sep 2016 19:41:28 -0400 Subject: [PATCH] KEYINFO: Add --learn. To learn about smartcard keys. --- doc/pwmd.html | 5 ++++- src/agent.c | 27 ++------------------------- src/cache.c | 11 +++++++++++ src/cache.h | 1 + src/commands.c | 30 +++++++++++++++++++++++++++++- 5 files changed, 47 insertions(+), 27 deletions(-) diff --git a/doc/pwmd.html b/doc/pwmd.html index 06d5231e..7bf83fa3 100644 --- a/doc/pwmd.html +++ b/doc/pwmd.html @@ -1090,7 +1090,7 @@ Next: , Previous:

Syntax:

-
KEYINFO
+
KEYINFO [--learn]
 

Returns a new line separated list of key ID’s that the currently opened @@ -1098,6 +1098,9 @@ data file has recipients and signers for. If the key is a signing key it will be prefixed with an S. If the file is a new one, or has no signers in the case of being symmetrically encrypted, the error code GPG_ERR_NO_DATA is returned. +

+When the --learn option is passed, keys on a smartcard will be +imported.


diff --git a/src/agent.c b/src/agent.c index 4d894753..10756dfc 100644 --- a/src/agent.c +++ b/src/agent.c @@ -64,29 +64,6 @@ mem_realloc_cb (void *data, const void *buffer, size_t len) } static gpg_error_t -status_cb (void *data, const char *line) -{ - struct agent_s *agent = data; - - agent->inquire_maxlen = 0; - - if (!strncmp (line, "INQUIRE_MAXLEN ", 15)) - agent->inquire_maxlen = atoi (line + 15); - - return 0; -} - -static gpg_error_t -inquire_cb (void *user, const char *keyword) -{ - struct agent_s *agent = user; - - (void)keyword; - return assuan_send_data (agent->ctx, agent->inquire->line, - agent->inquire->len); -} - -static gpg_error_t assuan_command (struct agent_s *a, char **result, size_t * len, const char *cmd) { @@ -99,8 +76,8 @@ assuan_command (struct agent_s *a, char **result, if (len) *len = 0; - rc = assuan_transact (a->ctx, cmd, mem_realloc_cb, &a->data, - inquire_cb, a, status_cb, a); + rc = assuan_transact (a->ctx, cmd, mem_realloc_cb, &a->data, NULL, NULL, + NULL, NULL); if (rc) xfree (a->data.buf); else diff --git a/src/cache.c b/src/cache.c index 22da5191..3b0f7a2b 100644 --- a/src/cache.c +++ b/src/cache.c @@ -1008,6 +1008,17 @@ cache_kill_scd () return rc; } +gpg_error_t +cache_agent_command (const char *cmd) +{ + gpg_error_t rc; + + MUTEX_LOCK (&cache_mutex); + rc = agent_command (cache_agent, NULL, NULL, "%s", cmd); + MUTEX_UNLOCK (&cache_mutex); + return rc; +} + void cache_release_mutex () { diff --git a/src/cache.h b/src/cache.h index 7b2b749f..a7d5df1d 100644 --- a/src/cache.h +++ b/src/cache.h @@ -74,5 +74,6 @@ gpg_error_t cache_defer_clear (const char *); gpg_error_t cache_encrypt (struct crypto_s *); gpg_error_t cache_decrypt (struct crypto_s *); gpg_error_t cache_clear_agent_keys (const char *, int decrypt, int sign); +gpg_error_t cache_agent_command (const char *); #endif diff --git a/src/commands.c b/src/commands.c index 766e5a7e..fe8a2f19 100644 --- a/src/commands.c +++ b/src/commands.c @@ -71,6 +71,7 @@ #define OPT_HTML 0x10000 #define OPT_CACHE_AGENT 0x20000 #define OPT_CACHE_SIGN 0x40000 +#define OPT_KEYINFO_LEARN 0x80000 #define FLOCK_TYPE_NONE 0 #define FLOCK_TYPE_SH 0x0001 @@ -4216,12 +4217,30 @@ parse_listkeys_opt_secret_only (void *data, void *value) } static gpg_error_t +parse_keyinfo_opt_learn (void *data, void *value) +{ + struct client_s *client = data; + + (void)value; + client->opts |= OPT_KEYINFO_LEARN; + return 0; +} + +static gpg_error_t keyinfo_command (assuan_context_t ctx, char *line) { struct client_s *client = assuan_get_pointer (ctx); gpg_error_t rc = 0; char **keys = NULL, **p = NULL; int sym = 0; + struct argv_s *args[] = { + &(struct argv_s) {"learn", OPTION_TYPE_NOARG, parse_keyinfo_opt_learn}, + NULL + }; + + rc = parse_options (&line, args, client, 0); + if (rc) + return send_error (ctx, rc); if (line && *line) return send_error (ctx, GPG_ERR_SYNTAX); @@ -4229,6 +4248,12 @@ keyinfo_command (assuan_context_t ctx, char *line) if (!(client->flags & FLAG_OPEN)) return send_error (ctx, GPG_ERR_INV_STATE); + if (client->opts & OPT_KEYINFO_LEARN) + { + rc = cache_agent_command ("LEARN"); + return send_error (ctx, rc); + } + if (client->flags & FLAG_NEW) return send_error (ctx, GPG_ERR_NO_DATA); @@ -4489,12 +4514,15 @@ init_commands () )); new_command("KEYINFO", 1, 0, 0, keyinfo_command, _( -"KEYINFO\n" +"KEYINFO [--learn]\n" "Returns a new line separated list of key ID's that the currently opened " "data file has recipients and signers for. If the key is a signing key it " "will be prefixed with an @code{S}. If the file is a new one, or has no " "signers in the case of being symmetrically encrypted, the error code " "@code{GPG_ERR_NO_DATA} is returned." +"@*@*" +"When the @option{--learn} option is passed, keys on a smartcard will be " +"imported." )); new_command("GETINFO", 1, 1, 0, getinfo_command, _( -- 2.11.4.GIT