tools: New option --keyboxd for gpg-connect-agent.

* 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>
This commit is contained in:
Werner Koch 2019-08-06 14:28:08 +02:00
parent e22ebf3570
commit 0611f548bc
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
7 changed files with 111 additions and 13 deletions

View File

@ -56,9 +56,11 @@
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);
}
@ -595,6 +606,25 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
}
/* 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_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. */

View 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

View 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;

View File

@ -43,6 +43,10 @@
#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);

View 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

View 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

View 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);
}