Replace use of opt.homedir by accessor functions.
[gnupg.git] / dirmngr / dirmngr.c
index b6892bf..bc71a40 100644 (file)
@@ -1,4 +1,4 @@
-/* dirmngr.c - LDAP access
+/* dirmngr.c - Keyserver and X.509 LDAP access
  * Copyright (C) 2002 Klarälvdalens Datakonsult AB
  * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2010, 2011 g10 Code GmbH
  * Copyright (C) 2014 Werner Koch
@@ -50,8 +50,7 @@
 #endif /*HTTP_USE_GNUTLS*/
 
 
-#define JNLIB_NEED_LOG_LOGV
-#define JNLIB_NEED_AFLOCAL
+#define GNUPG_COMMON_NEED_AFLOCAL
 #include "dirmngr.h"
 
 #include <assuan.h>
 #include "crlcache.h"
 #include "crlfetch.h"
 #include "misc.h"
-#include "ldapserver.h"
+#if USE_LDAP
+# include "ldapserver.h"
+#endif
 #include "asshelp.h"
-#include "ldap-wrapper.h"
+#if USE_LDAP
+# include "ldap-wrapper.h"
+#endif
 #include "../common/init.h"
 #include "gc-opt-flags.h"
+#include "dns-stuff.h"
 
 /* The plain Windows version uses the windows service system.  For
    example to start the service you may use "sc start dirmngr".
 # define USE_W32_SERVICE 1
 #endif
 
+#ifndef ENAMETOOLONG
+# define ENAMETOOLONG EINVAL
+#endif
+
 
 enum cmd_and_opt_values {
   aNull = 0,
@@ -133,6 +141,9 @@ enum cmd_and_opt_values {
   oLDAPWrapperProgram,
   oHTTPWrapperProgram,
   oIgnoreCertExtension,
+  oUseTor,
+  oKeyServer,
+  oNameServer,
   aTest
 };
 
@@ -205,14 +216,17 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_i (oMaxReplies, "max-replies",
                 N_("|N|do not return more than N items in one query")),
 
+  ARGPARSE_s_s (oNameServer, "nameserver", "@"),
+  ARGPARSE_s_s (oKeyServer, "keyserver", "@"),
   ARGPARSE_s_s (oHkpCaCert, "hkp-cacert",
                 N_("|FILE|use the CA certificates in FILE for HKP over TLS")),
 
+  ARGPARSE_s_n (oUseTor, "use-tor", N_("route all network traffic via Tor")),
 
   ARGPARSE_s_s (oSocketName, "socket-name", "@"),  /* Only for debugging.  */
 
   ARGPARSE_s_u (oFakedSystemTime, "faked-system-time", "@"), /*(epoch time)*/
-  ARGPARSE_p_u (oDebug,    "debug", "@"),
+  ARGPARSE_s_s (oDebug,    "debug", "@"),
   ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
   ARGPARSE_s_i (oGnutlsDebug, "gnutls-debug", "@"),
   ARGPARSE_s_i (oGnutlsDebug, "tls-debug", "@"),
@@ -230,17 +244,34 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_end ()
 };
 
+/* The list of supported debug flags.  */
+static struct debug_flags_s debug_flags [] =
+  {
+    { DBG_X509_VALUE   , "x509"    },
+    { DBG_CRYPTO_VALUE , "crypto"  },
+    { DBG_MEMORY_VALUE , "memory"  },
+    { DBG_CACHE_VALUE  , "cache"   },
+    { DBG_MEMSTAT_VALUE, "memstat" },
+    { DBG_HASHING_VALUE, "hashing" },
+    { DBG_IPC_VALUE    , "ipc"     },
+    { DBG_LOOKUP_VALUE , "lookup"  },
+    { 77, NULL } /* 77 := Do not exit on "help" or "?".  */
+  };
+
 #define DEFAULT_MAX_REPLIES 10
 #define DEFAULT_LDAP_TIMEOUT 100 /* arbitrary large timeout */
 
-/* For the cleanup handler we need to keep track of the socket's name. */
+/* For the cleanup handler we need to keep track of the socket's name.  */
 static const char *socket_name;
