tools: New option --keyboxd for gpg-connect-agent.
authorWerner Koch <wk@gnupg.org>
Tue, 6 Aug 2019 12:28:08 +0000 (14:28 +0200)
committerWerner Koch <wk@gnupg.org>
Tue, 6 Aug 2019 12:57:07 +0000 (14:57 +0200)
* configure.ac: New option --keyboxd-pgm.
(KEYBOXD_NAME, KEYBOXD_DISP_NAME): New ac_defines.
* common/util.h: Add substitutes for new error codes.
(GNUPG_MODULE_NAME_KEYBOXD): New.
* common/homedir.c (gnupg_module_name): Support
GNUPG_MODULE_NAME_KEYBOXD.
* common/asshelp.c (SECS_TO_WAIT_FOR_KEYBOXD): New.
(wait_for_sock): Support keyboxd.
(start_new_service): Ditto.
(start_new_keyboxd): New.
* tools/gpg-connect-agent.c: New options --keyboxd and
--keyboxd-program.
(start_agent): Implement new option.
--

This change allows us to test the new keyboxd using our standard
helper.  It also provides the necessary code to start keyboxd on the
fly.

Signed-off-by: Werner Koch <wk@gnupg.org>
common/asshelp.c
common/asshelp.h
common/homedir.c
common/util.h
configure.ac
doc/tools.texi
tools/gpg-connect-agent.c

index 84bc546..a5724fa 100644 (file)
    operation after we started them before giving up.  */
 #ifdef HAVE_W32CE_SYSTEM
 # define SECS_TO_WAIT_FOR_AGENT 30
+# define SECS_TO_WAIT_FOR_KEYBOXD 30
 # define SECS_TO_WAIT_FOR_DIRMNGR 30
 #else
 # define SECS_TO_WAIT_FOR_AGENT 5
+# define SECS_TO_WAIT_FOR_KEYBOXD 5
 # define SECS_TO_WAIT_FOR_DIRMNGR 5
 #endif
 
@@ -308,17 +310,14 @@ unlock_spawning (lock_spawn_t *lock, const char *name)
 }
 
 
-/* Helper for start_new_gpg_agent and start_new_dirmngr.
- * Values for WHICH are:
- *   0 - Start gpg-agent
- *   1 - Start dirmngr
- * SECS give the number of seconds to wait.  SOCKNAME is the name of
+/* Helper to start a service.
+ * SECS gives the number of seconds to wait.  SOCKNAME is the name of
  * the socket to connect.  VERBOSE is the usual verbose flag. CTX is
  * the assuan context.  DID_SUCCESS_MSG will be set to 1 if a success
  * messages has been printed.
  */
 static gpg_error_t
