aboutsummaryrefslogtreecommitdiffstats
path: root/sm/call-dirmngr.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2010-08-16 11:03:43 +0000
committerWerner Koch <[email protected]>2010-08-16 11:03:43 +0000
commit7e752a42082a96b62ae283e8763bc1be48693c0c (patch)
tree51874625e0a7bcaff265957eb69c76e2e428bd6f /sm/call-dirmngr.c
parentMinor Makefile fixes to let it build on all platforms (diff)
downloadgnupg-7e752a42082a96b62ae283e8763bc1be48693c0c.tar.gz
gnupg-7e752a42082a96b62ae283e8763bc1be48693c0c.zip
Auto-start dirmngr.
Diffstat (limited to 'sm/call-dirmngr.c')
-rw-r--r--sm/call-dirmngr.c147
1 files changed, 15 insertions, 132 deletions
diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c
index ba6cf6fba..6d0236c72 100644
--- a/sm/call-dirmngr.c
+++ b/sm/call-dirmngr.c
@@ -1,5 +1,6 @@
-/* call-dirmngr.c - communication with the dromngr
- * Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
+/* call-dirmngr.c - Communication with the dirmngr
+ * Copyright (C) 2002, 2003, 2005, 2007, 2008,
+ * 2010 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -33,6 +34,7 @@
#include "i18n.h"
#include "keydb.h"
+#include "asshelp.h"
struct membuf {
@@ -52,8 +54,6 @@ static assuan_context_t dirmngr2_ctx = NULL;
static int dirmngr_ctx_locked;
static int dirmngr2_ctx_locked;
-static int force_pipe_server = 0;
-
struct inq_certificate_parm_s {
ctrl_t ctrl;
assuan_context_t ctx;
@@ -184,15 +184,12 @@ prepare_dirmngr (ctrl_t ctrl, assuan_context_t ctx, gpg_error_t err)
-/* Try to connect to the agent via socket or fork it off and work by
- pipes. Handle the server's initial greeting */
-static int
+/* Return a new assuan context for a Dirmngr connection. */
+static gpg_error_t
start_dirmngr_ext (ctrl_t ctrl, assuan_context_t *ctx_r)
{
- int rc;
- char *infostr, *p;
- assuan_context_t ctx = NULL;
- int try_default = 0;
+ gpg_error_t err;
+ assuan_context_t ctx;
if (opt.disable_dirmngr)
return gpg_error (GPG_ERR_NO_DIRMNGR);
@@ -203,129 +200,15 @@ start_dirmngr_ext (ctrl_t ctrl, assuan_context_t *ctx_r)
/* Note: if you change this to multiple connections, you also need
to take care of the implicit option sending caching. */
-#ifdef HAVE_W32_SYSTEM
- infostr = NULL;
- opt.prefer_system_dirmngr = 1;
-#else
- infostr = force_pipe_server? NULL : getenv ("DIRMNGR_INFO");
-#endif /*HAVE_W32_SYSTEM*/
- if (infostr && !*infostr)
- infostr = NULL;
- else if (infostr)
- infostr = xstrdup (infostr);
-
- if (opt.prefer_system_dirmngr && !force_pipe_server && !infostr)
- {
- infostr = xstrdup (dirmngr_socket_name ());
- try_default = 1;
- }
+ err = start_new_dirmngr (&ctx, GPG_ERR_SOURCE_DEFAULT,
+ opt.homedir, opt.dirmngr_program,
+ opt.verbose, DBG_ASSUAN,
+ gpgsm_status2, ctrl);
+ prepare_dirmngr (ctrl, ctx, err);
+ if (err)
+ return err;
- rc = assuan_new (&ctx);
- if (rc)
- {
- log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc));
- return rc;
- }
-
- if (!infostr)
- {
- const char *pgmname;
- const char *argv[3];
- int no_close_list[3];
- int i;
-
- if (!opt.dirmngr_program || !*opt.dirmngr_program)
- opt.dirmngr_program = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR);
- if ( !(pgmname = strrchr (opt.dirmngr_program, '/')))
- pgmname = opt.dirmngr_program;
- else
- pgmname++;
-
- if (opt.verbose)
- log_info (_("no running dirmngr - starting `%s'\n"),
- opt.dirmngr_program);
-
- if (fflush (NULL))
- {
- gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
- log_error ("error flushing pending output: %s\n", strerror (errno));
- return tmperr;
- }
-
- argv[0] = pgmname;
- argv[1] = "--server";
- argv[2] = NULL;
-
- i=0;
- if (log_get_fd () != -1)
- no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
- no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
- no_close_list[i] = -1;
-
- /* connect to the agent and perform initial handshaking */
- rc = assuan_pipe_connect (ctx, opt.dirmngr_program, argv,
- no_close_list, NULL, NULL, 0);
- }
- else
- {
- int prot;
- int pid;
-
- if (!try_default)
- {
- if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
- {
- log_error (_("malformed DIRMNGR_INFO environment variable\n"));
- xfree (infostr);
- force_pipe_server = 1;
- return start_dirmngr_ext (ctrl, ctx_r);
- }
- *p++ = 0;
- pid = atoi (p);
- while (*p && *p != PATHSEP_C)
- p++;
- prot = *p? atoi (p+1) : 0;
- if (prot != 1)
- {
- log_error (_("dirmngr protocol version %d is not supported\n"),
- prot);
- xfree (infostr);
- force_pipe_server = 1;
- return start_dirmngr_ext (ctrl, ctx_r);
- }
- }
- else
- pid = -1;
-
- rc = assuan_socket_connect (ctx, infostr, pid, 0);
-#ifdef HAVE_W32_SYSTEM
- if (rc)
- log_debug ("connecting dirmngr at `%s' failed\n", infostr);
-#endif
-
- xfree (infostr);
-#ifndef HAVE_W32_SYSTEM
- if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED)
- {
- log_info (_("can't connect to the dirmngr - trying fall back\n"));
- force_pipe_server = 1;
- return start_dirmngr_ext (ctrl, ctx_r);
- }
-#endif /*!HAVE_W32_SYSTEM*/
- }
-
- prepare_dirmngr (ctrl, ctx, rc);
-
- if (rc)
- {
- assuan_release (ctx);
- log_error ("can't connect to the dirmngr: %s\n", gpg_strerror (rc));
- return gpg_error (GPG_ERR_NO_DIRMNGR);
- }
*ctx_r = ctx;
-
- if (DBG_ASSUAN)
- log_debug ("connection to dirmngr established\n");
return 0;
}