+/* If the socket has been redirected, this is the name of the
+   redirected socket..  */
+static const char *redir_socket_name;
 
 /* We need to keep track of the server's nonces (these are dummies for
    POSIX systems). */
 static assuan_sock_nonce_t socket_nonce;
 
-/* Only if this flag has been set we will remove the socket file.  */
+/* Only if this flag has been set will we remove the socket file.  */
 static int cleanup_socket;
 
 /* Keep track of the current log file so that we can avoid updating
@@ -287,14 +318,16 @@ union int_and_ptr_u
 
 /* The key used to store the current file descriptor in the thread
    local storage.  We use this in conjunction with the
-   log_set_pid_suffix_cb feature..  */
+   log_set_pid_suffix_cb feature.  */
 #ifndef HAVE_W32_SYSTEM
 static int my_tlskey_current_fd;
 #endif
 
 /* Prototypes. */
 static void cleanup (void);
+#if USE_LDAP
 static ldap_server_t parse_ldapserver_file (const char* filename);
+#endif /*USE_LDAP*/
 static fingerprint_list_t parse_ocsp_signer (const char *string);
 static void handle_connections (assuan_fd_t listen_fd);
 
@@ -320,7 +353,7 @@ my_strusage( int level )
     case 40: p = _("Usage: @DIRMNGR@ [options] (-h for help)");
       break;
     case 41: p = _("Syntax: @DIRMNGR@ [options] [command [args]]\n"
-                   "LDAP and OCSP access for @GNUPG@\n");
+                   "Keyserver, CRL, and OCSP access for @GNUPG@\n");
       break;
 
     default: p = NULL;
@@ -351,6 +384,7 @@ my_ksba_hash_buffer (void *arg, const char *oid,
 
 
 /* GNUTLS log function callback.  */
+#ifdef HTTP_USE_GNUTLS
 static void
 my_gnutls_log (int level, const char *text)
 {
@@ -362,7 +396,7 @@ my_gnutls_log (int level, const char *text)
 
   log_debug ("gnutls:L%d: %.*s\n", level, n, text);
 }
-
+#endif /*HTTP_USE_GNUTLS*/
 
 /* Setup the debugging.  With a LEVEL of NULL only the active debug
    flags are propagated to the subsystems.  With LEVEL set, a specific
@@ -379,11 +413,11 @@ set_debug (void)
   else if (!strcmp (debug_level, "none") || (numok && numlvl < 1))
     opt.debug = 0;
   else if (!strcmp (debug_level, "basic") || (numok && numlvl <= 2))
-    opt.debug = DBG_ASSUAN_VALUE;
+    opt.debug = DBG_IPC_VALUE;
   else if (!strcmp (debug_level, "advanced") || (numok && numlvl <= 5))
-    opt.debug = (DBG_ASSUAN_VALUE|DBG_X509_VALUE|DBG_LOOKUP_VALUE);
+    opt.debug = (DBG_IPC_VALUE|DBG_X509_VALUE|DBG_LOOKUP_VALUE);
   else if (!strcmp (debug_level, "expert") || (numok && numlvl <= 8))
-    opt.debug = (DBG_ASSUAN_VALUE|DBG_X509_VALUE|DBG_LOOKUP_VALUE
+    opt.debug = (DBG_IPC_VALUE|DBG_X509_VALUE|DBG_LOOKUP_VALUE
                  |DBG_CACHE_VALUE|DBG_CRYPTO_VALUE);
   else if (!strcmp (debug_level, "guru") || numok)
     {
@@ -428,6 +462,23 @@ set_debug (void)
       gnutls_global_set_log_level (opt_gnutls_debug);
     }
 #endif /*HTTP_USE_GNUTLS*/
+
+  if (opt.debug)
+    parse_debug_flag (NULL, &opt.debug, debug_flags);
+}
+
+
+static void
+set_tor_mode (void)
+{
+  if (opt.use_tor)
+    {
+      if (assuan_sock_set_flag (ASSUAN_INVALID_FD, "tor-mode", 1))
+        {
+          log_error ("error enabling Tor mode: %s\n", strerror (errno));
+          log_info ("(is your Libassuan recent enough?)\n");
+        }
+    }
 }
 
 
