From a98ea89fa5737fed15055ecfc9cbba121e372207 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 14 Nov 2006 14:53:42 +0000 Subject: [PATCH] New command GETEVENTCOUNTER. * command.c (bump_key_eventcounter): New. (bump_card_eventcounter): New. (cmd_geteventcounter): New command. * gpg-agent.c (handle_signal): Call bump_card_eventcounter. * findkey.c (agent_write_private_key): Call bump_key_eventcounter. * trustlist.c (agent_reload_trustlist): Ditto. --- TODO | 4 +++ agent/ChangeLog | 9 ++++++ agent/agent.h | 2 ++ agent/command.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++ agent/findkey.c | 2 +- agent/gpg-agent.c | 2 ++ agent/trustlist.c | 1 + doc/gpg-agent.texi | 26 +++++++++++++++ 8 files changed, 124 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index d5506531b..6d2d2f5f3 100644 --- a/TODO +++ b/TODO @@ -35,6 +35,10 @@ ** Remove the inter-module dependencies between gpgsm and keybox ** Add an source_of_key field +* agent/ +** If we detect that a private key has been deleted + Bump the key event counter. + * agent/command.c ** Make sure that secure memory is used where appropriate diff --git a/agent/ChangeLog b/agent/ChangeLog index 38ebd0f17..217350369 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,12 @@ +2006-11-14 Werner Koch + + * command.c (bump_key_eventcounter): New. + (bump_card_eventcounter): New. + (cmd_geteventcounter): New command. + * gpg-agent.c (handle_signal): Call bump_card_eventcounter. + * findkey.c (agent_write_private_key): Call bump_key_eventcounter. + * trustlist.c (agent_reload_trustlist): Ditto. + 2006-11-09 Werner Koch * gpg-agent.c (main): In detached mode connect standard diff --git a/agent/agent.h b/agent/agent.h index 6e02276b6..2b7f36741 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -182,6 +182,8 @@ void agent_init_default_ctrl (struct server_control_s *ctrl); /*-- command.c --*/ gpg_error_t agent_write_status (ctrl_t ctrl, const char *keyword, ...); +void bump_key_eventcounter (void); +void bump_card_eventcounter (void); void start_command_handler (int, int); /*-- command-ssh.c --*/ diff --git a/agent/command.c b/agent/command.c index d91b690df..981232d40 100644 --- a/agent/command.c +++ b/agent/command.c @@ -73,6 +73,28 @@ struct putval_item_s static struct putval_item_s *putval_list; + +/* To help polling clients, we keep tarck of the number of certain + events. This structure keeps those counters. The counters are + integers and there should be no problem if they are overflowing as + callers need to check only whether a counter changed. The actual + values are not meaningful. */ +struct +{ + /* Incremented if any of the other counters below changed. */ + unsigned int any; + + /* Incremented if a key is added or removed from the internal privat + key database. */ + unsigned int key; + + /* Incremented if a change of the card readers stati has been + detected. */ + unsigned int card; + +} eventcounter; + + @@ -292,6 +314,62 @@ agent_write_status (ctrl_t ctrl, const char *keyword, ...) } + +/* GETEVENTCOUNTER + + Return a a status line named EVENTCOUNTER with the current values + of all event counters. The values are decimal numbers in the range + 0 to UINT_MAX and wrapping around to 0. The actual values should + not be relied upon, they shall only be used to detect a change. + + The currently defined counters are: + + ANY - Incremented with any change of any of the other counters. + KEY - Incremented for added or removed private keys. + CARD - Incremented for changes of the card readers stati. +*/ +static int +cmd_geteventcounter (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + char any_counter[25]; + char key_counter[25]; + char card_counter[25]; + + snprintf (any_counter, sizeof any_counter, "%u", eventcounter.any); + snprintf (key_counter, sizeof key_counter, "%u", eventcounter.key); + snprintf (card_counter, sizeof card_counter, "%u", eventcounter.card); + + return agent_write_status (ctrl, "EVENTCOUNTER", + any_counter, + key_counter, + card_counter, + NULL); +} + + +/* This function should be called once for all key removals or + additions. Thus function is assured not to do any context + switches. */ +void +bump_key_eventcounter (void) +{ + eventcounter.key++; + eventcounter.any++; +} + +/* This function should be called for all card reader status + changes. Thus function is assured not to do any context + switches. */ +void +bump_card_eventcounter (void) +{ + eventcounter.card++; + eventcounter.any++; +} + + + /* ISTRUSTED @@ -1281,6 +1359,7 @@ register_commands (assuan_context_t ctx) const char *name; int (*handler)(assuan_context_t, char *line); } table[] = { + { "GETEVENTCOUNTER",cmd_geteventcounter }, { "ISTRUSTED", cmd_istrusted }, { "HAVEKEY", cmd_havekey }, { "SIGKEY", cmd_sigkey }, diff --git a/agent/findkey.c b/agent/findkey.c index 2e9c2b957..1510a9081 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -117,7 +117,7 @@ agent_write_private_key (const unsigned char *grip, xfree (fname); return tmperr; } - + bump_key_eventcounter (); xfree (fname); return 0; } diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 979fa3564..793bc91bf 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1400,6 +1400,8 @@ handle_signal (int signo) case SIGUSR2: if (opt.verbose) log_info ("SIGUSR2 received - checking smartcard status\n"); + /* Nothing to check right now. We only increment a counter. */ + bump_card_eventcounter (); break; case SIGTERM: diff --git a/agent/trustlist.c b/agent/trustlist.c index 0034525ad..9678ddab2 100644 --- a/agent/trustlist.c +++ b/agent/trustlist.c @@ -574,4 +574,5 @@ agent_reload_trustlist (void) trusttable = NULL; trusttablesize = 0; unlock_trusttable (); + bump_key_eventcounter (); } diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 44440bbcf..a1b7ac3b2 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -657,6 +657,7 @@ secret keys. * Agent LEARN:: Register a smartcard * Agent PASSWD:: Change a Passphrase * Agent UPDATESTARTUPTTY:: Change the Standard Display +* Agent GETEVENTCOUNTER:: Get the Event Counters @end menu @node Agent PKDECRYPT @@ -1076,6 +1077,31 @@ to another screen. It is only required because there is no way in the ssh-agent protocol to convey this information. +@node Agent GETEVENTCOUNTER +@subsection Get the Event Counters + +@example + GETEVENTCOUNTER +@end example + +This function return one status line with the current values of the +event counters. The event counters are useful to avoid polling by +delaying a poll until something has changed. The values are decimal +numbers in the range @code{0} to @code{UINT_MAX} and wrapping around to +0. The actual values should not be relied upon; they shall only be used +to detect a change. + +The currently defined counters are are: +@table @code +@item ANY +Incremented with any change of any of the other counters. +@item KEY +Incremented for added or removed private keys. +@item CARD +Incremented for changes of the card readers stati. +@end table + + @mansect see also @ifset isman @command{gpg2}(1),