-wait_for_sock (int secs, int which, const char *sockname,
+wait_for_sock (int secs, int module_name_id, const char *sockname,
                int verbose, assuan_context_t ctx, int *did_success_msg)
 {
   gpg_error_t err = 0;
@@ -343,8 +342,10 @@ wait_for_sock (int secs, int which, const char *sockname,
           /*            next_sleep_us); */
           if (secsleft < lastalert)
             {
-              log_info (which == 1?
+              log_info (module_name_id == GNUPG_MODULE_NAME_DIRMNGR?
                         _("waiting for the dirmngr to come up ... (%ds)\n"):
+                        module_name_id == GNUPG_MODULE_NAME_KEYBOXD?
+                        _("waiting for the keyboxd to come up ... (%ds)\n"):
                         _("waiting for the agent to come up ... (%ds)\n"),
                         secsleft);
               lastalert = secsleft;
@@ -357,8 +358,10 @@ wait_for_sock (int secs, int which, const char *sockname,
         {
           if (verbose)
             {
-              log_info (which == 1?
+              log_info (module_name_id == GNUPG_MODULE_NAME_DIRMNGR?
                         _("connection to the dirmngr established\n"):
+                        module_name_id == GNUPG_MODULE_NAME_KEYBOXD?
+                        _("connection to the keyboxd established\n"):
                         _("connection to the agent established\n"));
               *did_success_msg = 1;
             }
@@ -429,6 +432,14 @@ start_new_service (assuan_context_t *r_ctx,
       no_service_err = GPG_ERR_NO_DIRMNGR;
       seconds_to_wait = SECS_TO_WAIT_FOR_DIRMNGR;
       break;
+    case GNUPG_MODULE_NAME_KEYBOXD:
+      sockname = make_filename (gnupg_socketdir (), KEYBOXD_SOCK_NAME, NULL);
+      lock_name = "keyboxd";
+      printed_name = "keyboxd";
+      status_start_line = "starting_keyboxd ? 0 0";
+      no_service_err = GPG_ERR_NO_KEYBOXD;
+      seconds_to_wait = SECS_TO_WAIT_FOR_KEYBOXD;
+      break;
     default:
       err = gpg_error (GPG_ERR_INV_ARG);
       assuan_release (ctx);
@@ -520,7 +531,7 @@ start_new_service (assuan_context_t *r_ctx,
                        printed_name, program? program : program_name,
                        gpg_strerror (err));
           else
-            err = wait_for_sock (seconds_to_wait, 0,
+            err = wait_for_sock (seconds_to_wait, module_name_id,
                                  sockname, verbose, ctx, &did_success_msg);
         }
 
@@ -599,6 +610,25 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
    supporting it, start it up if needed and if AUTOSTART is true.
    Returns a new assuan context at R_CTX or an error code. */
 gpg_error_t
+start_new_keyboxd (assuan_context_t *r_ctx,
+                   gpg_err_source_t errsource,
+                   const char *keyboxd_program,
+                   int autostart, int verbose, int debug,
+                   gpg_error_t (*status_cb)(ctrl_t, int, ...),
+                   ctrl_t status_cb_arg)
+{
+  return start_new_service (r_ctx, GNUPG_MODULE_NAME_KEYBOXD,
+                            errsource, keyboxd_program,
+                            NULL, NULL, NULL,
+                            autostart, verbose, debug,
+                            status_cb, status_cb_arg);
+}
+
+
+/* Try to connect to the dirmngr via a socket.  On platforms
+   supporting it, start it up if needed and if AUTOSTART is true.
+   Returns a new assuan context at R_CTX or an error code. */
+gpg_error_t
 start_new_dirmngr (assuan_context_t *r_ctx,
                    gpg_err_source_t errsource,
                    const char *dirmngr_program,
index a04a077..b2f4e53 100644 (file)
@@ -65,6 +65,16 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
                      gpg_error_t (*status_cb)(ctrl_t, int, ...),
                      ctrl_t status_cb_arg);
 
+/* This function is used to connect to the keyboxd.  If needed the
+ * keyboxd is started.  */
+gpg_error_t
+start_new_keyboxd (assuan_context_t *r_ctx,
+                   gpg_err_source_t errsource,
+                   const char *keyboxd_program,
+                   int autostart, int verbose, int debug,
+                   gpg_error_t (*status_cb)(ctrl_t, int, ...),
+                   ctrl_t status_cb_arg);
+
 /* This function is used to connect to the dirmngr.  On some platforms
    the function is able starts a dirmngr process if needed.  */
 gpg_error_t
index 9c680a5..4425d78 100644 (file)
@@ -1115,6 +1115,13 @@ gnupg_module_name (int which)
       X(bindir, "dirmngr", DIRMNGR_NAME);
 #endif
 
+    case GNUPG_MODULE_NAME_KEYBOXD:
+#ifdef GNUPG_DEFAULT_KEYBOXD
+      return GNUPG_DEFAULT_KEYBOXD;
+#else
+      X(bindir, "keyboxd", KEYBOXD_NAME);
+#endif
+
     case GNUPG_MODULE_NAME_PROTECT_TOOL:
 #ifdef GNUPG_DEFAULT_PROTECT_TOOL
       return GNUPG_DEFAULT_PROTECT_TOOL;
index bd6cd1f..8f8a06a 100644 (file)
 #define GPG_ERR_NO_AUTH   314
 #define GPG_ERR_BAD_AUTH  315
 #endif /*GPG_ERROR_VERSION_NUMBER*/
+#if GPG_ERROR_VERSION_NUMBER < 0x012500 /* 1.37 */
+#define GPG_ERR_NO_KEYBOXD  316
+#define GPG_ERR_KEYBOXD     317
+#endif /*GPG_ERROR_VERSION_NUMBER*/
 
 /* Hash function used with libksba. */
 #define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write)
@@ -243,6 +247,7 @@ const char *gnupg_libdir (void);
 const char *gnupg_datadir (void);
 const char *gnupg_localedir (void);
 const char *gnupg_cachedir (void);
+const char *gpg_agent_socket_name (void);
 const char *dirmngr_socket_name (void);
 
 char *_gnupg_socketdir_internal (int skip_checks, unsigned *r_info);
@@ -261,6 +266,7 @@ char *_gnupg_socketdir_internal (int skip_checks, unsigned *r_info);
 #define GNUPG_MODULE_NAME_GPGCONF       10
 #define GNUPG_MODULE_NAME_DIRMNGR_LDAP  11
 #define GNUPG_MODULE_NAME_GPGV          12
+#define GNUPG_MODULE_NAME_KEYBOXD       13
 const char *gnupg_module_name (int which);
 void gnupg_module_name_flush_some (void);
 void gnupg_set_builddir (const char *newdir);
index df5ca12..f18e7a2 100644 (file)
@@ -191,6 +191,14 @@ AM_CONDITIONAL(GNUPG_DIRMNGR_PGM, test -n "$GNUPG_DIRMNGR_PGM")
 show_gnupg_dirmngr_pgm="(default)"
 test -n "$GNUPG_DIRMNGR_PGM" && show_gnupg_dirmngr_pgm="$GNUPG_DIRMNGR_PGM"
 
+AC_ARG_WITH(keyboxd-pgm,
+    [  --with-keyboxd-pgm=PATH  Use PATH as the default for the keyboxd)],
+          GNUPG_KEYBOXD_PGM="$withval", GNUPG_KEYBOXD_PGM="" )
+AC_SUBST(GNUPG_KEYBOXD_PGM)
+AM_CONDITIONAL(GNUPG_KEYBOXD_PGM, test -n "$GNUPG_KEYBOXD_PGM")
+show_gnupg_keyboxd_pgm="(default)"
+test -n "$GNUPG_KEYBOXD_PGM" && show_gnupg_keyboxd_pgm="$GNUPG_KEYBOXD_PGM"
+
 AC_ARG_WITH(protect-tool-pgm,
     [  --with-protect-tool-pgm=PATH  Use PATH as the default for the protect-tool)],
           GNUPG_PROTECT_TOOL_PGM="$withval", GNUPG_PROTECT_TOOL_PGM="" )
@@ -1870,6 +1878,10 @@ AC_DEFINE_UNQUOTED(DIRMNGR_NAME, "dirmngr", [The name of the dirmngr])
 AC_DEFINE_UNQUOTED(DIRMNGR_DISP_NAME, "DirMngr",
                                       [The displayed name of dirmngr])
 
+AC_DEFINE_UNQUOTED(KEYBOXD_NAME, "keyboxd", [The name of the keyboxd])
+AC_DEFINE_UNQUOTED(KEYBOXD_DISP_NAME, "Keyboxd",
+                                      [The displayed name of keyboxd])
+
 AC_DEFINE_UNQUOTED(G13_NAME, "g13", [The name of the g13 tool])
 AC_DEFINE_UNQUOTED(G13_DISP_NAME, "G13", [The displayed name of g13])
 
@@ -2090,6 +2102,7 @@ echo "
         Default agent:     $show_gnupg_agent_pgm
         Default pinentry:  $show_gnupg_pinentry_pgm
         Default scdaemon:  $show_gnupg_scdaemon_pgm
+        Default keyboxd:   $show_gnupg_keyboxd_pgm
         Default dirmngr:   $show_gnupg_dirmngr_pgm
 
         Dirmngr auto start:  $dirmngr_auto_start
index 4600300..0893c65 100644 (file)
@@ -1328,11 +1328,22 @@ Specify the directory manager (keyserver client) program to be started
 if none is running.  This has only an effect if used together with the
 option @option{--dirmngr}.
 
+@item --keyboxd-program @var{file}
+@opindex keyboxd-program
+Specify the keybox daemon program to be started if none is running.
+This has only an effect if used together with the option
+@option{--keyboxd}.
+
 @item --dirmngr
 @opindex dirmngr
 Connect to a running directory manager (keyserver client) instead of
 to the gpg-agent.  If a dirmngr is not running, start it.
 
+@item --keyboxd
+@opindex keyboxd
+Connect to a running keybox daemon instead of
+to the gpg-agent.  If a keyboxd is not running, start it.
+
 @item -S
 @itemx --raw-socket @var{name}
 @opindex raw-socket
index 7eb7ffa..0a128b3 100644 (file)
@@ -60,12 +60,14 @@ enum cmd_and_opt_values
     oHomedir,
     oAgentProgram,
     oDirmngrProgram,
+    oKeyboxdProgram,
     oHex,
     oDecode,
     oNoExtConnect,
     oDirmngr,
+    oKeyboxd,
     oUIServer,
-    oNoAutostart,
+    oNoAutostart
 
   };
 
@@ -79,6 +81,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oHex,   "hex",       N_("print data out hex encoded")),
   ARGPARSE_s_n (oDecode,"decode",    N_("decode received data lines")),
   ARGPARSE_s_n (oDirmngr,"dirmngr",  N_("connect to the dirmngr")),
+  ARGPARSE_s_n (oKeyboxd,"keyboxd",  N_("connect to the keyboxd")),
   ARGPARSE_s_n (oUIServer, "uiserver", "@"),
   ARGPARSE_s_s (oRawSocket, "raw-socket",
                 N_("|NAME|connect to Assuan socket NAME")),
@@ -97,6 +100,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oHomedir, "homedir", "@" ),
   ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
   ARGPARSE_s_s (oDirmngrProgram, "dirmngr-program", "@"),
+  ARGPARSE_s_s (oKeyboxdProgram, "keyboxd-program", "@"),
 
   ARGPARSE_end ()
 };
@@ -109,11 +113,13 @@ struct
   int quiet;           /* Be extra quiet.  */
   int autostart;        /* Start the server if not running.  */
   const char *homedir;  /* Configuration directory name */
-  const char *agent_program;  /* Value of --agent-program.  */
+  const char *agent_program;    /* Value of --agent-program.    */
   const char *dirmngr_program;  /* Value of --dirmngr-program.  */
+  const char *keyboxd_program;  /* Value of --keyboxd-program.  */
   int hex;              /* Print data lines in hex format. */
   int decode;           /* Decode received data lines.  */
   int use_dirmngr;      /* Use the dirmngr and not gpg-agent.  */
+  int use_keyboxd;      /* Use the keyboxd and not gpg-agent.  */
   int use_uiserver;     /* Use the standard UI server.  */
   const char *raw_socket; /* Name of socket to connect in raw mode. */
   const char *tcp_socket; /* Name of server to connect in tcp mode. */
@@ -1200,10 +1206,12 @@ main (int argc, char **argv)
         case oHomedir:   gnupg_set_homedir (pargs.r.ret_str); break;
         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
         case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str;  break;
+        case oKeyboxdProgram: opt.keyboxd_program = pargs.r.ret_str;  break;
         case oNoAutostart:    opt.autostart = 0; break;
         case oHex:       opt.hex = 1; break;
         case oDecode:    opt.decode = 1; break;
         case oDirmngr:   opt.use_dirmngr = 1; break;
+        case oKeyboxd:   opt.use_keyboxd = 1; break;
         case oUIServer:  opt.use_uiserver = 1; break;
         case oRawSocket: opt.raw_socket = pargs.r.ret_str; break;
         case oTcpSocket: opt.tcp_socket = pargs.r.ret_str; break;
@@ -1879,7 +1887,10 @@ main (int argc, char **argv)
     }
 
   if (opt.verbose)
-    log_info ("closing connection to agent\n");
+    log_info ("closing connection to %s\n",
+              opt.use_dirmngr? "dirmngr" :
+              opt.use_keyboxd? "keyboxd" :
+              "agent");
 
   /* XXX: We would like to release the context here, but libassuan
      nicely says good bye to the server, which results in a SIGPIPE if
@@ -2224,6 +2235,13 @@ start_agent (void)
                              opt.autostart,
                              !opt.quiet, 0,
                              NULL, NULL);
+  else if (opt.use_keyboxd)
+    err = start_new_keyboxd (&ctx,
+                             GPG_ERR_SOURCE_DEFAULT,
+                             opt.keyboxd_program,
+                             opt.autostart,
+                             !opt.quiet, 0,
+                             NULL, NULL);
   else
     err = start_new_gpg_agent (&ctx,
                                GPG_ERR_SOURCE_DEFAULT,
@@ -2239,12 +2257,15 @@ start_agent (void)
     {
       if (!opt.autostart
           && (gpg_err_code (err)
-              == (opt.use_dirmngr? GPG_ERR_NO_DIRMNGR : GPG_ERR_NO_AGENT)))
+              == (opt.use_dirmngr? GPG_ERR_NO_DIRMNGR :
+                  opt.use_keyboxd? GPG_ERR_NO_KEYBOXD : GPG_ERR_NO_AGENT)))
         {
           /* In the no-autostart case we don't make gpg-connect-agent
              fail on a missing server.  */
           log_info (opt.use_dirmngr?
                     _("no dirmngr running in this session\n"):
+                    opt.use_keyboxd?
+                    _("no keybox daemon running in this session\n"):
                     _("no gpg-agent running in this session\n"));
           exit (0);
         }