@@ -445,7 +496,9 @@ wrong_args (const char *text)
 static void
 shutdown_reaper (void)
 {
+#if USE_LDAP
   ldap_wrapper_wait_connections ();
+#endif
 }
 
 
@@ -486,6 +539,8 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
         }
       FREE_STRLIST (opt.ignored_cert_extensions);
       http_register_tls_ca (NULL);
+      FREE_STRLIST (opt.keyserver);
+      /* Note: We do not allow resetting of opt.use_tor at runtime.  */
       return 1;
     }
 
@@ -493,7 +548,9 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
     {
     case oQuiet:   opt.quiet = 1; break;
     case oVerbose: opt.verbose++; break;
-    case oDebug:   opt.debug |= pargs->r.ret_ulong; break;
+    case oDebug:
+      parse_debug_flag (pargs->r.ret_str, &opt.debug, debug_flags);
+      break;
     case oDebugAll: opt.debug = ~0; break;
     case oDebugLevel: debug_level = pargs->r.ret_str; break;
     case oGnutlsDebug: opt_gnutls_debug = pargs->r.ret_int; break;
@@ -539,13 +596,37 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
     case oMaxReplies: opt.max_replies = pargs->r.ret_int; break;
 
     case oHkpCaCert:
-      http_register_tls_ca (pargs->r.ret_str);
+      {
+        char *tmpname;
+
+        /* Do tilde expansion and print a warning if the file can't be
+           accessed.  */
+        tmpname = make_absfilename_try (pargs->r.ret_str, NULL);
+        if (!tmpname || access (tmpname, F_OK))
+          log_info (_("can't access '%s': %s\n"),
+                    tmpname? tmpname : pargs->r.ret_str,
+                    gpg_strerror (gpg_error_from_syserror()));
+        else
+          http_register_tls_ca (tmpname);
+        xfree (tmpname);
+      }
       break;
 
     case oIgnoreCertExtension:
       add_to_strlist (&opt.ignored_cert_extensions, pargs->r.ret_str);
       break;
 
+    case oUseTor: opt.use_tor = 1; break;
+
+    case oKeyServer:
+      if (*pargs->r.ret_str)
+        add_to_strlist (&opt.keyserver, pargs->r.ret_str);
+      break;
+
+    case oNameServer:
+      set_dns_nameserver (pargs->r.ret_str);
+      break;
+
     default:
       return 0; /* Not handled. */
     }
