From 651d9e1c6bc1cab248024c3850ef64698247588f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 21 Feb 2014 11:22:45 +0100 Subject: [PATCH] Always pass correct name to argv[0]. Ignore GPG_AGENT_INFO for gpg2. * src/dirinfo.c (WANT_GPG_ONE_MODE): New. (struct dirinfo): Add field "gpg_one_mode". (get_gpgconf_item): Set that field and return it if requested. (_gpgme_in_gpg_one_mode): New. * src/engine-gpg.c (build_argv): Check GPG_AGENT_INFO only in gpg-1 mode. * src/dirinfo.c (_gpgme_get_basename): New. * src/engine-g13.c (g13_new): Take argv[0] from the pgmname. * src/engine-gpgsm.c (gpgsm_new): Ditto. * src/engine-gpg.c (build_argv): Ditto. Add arg PGMNAME. (start): Pass PGMNAME to buildargv. --- src/dirinfo.c | 35 ++++++++++++++++++++++++++++++++++- src/engine-g13.c | 14 +++++++------- src/engine-gpg.c | 34 ++++++++++++++++++++-------------- src/engine-gpgsm.c | 17 ++++++++--------- src/util.h | 3 +++ 5 files changed, 72 insertions(+), 31 deletions(-) diff --git a/src/dirinfo.c b/src/dirinfo.c index eb29c6bd..8526d392 100644 --- a/src/dirinfo.c +++ b/src/dirinfo.c @@ -42,7 +42,8 @@ enum WANT_GPG_NAME, WANT_GPGSM_NAME, WANT_G13_NAME, - WANT_UISRV_SOCKET + WANT_UISRV_SOCKET, + WANT_GPG_ONE_MODE }; /* Values retrieved via gpgconf and cached here. */ @@ -56,6 +57,7 @@ static struct { char *gpgsm_name; char *g13_name; char *uisrv_socket; + int gpg_one_mode; /* System is in gpg1 mode. */ } dirinfo; @@ -223,12 +225,14 @@ get_gpgconf_item (int what) { /* Probably gpgconf is not installed. Assume we are using GnuPG-1. */ + dirinfo.gpg_one_mode = 1; pgmname = _gpgme_get_gpg_path (); if (pgmname) dirinfo.gpg_name = pgmname; } else { + dirinfo.gpg_one_mode = 0; read_gpgconf_dirs (pgmname, 0); read_gpgconf_dirs (pgmname, 1); dirinfo.gpgconf_name = pgmname; @@ -268,6 +272,7 @@ get_gpgconf_item (int what) case WANT_GPGSM_NAME: result = dirinfo.gpgsm_name; break; case WANT_G13_NAME: result = dirinfo.g13_name; break; case WANT_UISRV_SOCKET: result = dirinfo.uisrv_socket; break; + case WANT_GPG_ONE_MODE: result = dirinfo.gpg_one_mode? "1":NULL; break; } UNLOCK (dirinfo_lock); return result; @@ -323,3 +328,31 @@ _gpgme_get_default_uisrv_socket (void) { return get_gpgconf_item (WANT_UISRV_SOCKET); } + +/* Return true if we are in GnuPG-1 mode - ie. no gpgconf and agent + being optional. */ +int +_gpgme_in_gpg_one_mode (void) +{ + return !!get_gpgconf_item (WANT_GPG_ONE_MODE); +} + + + +/* Helper function to return the basename of the passed filename. */ +const char * +_gpgme_get_basename (const char *name) +{ + const char *s; + + if (!name || !*name) + return name; + for (s = name + strlen (name) -1; s >= name; s--) + if (*s == '/' +#ifdef HAVE_W32_SYSTEM + || *s == '\\' || *s == ':' +#endif + ) + return s+1; + return name; +} diff --git a/src/engine-g13.c b/src/engine-g13.c index f0910159..75154ca0 100644 --- a/src/engine-g13.c +++ b/src/engine-g13.c @@ -216,6 +216,7 @@ g13_new (void **engine, const char *file_name, const char *home_dir) { gpgme_error_t err = 0; engine_g13_t g13; + const char *pgmname; int argc; const char *argv[5]; char *dft_display = NULL; @@ -232,8 +233,9 @@ g13_new (void **engine, const char *file_name, const char *home_dir) g13->status_cb.tag = 0; g13->status_cb.data = g13; + pgmname = file_name ? file_name : _gpgme_get_default_g13_name (); argc = 0; - argv[argc++] = "g13"; + argv[argc++] = _gpgme_get_basename (pgmname); if (home_dir) { argv[argc++] = "--homedir"; @@ -250,13 +252,11 @@ g13_new (void **engine, const char *file_name, const char *home_dir) assuan_ctx_set_system_hooks (g13->assuan_ctx, &_gpgme_assuan_system_hooks); #if USE_DESCRIPTOR_PASSING - err = assuan_pipe_connect - (g13->assuan_ctx, file_name ? file_name : _gpgme_get_default_g13_name (), - argv, NULL, NULL, NULL, ASSUAN_PIPE_CONNECT_FDPASSING); + err = assuan_pipe_connect (g13->assuan_ctx, pgmname, argv, + NULL, NULL, NULL, ASSUAN_PIPE_CONNECT_FDPASSING); #else - err = assuan_pipe_connect - (g13->assuan_ctx, file_name ? file_name : _gpgme_get_default_g13_name (), - argv, NULL, NULL, NULL, 0); + err = assuan_pipe_connect (g13->assuan_ctx, pgmname, argv, + NULL, NULL, NULL, 0); #endif if (err) goto leave; diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 2f59bb9a..6b04e184 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -718,7 +718,7 @@ gpg_set_command_handler (void *engine, engine_command_handler_t fnc, static gpgme_error_t -build_argv (engine_gpg_t gpg) +build_argv (engine_gpg_t gpg, const char *pgmname) { gpgme_error_t err; struct arg_and_data_s *a; @@ -729,15 +729,20 @@ build_argv (engine_gpg_t gpg) int use_agent = 0; char *p; - /* We don't want to use the agent with a malformed environment - variable. This is only a very basic test but sufficient to make - our life in the regression tests easier. */ - err = _gpgme_getenv ("GPG_AGENT_INFO", &p); - if (err) - return err; - use_agent = (p && strchr (p, ':')); - if (p) - free (p); + if (_gpgme_in_gpg_one_mode ()) + { + /* In GnuPG-1 mode we don't want to use the agent with a + malformed environment variable. This is only a very basic + test but sufficient to make our life in the regression tests + easier. With GnuPG-2 the agent is anyway required and on + modern installations GPG_AGENT_INFO is optional. */ + err = _gpgme_getenv ("GPG_AGENT_INFO", &p); + if (err) + return err; + use_agent = (p && strchr (p, ':')); + if (p) + free (p); + } if (gpg->argv) { @@ -788,7 +793,7 @@ build_argv (engine_gpg_t gpg) } argc = datac = 0; - argv[argc] = strdup ("gpg"); /* argv[0] */ + argv[argc] = strdup (_gpgme_get_basename (pgmname)); /* argv[0] */ if (!argv[argc]) { int saved_err = gpg_error_from_syserror (); @@ -1292,6 +1297,7 @@ start (engine_gpg_t gpg) int status; struct spawn_fd_item_s *fd_list; pid_t pid; + const char *pgmname; if (!gpg) return gpg_error (GPG_ERR_INV_VALUE); @@ -1317,7 +1323,8 @@ start (engine_gpg_t gpg) return rc; } - rc = build_argv (gpg); + pgmname = gpg->file_name ? gpg->file_name : _gpgme_get_default_gpg_name (); + rc = build_argv (gpg, pgmname); if (rc) return rc; @@ -1351,8 +1358,7 @@ start (engine_gpg_t gpg) fd_list[n].fd = -1; fd_list[n].dup_to = -1; - status = _gpgme_io_spawn (gpg->file_name ? gpg->file_name : - _gpgme_get_default_gpg_name (), gpg->argv, + status = _gpgme_io_spawn (pgmname, gpg->argv, IOSPAWN_FLAG_ALLOW_SET_FG, fd_list, NULL, NULL, &pid); { diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c index 24cd34d9..6bcc0952 100644 --- a/src/engine-gpgsm.c +++ b/src/engine-gpgsm.c @@ -239,6 +239,7 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir) { gpgme_error_t err = 0; engine_gpgsm_t gpgsm; + const char *pgmname; const char *argv[5]; int argc; #if !USE_DESCRIPTOR_PASSING @@ -321,8 +322,10 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir) child_fds[3] = -1; #endif + pgmname = file_name ? file_name : _gpgme_get_default_gpgsm_name (); + argc = 0; - argv[argc++] = "gpgsm"; + argv[argc++] = _gpgme_get_basename (pgmname); if (home_dir) { argv[argc++] = "--homedir"; @@ -339,10 +342,8 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir) assuan_ctx_set_system_hooks (gpgsm->assuan_ctx, &_gpgme_assuan_system_hooks); #if USE_DESCRIPTOR_PASSING - err = assuan_pipe_connect - (gpgsm->assuan_ctx, - file_name ? file_name : _gpgme_get_default_gpgsm_name (), - argv, NULL, NULL, NULL, ASSUAN_PIPE_CONNECT_FDPASSING); + err = assuan_pipe_connect (gpgsm->assuan_ctx, pgmname, argv, + NULL, NULL, NULL, ASSUAN_PIPE_CONNECT_FDPASSING); #else { assuan_fd_t achild_fds[4]; @@ -352,10 +353,8 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir) for (i = 0; i < 4; i++) achild_fds[i] = (assuan_fd_t) child_fds[i]; - err = assuan_pipe_connect - (gpgsm->assuan_ctx, - file_name ? file_name : _gpgme_get_default_gpgsm_name (), - argv, achild_fds, NULL, NULL, 0); + err = assuan_pipe_connect (gpgsm->assuan_ctx, pgmname, argv, + achild_fds, NULL, NULL, 0); /* For now... */ for (i = 0; i < 4; i++) diff --git a/src/util.h b/src/util.h index c0934e16..4b46ea0b 100644 --- a/src/util.h +++ b/src/util.h @@ -60,6 +60,9 @@ const char *_gpgme_get_default_gpgsm_name (void); const char *_gpgme_get_default_g13_name (void); const char *_gpgme_get_default_gpgconf_name (void); const char *_gpgme_get_default_uisrv_socket (void); +int _gpgme_in_gpg_one_mode (void); + +const char *_gpgme_get_basename (const char *name);