@@ -596,6 +677,7 @@ pid_suffix_callback (unsigned long *r_suffix)
 {
   union int_and_ptr_u value;
 
+  memset (&value, 0, sizeof value);
   value.aptr = npth_getspecific (my_tlskey_current_fd);
   *r_suffix = value.aint;
   return (*r_suffix != -1);  /* Use decimal representation.  */
@@ -627,12 +709,16 @@ main (int argc, char **argv)
   int nodetach = 0;
   int csh_style = 0;
   char *logfile = NULL;
+#if USE_LDAP
   char *ldapfile = NULL;
+#endif /*USE_LDAP*/
   int debug_wait = 0;
   int rc;
   int homedir_seen = 0;
   struct assuan_malloc_hooks malloc_hooks;
 
+  early_system_init ();
+
 #ifdef USE_W32_SERVICE
   /* The option will be set by main() below if we should run as a
      system daemon.  */
@@ -709,9 +795,7 @@ main (int argc, char **argv)
   if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
     csh_style = 1;
 
-  opt.homedir = default_homedir ();
-
-  /* Now with NPth running we can set the logging callback.  Our
+    /* Now with NPth running we can set the logging callback.  Our
      windows implementation does not yet feature the NPth TLS
      functions.  */
 #ifndef HAVE_W32_SYSTEM
@@ -749,7 +833,7 @@ main (int argc, char **argv)
         default_config = 0; /* --no-options */
       else if (pargs.r_opt == oHomedir)
         {
-          opt.homedir = pargs.r.ret_str;
+          gnupg_set_homedir (pargs.r.ret_str);
           homedir_seen = 1;
         }
       else if (pargs.r_opt == aDaemon)
@@ -776,11 +860,10 @@ main (int argc, char **argv)
   if (opt.system_daemon && !homedir_seen)
     {
 #ifdef HAVE_W32CE_SYSTEM
-      opt.homedir = DIRSEP_S "gnupg";
+      gnupg_set_homedir (DIRSEP_S "gnupg");
 #else
-      opt.homedir = gnupg_sysconfdir ();
+      gnupg_set_homedir (gnupg_sysconfdir ());
 #endif
-      opt.homedir_data = gnupg_datadir ();
       opt.homedir_cache = gnupg_cachedir ();
       socket_name = dirmngr_sys_socket_name ();
     }
@@ -790,7 +873,7 @@ main (int argc, char **argv)
     socket_name = dirmngr_sys_socket_name ();
 
   if (default_config)
-    configname = make_filename (opt.homedir, DIRMNGR_NAME".conf", NULL );
+    configname = make_filename (gnupg_homedir (), DIRMNGR_NAME".conf", NULL );
 
   argc = orig_argc;
   argv = orig_argv;
@@ -847,9 +930,6 @@ main (int argc, char **argv)
         case oVerbose: opt.verbose++; break;
         case oBatch: opt.batch=1; break;
 
-        case oDebug: opt.debug |= pargs.r.ret_ulong; break;
-        case oDebugAll: opt.debug = ~0; break;
-        case oDebugLevel: debug_level = pargs.r.ret_str; break;
         case oDebugWait: debug_wait = pargs.r.ret_int; break;
 
         case oOptions:
@@ -869,7 +949,11 @@ main (int argc, char **argv)
         case oLogFile: logfile = pargs.r.ret_str; break;
         case oCsh: csh_style = 1; break;
         case oSh: csh_style = 0; break;
-       case oLDAPFile: ldapfile = pargs.r.ret_str; break;
+       case oLDAPFile:
+#        if USE_LDAP
+          ldapfile = pargs.r.ret_str;
+#        endif /*USE_LDAP*/
+          break;
        case oLDAPAddServers: opt.add_new_ldapservers = 1; break;
        case oLDAPTimeout:
          opt.ldaptimeout = pargs.r.ret_int;
@@ -902,10 +986,8 @@ main (int argc, char **argv)
   if (nogreeting )
     greeting = 0;
 
-  if (!opt.homedir_data)
-    opt.homedir_data = opt.homedir;
   if (!opt.homedir_cache)
-    opt.homedir_cache = opt.homedir;
+    opt.homedir_cache = xstrdup (gnupg_homedir ());
 
   if (greeting)
     {
@@ -918,6 +1000,13 @@ main (int argc, char **argv)
   log_info ("NOTE: this is a development version!\n");
 #endif
 
+  if (opt.use_tor)
+    {
+      log_info ("WARNING: ***************************************\n");
+      log_info ("WARNING: Tor mode (--use-tor) MAY NOT FULLY WORK!\n");
+      log_info ("WARNING: ***************************************\n");
+    }
+
   /* Print a warning if an argument looks like an option.  */
   if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
     {
@@ -928,7 +1017,8 @@ main (int argc, char **argv)
           log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
     }
 
-  if (!access ("/etc/"DIRMNGR_NAME, F_OK) && !strncmp (opt.homedir, "/etc/", 5))
+  if (!access ("/etc/"DIRMNGR_NAME, F_OK)
+      && !strncmp (gnupg_homedir (), "/etc/", 5))
     log_info
       ("NOTE: DirMngr is now a proper part of %s.  The configuration and"
        " other directory names changed.  Please check that no other version"
@@ -946,11 +1036,13 @@ main (int argc, char **argv)
     }
 
   set_debug ();
+  set_tor_mode ();
 
   /* Get LDAP server list from file. */
+#if USE_LDAP
   if (!ldapfile)
     {
-      ldapfile = make_filename (opt.homedir,
+      ldapfile = make_filename (gnupg_homedir (),
                                 opt.system_daemon?
                                 "ldapservers.conf":"dirmngr_ldapservers.conf",
                                 NULL);
@@ -959,6 +1051,7 @@ main (int argc, char **argv)
     }
   else
       opt.ldapservers = parse_ldapserver_file (ldapfile);
+#endif /*USE_LDAP*/
 
 #ifndef HAVE_W32_SYSTEM
   /* We need to ignore the PIPE signal because the we might log to a
@@ -995,7 +1088,10 @@ main (int argc, char **argv)
           log_debug ("... okay\n");
         }
 
+#if USE_LDAP
       ldap_wrapper_launch_thread ();
+#endif /*USE_LDAP*/
+
       cert_cache_init ();
       crl_cache_init ();
       start_command_handler (ASSUAN_INVALID_FD);
@@ -1015,9 +1111,9 @@ main (int argc, char **argv)
       if (logfile)
         {
           log_set_file (logfile);
-          log_set_prefix (NULL, (JNLIB_LOG_WITH_PREFIX
-                                 |JNLIB_LOG_WITH_TIME
-                                 |JNLIB_LOG_WITH_PID));
+          log_set_prefix (NULL, (GPGRT_LOG_WITH_PREFIX
+                                 |GPGRT_LOG_WITH_TIME
+                                 |GPGRT_LOG_WITH_PID));
           current_logfile = xstrdup (logfile);
         }
 
@@ -1028,12 +1124,6 @@ main (int argc, char **argv)
           dirmngr_exit (1);
         }
 #endif
-      if (strlen (socket_name)+1 >= sizeof serv_addr.sun_path )
-        {
-          log_error (_("name of socket too long\n"));
-          dirmngr_exit (1);
-        }
-
       fd = assuan_sock_new (AF_UNIX, SOCK_STREAM, 0);
       if (fd == ASSUAN_INVALID_FD)
         {
@@ -1042,9 +1132,30 @@ main (int argc, char **argv)
           dirmngr_exit (1);
         }
 
-      memset (&serv_addr, 0, sizeof serv_addr);
-      serv_addr.sun_family = AF_UNIX;
-      strcpy (serv_addr.sun_path, socket_name);
+      {
+        int redirected;
+
+        if (assuan_sock_set_sockaddr_un (socket_name,
+                                         (struct sockaddr*)&serv_addr,
+                                         &redirected))
+          {
+            if (errno == ENAMETOOLONG)
+              log_error (_("socket name '%s' is too long\n"), socket_name);
+            else
+              log_error ("error preparing socket '%s': %s\n",
+                         socket_name,
+                         gpg_strerror (gpg_error_from_syserror ()));
+            dirmngr_exit (1);
+          }
+        if (redirected)
+          {
+            redir_socket_name = xstrdup (serv_addr.sun_path);
+            if (opt.verbose)
+              log_info ("redirecting socket '%s' to '%s'\n",
+                        socket_name, redir_socket_name);
+          }
+      }
+
       len = SUN_LEN (&serv_addr);
 
       rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len);
@@ -1056,7 +1167,7 @@ main (int argc, char **argv)
               ))
        {
           /* Fixme: We should test whether a dirmngr is already running. */
-         gnupg_remove (socket_name);
+         gnupg_remove (redir_socket_name? redir_socket_name : socket_name);
          rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len);
        }
       if (rc != -1
@@ -1065,7 +1176,8 @@ main (int argc, char **argv)
       if (rc == -1)
         {
           log_error (_("error binding socket to '%s': %s\n"),
-                     serv_addr.sun_path, gpg_strerror (gpg_error_from_errno (errno)));
+                     serv_addr.sun_path,
+                     gpg_strerror (gpg_error_from_errno (errno)));
           assuan_sock_close (fd);
           dirmngr_exit (1);
         }
@@ -1079,7 +1191,7 @@ main (int argc, char **argv)
         }
 
       if (opt.verbose)
-        log_info (_("listening on socket '%s'\n"), socket_name );
+        log_info (_("listening on socket '%s'\n"), serv_addr.sun_path);
 
       es_fflush (NULL);
 
@@ -1113,7 +1225,7 @@ main (int argc, char **argv)
 
           /* Create the info string: <name>:<pid>:<protocol_version> */
           if (asprintf (&infostr, "%s=%s:%lu:1",
-                        DIRMNGR_INFO_NAME, socket_name, (ulong)pid ) < 0)
+                        DIRMNGR_INFO_NAME, serv_addr.sun_path, (ulong)pid ) < 0)
             {
               log_error (_("out of core\n"));
               kill (pid, SIGTERM);
@@ -1159,7 +1271,7 @@ main (int argc, char **argv)
             }
 
           log_get_prefix (&oldflags);
-          log_set_prefix (NULL, oldflags | JNLIB_LOG_RUN_DETACHED);
+          log_set_prefix (NULL, oldflags | GPGRT_LOG_RUN_DETACHED);
           opt.running_detached = 1;
 
           if (chdir("/"))
@@ -1170,7 +1282,10 @@ main (int argc, char **argv)
         }
 #endif
 
+#if USE_LDAP
       ldap_wrapper_launch_thread ();
+#endif /*USE_LDAP*/
+
       cert_cache_init ();
       crl_cache_init ();
 #ifdef USE_W32_SERVICE
@@ -1196,7 +1311,9 @@ main (int argc, char **argv)
       /* Just list the CRL cache and exit. */
       if (argc)
         wrong_args ("--list-crls");
+#if USE_LDAP
       ldap_wrapper_launch_thread ();
+#endif /*USE_LDAP*/
       crl_cache_init ();
       crl_cache_list (es_stdout);
     }
@@ -1207,7 +1324,9 @@ main (int argc, char **argv)
       memset (&ctrlbuf, 0, sizeof ctrlbuf);
       dirmngr_init_default_ctrl (&ctrlbuf);
 
+#if USE_LDAP
       ldap_wrapper_launch_thread ();
+#endif /*USE_LDAP*/
       cert_cache_init ();
       crl_cache_init ();
       if (!argc)
@@ -1217,6 +1336,7 @@ main (int argc, char **argv)
           for (; !rc && argc; argc--, argv++)
             rc = crl_cache_load (&ctrlbuf, *argv);
         }
+      dirmngr_deinit_default_ctrl (&ctrlbuf);
     }
   else if (cmd == aFetchCRL)
     {
@@ -1229,7 +1349,9 @@ main (int argc, char **argv)
       memset (&ctrlbuf, 0, sizeof ctrlbuf);
       dirmngr_init_default_ctrl (&ctrlbuf);
 
+#if USE_LDAP
       ldap_wrapper_launch_thread ();
+#endif /*USE_LDAP*/
       cert_cache_init ();
       crl_cache_init ();
       rc = crl_fetch (&ctrlbuf, argv[0], &reader);
@@ -1244,6 +1366,7 @@ main (int argc, char **argv)
                        argv[0], gpg_strerror (rc));
           crl_close_reader (reader);
         }
+      dirmngr_deinit_default_ctrl (&ctrlbuf);
     }
   else if (cmd == aFlush)
     {
@@ -1272,7 +1395,7 @@ main (int argc, char **argv)
       /* First the configuration file.  This is not an option, but it
         is vital information for GPG Conf.  */
       if (!opt.config_filename)
-        opt.config_filename = make_filename (opt.homedir,
+        opt.config_filename = make_filename (gnupg_homedir (),
                                              "dirmngr.conf", NULL );
 
       filename = percent_escape (opt.config_filename, NULL);
@@ -1292,7 +1415,7 @@ main (int argc, char **argv)
          and having both of them is thus problematic.  --no-detach is
          also only usable on the command line.  --batch is unused.  */
 
-      filename = make_filename (opt.homedir,
+      filename = make_filename (gnupg_homedir (),
                                 opt.system_daemon?
                                 "ldapservers.conf":"dirmngr_ldapservers.conf",
                                 NULL);
@@ -1325,6 +1448,9 @@ main (int argc, char **argv)
       /* Note: The next one is to fix a typo in gpgconf - should be
          removed eventually. */
       es_printf ("ignore-ocsp-servic-url:%lu:\n", flags | GC_OPT_FLAG_NONE);
+
+      es_printf ("use-tor:%lu:\n", flags | GC_OPT_FLAG_NONE);
+      es_printf ("keyserver:%lu:\n", flags | GC_OPT_FLAG_NONE);
     }
   cleanup ();
   return !!rc;
@@ -1376,13 +1502,17 @@ cleanup (void)
   crl_cache_deinit ();
   cert_cache_deinit (1);
 
+#if USE_LDAP
   ldapserver_list_free (opt.ldapservers);
+#endif /*USE_LDAP*/
   opt.ldapservers = NULL;
 
   if (cleanup_socket)
     {
       cleanup_socket = 0;
-      if (socket_name && *socket_name)
+      if (redir_socket_name)
+        gnupg_remove (redir_socket_name);
+      else if (socket_name && *socket_name)
         gnupg_remove (socket_name);
     }
 }
@@ -1399,9 +1529,18 @@ dirmngr_exit (int rc)
 void
 dirmngr_init_default_ctrl (ctrl_t ctrl)
 {
-  (void)ctrl;
+  if (opt.http_proxy)
+    ctrl->http_proxy = xstrdup (opt.http_proxy);
+}
+
 
-  /* Nothing for now. */
+void
+dirmngr_deinit_default_ctrl (ctrl_t ctrl)
+{
+  if (!ctrl)
+    return;
+  xfree (ctrl->http_proxy);
+  ctrl->http_proxy = NULL;
 }
 
 
@@ -1419,6 +1558,7 @@ dirmngr_init_default_ctrl (ctrl_t ctrl)
    5. field: Base DN
 
 */
+#if USE_LDAP
 static ldap_server_t
 parse_ldapserver_file (const char* filename)
 {
@@ -1475,7 +1615,7 @@ parse_ldapserver_file (const char* filename)
 
   return serverstart;
 }
-
+#endif /*USE_LDAP*/
 
 static fingerprint_list_t
 parse_ocsp_signer (const char *string)
@@ -1517,7 +1657,7 @@ parse_ocsp_signer (const char *string)
     {
       if (string[0] == '.' && string[1] == '/' )
         string += 2;
-      fname = make_filename (opt.homedir, string, NULL);
+      fname = make_filename (gnupg_homedir (), string, NULL);
     }
 
   fp = es_fopen (fname, "r");
@@ -1651,6 +1791,7 @@ reread_configuration (void)
   fclose (fp);
 
   set_debug ();
+  set_tor_mode ();
 }
 
 
@@ -1748,7 +1889,7 @@ housekeeping_thread (void *arg)
 }
 
 
-#if JNLIB_GCC_HAVE_PUSH_PRAGMA
+#if GPGRT_GCC_HAVE_PUSH_PRAGMA
 # pragma GCC push_options
 # pragma GCC optimize ("no-strict-overflow")
 #endif
@@ -1768,7 +1909,7 @@ time_for_housekeeping_p (time_t curtime)
     }
   return 0;
 }
-#if JNLIB_GCC_HAVE_PUSH_PRAGMA
+#if GPGRT_GCC_HAVE_PUSH_PRAGMA
 # pragma GCC pop_options
 #endif
 
@@ -1814,8 +1955,8 @@ handle_tick (void)
 }
 
 
-/* Check the nonce on a new connection.  This is a NOP unless we we
-   are using our Unix domain socket emulation under Windows.  */
+/* Check the nonce on a new connection.  This is a NOP unless we are
+   using our Unix domain socket emulation under Windows.  */
 static int
 check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce)
 {
@@ -1831,13 +1972,14 @@ check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce)
 }
 
 
-/* Helper to call a connection's main fucntion. */
+/* Helper to call a connection's main function. */
 static void *
 start_connection_thread (void *arg)
 {
   union int_and_ptr_u argval;
   gnupg_fd_t fd;
 
+  memset (&argval, 0, sizeof argval);
   argval.aptr = arg;
   fd = argval.afd;
 
@@ -1977,12 +2119,14 @@ handle_connections (assuan_fd_t listen_fd)
               union int_and_ptr_u argval;
              npth_t thread;
 
+              memset (&argval, 0, sizeof argval);
               argval.afd = fd;
               snprintf (threadname, sizeof threadname-1,
                         "conn fd=%d", FD2INT(fd));
               threadname[sizeof threadname -1] = 0;
 
-              ret = npth_create (&thread, &tattr, start_connection_thread, argval.aptr);
+              ret = npth_create (&thread, &tattr,
+                                 start_connection_thread, argval.aptr);
              if (ret)
                 {
                   log_error ("error spawning connection handler: %s\n",