LCOV - code coverage report
Current view: top level - dirmngr - dirmngr.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 862 0.0 %
Date: 2016-11-29 15:00:56 Functions: 0 36 0.0 %

          Line data    Source code
       1             : /* dirmngr.c - Keyserver and X.509 LDAP access
       2             :  * Copyright (C) 2002 Klarälvdalens Datakonsult AB
       3             :  * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2010, 2011 g10 Code GmbH
       4             :  * Copyright (C) 2014 Werner Koch
       5             :  *
       6             :  * This file is part of GnuPG.
       7             :  *
       8             :  * GnuPG is free software; you can redistribute it and/or modify
       9             :  * it under the terms of the GNU General Public License as published by
      10             :  * the Free Software Foundation; either version 3 of the License, or
      11             :  * (at your option) any later version.
      12             :  *
      13             :  * GnuPG is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :  * GNU General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU General Public License
      19             :  * along with this program; if not, see <https://www.gnu.org/licenses/>.
      20             :  */
      21             : 
      22             : #include <config.h>
      23             : 
      24             : #include <stdio.h>
      25             : #include <stdlib.h>
      26             : #include <stddef.h>
      27             : #include <stdarg.h>
      28             : #include <string.h>
      29             : #include <errno.h>
      30             : #include <assert.h>
      31             : #include <time.h>
      32             : #include <fcntl.h>
      33             : #ifndef HAVE_W32_SYSTEM
      34             : #include <sys/socket.h>
      35             : #include <sys/un.h>
      36             : #endif
      37             : #include <sys/stat.h>
      38             : #include <unistd.h>
      39             : #ifdef HAVE_SIGNAL_H
      40             : # include <signal.h>
      41             : #endif
      42             : #ifdef HAVE_INOTIFY_INIT
      43             : # include <sys/inotify.h>
      44             : #endif /*HAVE_INOTIFY_INIT*/
      45             : #include <npth.h>
      46             : 
      47             : #include "dirmngr-err.h"
      48             : 
      49             : #if  HTTP_USE_NTBTLS
      50             : # include <ntbtls.h>
      51             : #elif HTTP_USE_GNUTLS
      52             : # include <gnutls/gnutls.h>
      53             : #endif /*HTTP_USE_GNUTLS*/
      54             : 
      55             : 
      56             : #define GNUPG_COMMON_NEED_AFLOCAL
      57             : #include "dirmngr.h"
      58             : 
      59             : #include <assuan.h>
      60             : 
      61             : #include "certcache.h"
      62             : #include "crlcache.h"
      63             : #include "crlfetch.h"
      64             : #include "misc.h"
      65             : #if USE_LDAP
      66             : # include "ldapserver.h"
      67             : #endif
      68             : #include "asshelp.h"
      69             : #if USE_LDAP
      70             : # include "ldap-wrapper.h"
      71             : #endif
      72             : #include "../common/init.h"
      73             : #include "gc-opt-flags.h"
      74             : #include "dns-stuff.h"
      75             : 
      76             : #ifndef ENAMETOOLONG
      77             : # define ENAMETOOLONG EINVAL
      78             : #endif
      79             : 
      80             : 
      81             : enum cmd_and_opt_values {
      82             :   aNull = 0,
      83             :   oCsh            = 'c',
      84             :   oQuiet          = 'q',
      85             :   oSh             = 's',
      86             :   oVerbose        = 'v',
      87             :   oNoVerbose = 500,
      88             : 
      89             :   aServer,
      90             :   aDaemon,
      91             :   aSupervised,
      92             :   aListCRLs,
      93             :   aLoadCRL,
      94             :   aFetchCRL,
      95             :   aShutdown,
      96             :   aFlush,
      97             :   aGPGConfList,
      98             :   aGPGConfTest,
      99             : 
     100             :   oOptions,
     101             :   oDebug,
     102             :   oDebugAll,
     103             :   oDebugWait,
     104             :   oDebugLevel,
     105             :   oGnutlsDebug,
     106             :   oNoGreeting,
     107             :   oNoOptions,
     108             :   oHomedir,
     109             :   oNoDetach,
     110             :   oLogFile,
     111             :   oBatch,
     112             :   oDisableHTTP,
     113             :   oDisableLDAP,
     114             :   oIgnoreLDAPDP,
     115             :   oIgnoreHTTPDP,
     116             :   oIgnoreOCSPSvcUrl,
     117             :   oHonorHTTPProxy,
     118             :   oHTTPProxy,
     119             :   oLDAPProxy,
     120             :   oOnlyLDAPProxy,
     121             :   oLDAPFile,
     122             :   oLDAPTimeout,
     123             :   oLDAPAddServers,
     124             :   oOCSPResponder,
     125             :   oOCSPSigner,
     126             :   oOCSPMaxClockSkew,
     127             :   oOCSPMaxPeriod,
     128             :   oOCSPCurrentPeriod,
     129             :   oMaxReplies,
     130             :   oHkpCaCert,
     131             :   oFakedSystemTime,
     132             :   oForce,
     133             :   oAllowOCSP,
     134             :   oAllowVersionCheck,
     135             :   oSocketName,
     136             :   oLDAPWrapperProgram,
     137             :   oHTTPWrapperProgram,
     138             :   oIgnoreCertExtension,
     139             :   oUseTor,
     140             :   oKeyServer,
     141             :   oNameServer,
     142             :   oDisableCheckOwnSocket,
     143             :   aTest
     144             : };
     145             : 
     146             : 
     147             : 
     148             : static ARGPARSE_OPTS opts[] = {
     149             : 
     150             :   ARGPARSE_group (300, N_("@Commands:\n ")),
     151             : 
     152             :   ARGPARSE_c (aServer,   "server",  N_("run in server mode (foreground)") ),
     153             :   ARGPARSE_c (aDaemon,   "daemon",  N_("run in daemon mode (background)") ),
     154             : #ifndef HAVE_W32_SYSTEM
     155             :   ARGPARSE_c (aSupervised,  "supervised", N_("run in supervised mode")),
     156             : #endif
     157             :   ARGPARSE_c (aListCRLs, "list-crls", N_("list the contents of the CRL cache")),
     158             :   ARGPARSE_c (aLoadCRL,  "load-crl",  N_("|FILE|load CRL from FILE into cache")),
     159             :   ARGPARSE_c (aFetchCRL, "fetch-crl", N_("|URL|fetch a CRL from URL")),
     160             :   ARGPARSE_c (aShutdown, "shutdown",  N_("shutdown the dirmngr")),
     161             :   ARGPARSE_c (aFlush,    "flush",     N_("flush the cache")),
     162             :   ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"),
     163             :   ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"),
     164             : 
     165             :   ARGPARSE_group (301, N_("@\nOptions:\n ")),
     166             : 
     167             :   ARGPARSE_s_n (oVerbose,  "verbose",   N_("verbose")),
     168             :   ARGPARSE_s_n (oQuiet,    "quiet",     N_("be somewhat more quiet")),
     169             :   ARGPARSE_s_n (oSh,       "sh",        N_("sh-style command output")),
     170             :   ARGPARSE_s_n (oCsh,      "csh",       N_("csh-style command output")),
     171             :   ARGPARSE_s_s (oOptions,  "options",   N_("|FILE|read options from FILE")),
     172             :   ARGPARSE_s_s (oDebugLevel, "debug-level",
     173             :                 N_("|LEVEL|set the debugging level to LEVEL")),
     174             :   ARGPARSE_s_n (oNoDetach, "no-detach", N_("do not detach from the console")),
     175             :   ARGPARSE_s_s (oLogFile,  "log-file",
     176             :                 N_("|FILE|write server mode logs to FILE")),
     177             :   ARGPARSE_s_n (oBatch,    "batch",       N_("run without asking a user")),
     178             :   ARGPARSE_s_n (oForce,    "force",       N_("force loading of outdated CRLs")),
     179             :   ARGPARSE_s_n (oAllowOCSP, "allow-ocsp", N_("allow sending OCSP requests")),
     180             :   ARGPARSE_s_n (oAllowVersionCheck, "allow-version-check",
     181             :                 N_("allow online software version check")),
     182             :   ARGPARSE_s_n (oDisableHTTP, "disable-http", N_("inhibit the use of HTTP")),
     183             :   ARGPARSE_s_n (oDisableLDAP, "disable-ldap", N_("inhibit the use of LDAP")),
     184             :   ARGPARSE_s_n (oIgnoreHTTPDP,"ignore-http-dp",
     185             :                 N_("ignore HTTP CRL distribution points")),
     186             :   ARGPARSE_s_n (oIgnoreLDAPDP,"ignore-ldap-dp",
     187             :                 N_("ignore LDAP CRL distribution points")),
     188             :   ARGPARSE_s_n (oIgnoreOCSPSvcUrl, "ignore-ocsp-service-url",
     189             :                 N_("ignore certificate contained OCSP service URLs")),
     190             : 
     191             :   ARGPARSE_s_s (oHTTPProxy,  "http-proxy",
     192             :                 N_("|URL|redirect all HTTP requests to URL")),
     193             :   ARGPARSE_s_s (oLDAPProxy,  "ldap-proxy",
     194             :                 N_("|HOST|use HOST for LDAP queries")),
     195             :   ARGPARSE_s_n (oOnlyLDAPProxy, "only-ldap-proxy",
     196             :                 N_("do not use fallback hosts with --ldap-proxy")),
     197             : 
     198             :   ARGPARSE_s_s (oLDAPFile, "ldapserverlist-file",
     199             :                 N_("|FILE|read LDAP server list from FILE")),
     200             :   ARGPARSE_s_n (oLDAPAddServers, "add-servers",
     201             :                 N_("add new servers discovered in CRL distribution"
     202             :                    " points to serverlist")),
     203             :   ARGPARSE_s_i (oLDAPTimeout, "ldaptimeout",
     204             :                 N_("|N|set LDAP timeout to N seconds")),
     205             : 
     206             :   ARGPARSE_s_s (oOCSPResponder, "ocsp-responder",
     207             :                 N_("|URL|use OCSP responder at URL")),
     208             :   ARGPARSE_s_s (oOCSPSigner, "ocsp-signer",
     209             :                 N_("|FPR|OCSP response signed by FPR")),
     210             :   ARGPARSE_s_i (oOCSPMaxClockSkew, "ocsp-max-clock-skew", "@"),
     211             :   ARGPARSE_s_i (oOCSPMaxPeriod,    "ocsp-max-period", "@"),
     212             :   ARGPARSE_s_i (oOCSPCurrentPeriod, "ocsp-current-period", "@"),
     213             : 
     214             :   ARGPARSE_s_i (oMaxReplies, "max-replies",
     215             :                 N_("|N|do not return more than N items in one query")),
     216             : 
     217             :   ARGPARSE_s_s (oNameServer, "nameserver", "@"),
     218             :   ARGPARSE_s_s (oKeyServer, "keyserver", "@"),
     219             :   ARGPARSE_s_s (oHkpCaCert, "hkp-cacert",
     220             :                 N_("|FILE|use the CA certificates in FILE for HKP over TLS")),
     221             : 
     222             :   ARGPARSE_s_n (oUseTor, "use-tor", N_("route all network traffic via Tor")),
     223             : 
     224             :   ARGPARSE_s_s (oSocketName, "socket-name", "@"),  /* Only for debugging.  */
     225             : 
     226             :   ARGPARSE_s_u (oFakedSystemTime, "faked-system-time", "@"), /*(epoch time)*/
     227             :   ARGPARSE_s_s (oDebug,    "debug", "@"),
     228             :   ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
     229             :   ARGPARSE_s_i (oGnutlsDebug, "gnutls-debug", "@"),
     230             :   ARGPARSE_s_i (oGnutlsDebug, "tls-debug", "@"),
     231             :   ARGPARSE_s_i (oDebugWait, "debug-wait", "@"),
     232             :   ARGPARSE_s_n (oDisableCheckOwnSocket, "disable-check-own-socket", "@"),
     233             :   ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"),
     234             :   ARGPARSE_s_s (oHomedir, "homedir", "@"),
     235             :   ARGPARSE_s_s (oLDAPWrapperProgram, "ldap-wrapper-program", "@"),
     236             :   ARGPARSE_s_s (oHTTPWrapperProgram, "http-wrapper-program", "@"),
     237             :   ARGPARSE_s_n (oHonorHTTPProxy, "honor-http-proxy", "@"),
     238             :   ARGPARSE_s_s (oIgnoreCertExtension,"ignore-cert-extension", "@"),
     239             : 
     240             :   ARGPARSE_group (302,N_("@\n(See the \"info\" manual for a complete listing "
     241             :                          "of all commands and options)\n")),
     242             : 
     243             :   ARGPARSE_end ()
     244             : };
     245             : 
     246             : /* The list of supported debug flags.  */
     247             : static struct debug_flags_s debug_flags [] =
     248             :   {
     249             :     { DBG_X509_VALUE   , "x509"    },
     250             :     { DBG_CRYPTO_VALUE , "crypto"  },
     251             :     { DBG_MEMORY_VALUE , "memory"  },
     252             :     { DBG_CACHE_VALUE  , "cache"   },
     253             :     { DBG_MEMSTAT_VALUE, "memstat" },
     254             :     { DBG_HASHING_VALUE, "hashing" },
     255             :     { DBG_IPC_VALUE    , "ipc"     },
     256             :     { DBG_LOOKUP_VALUE , "lookup"  },
     257             :     { 77, NULL } /* 77 := Do not exit on "help" or "?".  */
     258             :   };
     259             : 
     260             : #define DEFAULT_MAX_REPLIES 10
     261             : #define DEFAULT_LDAP_TIMEOUT 100 /* arbitrary large timeout */
     262             : 
     263             : /* For the cleanup handler we need to keep track of the socket's name.  */
     264             : static const char *socket_name;
     265             : /* If the socket has been redirected, this is the name of the
     266             :    redirected socket..  */
     267             : static const char *redir_socket_name;
     268             : 
     269             : /* We need to keep track of the server's nonces (these are dummies for
     270             :    POSIX systems). */
     271             : static assuan_sock_nonce_t socket_nonce;
     272             : 
     273             : /* Only if this flag has been set will we remove the socket file.  */
     274             : static int cleanup_socket;
     275             : 
     276             : /* Keep track of the current log file so that we can avoid updating
     277             :    the log file after a SIGHUP if it didn't changed. Malloced. */
     278             : static char *current_logfile;
     279             : 
     280             : /* Helper to implement --debug-level. */
     281             : static const char *debug_level;
     282             : 
     283             : /* Helper to set the NTBTLS or GNUTLS log level.  */
     284             : static int opt_gnutls_debug = -1;
     285             : 
     286             : /* Flag indicating that a shutdown has been requested.  */
     287             : static volatile int shutdown_pending;
     288             : 
     289             : /* Flags to indicate that we shall not watch our own socket. */
     290             : static int disable_check_own_socket;
     291             : 
     292             : /* Counter for the active connections.  */
     293             : static int active_connections;
     294             : 
     295             : /* This flag is set by any network access and used by the housekeeping
     296             :  * thread to run background network tasks.  */
     297             : static int network_activity_seen;
     298             : 
     299             : /* The timer tick used for housekeeping stuff.  */
     300             : #define TIMERTICK_INTERVAL         (60)
     301             : 
     302             : /* How oft to run the housekeeping.  */
     303             : #define HOUSEKEEPING_INTERVAL      (600)
     304             : 
     305             : 
     306             : /* This union is used to avoid compiler warnings in case a pointer is
     307             :    64 bit and an int 32 bit.  We store an integer in a pointer and get
     308             :    it back later (npth_getspecific et al.).  */
     309             : union int_and_ptr_u
     310             : {
     311             :   int  aint;
     312             :   assuan_fd_t afd;
     313             :   void *aptr;
     314             : };
     315             : 
     316             : 
     317             : 
     318             : /* The key used to store the current file descriptor in the thread
     319             :    local storage.  We use this in conjunction with the
     320             :    log_set_pid_suffix_cb feature.  */
     321             : #ifndef HAVE_W32_SYSTEM
     322             : static int my_tlskey_current_fd;
     323             : #endif
     324             : 
     325             : /* Prototypes. */
     326             : static void cleanup (void);
     327             : #if USE_LDAP
     328             : static ldap_server_t parse_ldapserver_file (const char* filename);
     329             : #endif /*USE_LDAP*/
     330             : static fingerprint_list_t parse_ocsp_signer (const char *string);
     331             : static void netactivity_action (void);
     332             : static void handle_connections (assuan_fd_t listen_fd);
     333             : 
     334             : /* NPth wrapper function definitions. */
     335           0 : ASSUAN_SYSTEM_NPTH_IMPL;
     336             : 
     337             : static const char *
     338           0 : my_strusage( int level )
     339             : {
     340             :   const char *p;
     341           0 :   switch ( level )
     342             :     {
     343           0 :     case 11: p = "@DIRMNGR@ (@GNUPG@)";
     344           0 :       break;
     345           0 :     case 13: p = VERSION; break;
     346           0 :     case 17: p = PRINTABLE_OS_NAME; break;
     347             :       /* TRANSLATORS: @EMAIL@ will get replaced by the actual bug
     348             :          reporting address.  This is so that we can change the
     349             :          reporting address without breaking the translations.  */
     350           0 :     case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
     351           0 :     case 49: p = PACKAGE_BUGREPORT; break;
     352             :     case 1:
     353           0 :     case 40: p = _("Usage: @DIRMNGR@ [options] (-h for help)");
     354           0 :       break;
     355           0 :     case 41: p = _("Syntax: @DIRMNGR@ [options] [command [args]]\n"
     356             :                    "Keyserver, CRL, and OCSP access for @GNUPG@\n");
     357           0 :       break;
     358             : 
     359           0 :     default: p = NULL;
     360             :     }
     361           0 :   return p;
     362             : }
     363             : 
     364             : 
     365             : /* Callback from libksba to hash a provided buffer.  Our current
     366             :    implementation does only allow SHA-1 for hashing. This may be
     367             :    extended by mapping the name, testing for algorithm availibility
     368             :    and adjust the length checks accordingly. */
     369             : static gpg_error_t
     370           0 : my_ksba_hash_buffer (void *arg, const char *oid,
     371             :                      const void *buffer, size_t length, size_t resultsize,
     372             :                      unsigned char *result, size_t *resultlen)
     373             : {
     374             :   (void)arg;
     375             : 
     376           0 :   if (oid && strcmp (oid, "1.3.14.3.2.26"))
     377           0 :     return gpg_error (GPG_ERR_NOT_SUPPORTED);
     378           0 :   if (resultsize < 20)
     379           0 :     return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
     380           0 :   gcry_md_hash_buffer (2, result, buffer, length);
     381           0 :   *resultlen = 20;
     382           0 :   return 0;
     383             : }
     384             : 
     385             : 
     386             : /* GNUTLS log function callback.  */
     387             : #ifdef HTTP_USE_GNUTLS
     388             : static void
     389           0 : my_gnutls_log (int level, const char *text)
     390             : {
     391             :   int n;
     392             : 
     393           0 :   n = strlen (text);
     394           0 :   while (n && text[n-1] == '\n')
     395           0 :     n--;
     396             : 
     397           0 :   log_debug ("gnutls:L%d: %.*s\n", level, n, text);
     398           0 : }
     399             : #endif /*HTTP_USE_GNUTLS*/
     400             : 
     401             : /* Setup the debugging.  With a LEVEL of NULL only the active debug
     402             :    flags are propagated to the subsystems.  With LEVEL set, a specific
     403             :    set of debug flags is set; thus overriding all flags already
     404             :    set. */
     405             : static void
     406           0 : set_debug (void)
     407             : {
     408           0 :   int numok = (debug_level && digitp (debug_level));
     409           0 :   int numlvl = numok? atoi (debug_level) : 0;
     410             : 
     411           0 :   if (!debug_level)
     412             :     ;
     413           0 :   else if (!strcmp (debug_level, "none") || (numok && numlvl < 1))
     414           0 :     opt.debug = 0;
     415           0 :   else if (!strcmp (debug_level, "basic") || (numok && numlvl <= 2))
     416           0 :     opt.debug = DBG_IPC_VALUE;
     417           0 :   else if (!strcmp (debug_level, "advanced") || (numok && numlvl <= 5))
     418           0 :     opt.debug = (DBG_IPC_VALUE|DBG_X509_VALUE|DBG_LOOKUP_VALUE);
     419           0 :   else if (!strcmp (debug_level, "expert") || (numok && numlvl <= 8))
     420           0 :     opt.debug = (DBG_IPC_VALUE|DBG_X509_VALUE|DBG_LOOKUP_VALUE
     421             :                  |DBG_CACHE_VALUE|DBG_CRYPTO_VALUE);
     422           0 :   else if (!strcmp (debug_level, "guru") || numok)
     423             :     {
     424           0 :       opt.debug = ~0;
     425             :       /* Unless the "guru" string has been used we don't want to allow
     426             :          hashing debugging.  The rationale is that people tend to
     427             :          select the highest debug value and would then clutter their
     428             :          disk with debug files which may reveal confidential data.  */
     429           0 :       if (numok)
     430           0 :         opt.debug &= ~(DBG_HASHING_VALUE);
     431             :     }
     432             :   else
     433             :     {
     434           0 :       log_error (_("invalid debug-level '%s' given\n"), debug_level);
     435           0 :       log_info (_("valid debug levels are: %s\n"),
     436             :                 "none, basic, advanced, expert, guru");
     437           0 :       opt.debug = 0; /* Reset debugging, so that prior debug
     438             :                         statements won't have an undesired effect. */
     439             :     }
     440             : 
     441             : 
     442           0 :   if (opt.debug && !opt.verbose)
     443             :     {
     444           0 :       opt.verbose = 1;
     445           0 :       gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
     446             :     }
     447           0 :   if (opt.debug && opt.quiet)
     448           0 :     opt.quiet = 0;
     449             : 
     450           0 :   if (opt.debug & DBG_CRYPTO_VALUE )
     451           0 :     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
     452             : 
     453             : #if HTTP_USE_NTBTLS
     454             :   if (opt_gnutls_debug >= 0)
     455             :     {
     456             :       ntbtls_set_debug (opt_gnutls_debug, NULL, NULL);
     457             :     }
     458             : #elif HTTP_USE_GNUTLS
     459           0 :   if (opt_gnutls_debug >= 0)
     460             :     {
     461           0 :       gnutls_global_set_log_function (my_gnutls_log);
     462           0 :       gnutls_global_set_log_level (opt_gnutls_debug);
     463             :     }
     464             : #endif /*HTTP_USE_GNUTLS*/
     465             : 
     466           0 :   if (opt.debug)
     467           0 :     parse_debug_flag (NULL, &opt.debug, debug_flags);
     468           0 : }
     469             : 
     470             : 
     471             : static void
     472           0 : set_tor_mode (void)
     473             : {
     474           0 :   if (opt.use_tor)
     475             :     {
     476           0 :       if (assuan_sock_set_flag (ASSUAN_INVALID_FD, "tor-mode", 1))
     477             :         {
     478           0 :           log_error ("error enabling Tor mode: %s\n", strerror (errno));
     479           0 :           log_info ("(is your Libassuan recent enough?)\n");
     480             :         }
     481             :     }
     482           0 : }
     483             : 
     484             : 
     485             : static void
     486           0 : wrong_args (const char *text)
     487             : {
     488           0 :   es_fprintf (es_stderr, _("usage: %s [options] "), DIRMNGR_NAME);
     489           0 :   es_fputs (text, es_stderr);
     490           0 :   es_putc ('\n', es_stderr);
     491           0 :   dirmngr_exit (2);
     492           0 : }
     493             : 
     494             : 
     495             : /* Helper to stop the reaper thread for the ldap wrapper.  */
     496             : static void
     497           0 : shutdown_reaper (void)
     498             : {
     499             : #if USE_LDAP
     500           0 :   ldap_wrapper_wait_connections ();
     501             : #endif
     502           0 : }
     503             : 
     504             : 
     505             : /* Handle options which are allowed to be reset after program start.
     506             :    Return true if the current option in PARGS could be handled and
     507             :    false if not.  As a special feature, passing a value of NULL for
     508             :    PARGS, resets the options to the default.  REREAD should be set
     509             :    true if it is not the initial option parsing. */
     510             : static int
     511           0 : parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
     512             : {
     513           0 :   if (!pargs)
     514             :     { /* Reset mode. */
     515           0 :       opt.quiet = 0;
     516           0 :       opt.verbose = 0;
     517           0 :       opt.debug = 0;
     518           0 :       opt.ldap_wrapper_program = NULL;
     519           0 :       opt.disable_http = 0;
     520           0 :       opt.disable_ldap = 0;
     521           0 :       opt.honor_http_proxy = 0;
     522           0 :       opt.http_proxy = NULL;
     523           0 :       opt.ldap_proxy = NULL;
     524           0 :       opt.only_ldap_proxy = 0;
     525           0 :       opt.ignore_http_dp = 0;
     526           0 :       opt.ignore_ldap_dp = 0;
     527           0 :       opt.ignore_ocsp_service_url = 0;
     528           0 :       opt.allow_ocsp = 0;
     529           0 :       opt.allow_version_check = 0;
     530           0 :       opt.ocsp_responder = NULL;
     531           0 :       opt.ocsp_max_clock_skew = 10 * 60;      /* 10 minutes.  */
     532           0 :       opt.ocsp_max_period = 90 * 86400;       /* 90 days.  */
     533           0 :       opt.ocsp_current_period = 3 * 60 * 60;  /* 3 hours. */
     534           0 :       opt.max_replies = DEFAULT_MAX_REPLIES;
     535           0 :       while (opt.ocsp_signer)
     536             :         {
     537           0 :           fingerprint_list_t tmp = opt.ocsp_signer->next;
     538           0 :           xfree (opt.ocsp_signer);
     539           0 :           opt.ocsp_signer = tmp;
     540             :         }
     541           0 :       FREE_STRLIST (opt.ignored_cert_extensions);
     542           0 :       http_register_tls_ca (NULL);
     543           0 :       FREE_STRLIST (opt.keyserver);
     544             :       /* Note: We do not allow resetting of opt.use_tor at runtime.  */
     545           0 :       disable_check_own_socket = 0;
     546           0 :       return 1;
     547             :     }
     548             : 
     549           0 :   switch (pargs->r_opt)
     550             :     {
     551           0 :     case oQuiet:   opt.quiet = 1; break;
     552           0 :     case oVerbose: opt.verbose++; break;
     553             :     case oDebug:
     554           0 :       parse_debug_flag (pargs->r.ret_str, &opt.debug, debug_flags);
     555           0 :       break;
     556           0 :     case oDebugAll: opt.debug = ~0; break;
     557           0 :     case oDebugLevel: debug_level = pargs->r.ret_str; break;
     558           0 :     case oGnutlsDebug: opt_gnutls_debug = pargs->r.ret_int; break;
     559             : 
     560             :     case oLogFile:
     561           0 :       if (!reread)
     562           0 :         return 0; /* Not handled. */
     563           0 :       if (!current_logfile || !pargs->r.ret_str
     564           0 :           || strcmp (current_logfile, pargs->r.ret_str))
     565             :         {
     566           0 :           log_set_file (pargs->r.ret_str);
     567           0 :           xfree (current_logfile);
     568           0 :           current_logfile = xtrystrdup (pargs->r.ret_str);
     569             :         }
     570           0 :       break;
     571             : 
     572           0 :     case oDisableCheckOwnSocket: disable_check_own_socket = 1; break;
     573             : 
     574             :     case oLDAPWrapperProgram:
     575           0 :       opt.ldap_wrapper_program = pargs->r.ret_str;
     576           0 :       break;
     577             :     case oHTTPWrapperProgram:
     578           0 :       opt.http_wrapper_program = pargs->r.ret_str;
     579           0 :       break;
     580             : 
     581           0 :     case oDisableHTTP: opt.disable_http = 1; break;
     582           0 :     case oDisableLDAP: opt.disable_ldap = 1; break;
     583           0 :     case oHonorHTTPProxy: opt.honor_http_proxy = 1; break;
     584           0 :     case oHTTPProxy: opt.http_proxy = pargs->r.ret_str; break;
     585           0 :     case oLDAPProxy: opt.ldap_proxy = pargs->r.ret_str; break;
     586           0 :     case oOnlyLDAPProxy: opt.only_ldap_proxy = 1; break;
     587           0 :     case oIgnoreHTTPDP: opt.ignore_http_dp = 1; break;
     588           0 :     case oIgnoreLDAPDP: opt.ignore_ldap_dp = 1; break;
     589           0 :     case oIgnoreOCSPSvcUrl: opt.ignore_ocsp_service_url = 1; break;
     590             : 
     591           0 :     case oAllowOCSP: opt.allow_ocsp = 1; break;
     592           0 :     case oAllowVersionCheck: opt.allow_version_check = 1; break;
     593           0 :     case oOCSPResponder: opt.ocsp_responder = pargs->r.ret_str; break;
     594             :     case oOCSPSigner:
     595           0 :       opt.ocsp_signer = parse_ocsp_signer (pargs->r.ret_str);
     596           0 :       break;
     597           0 :     case oOCSPMaxClockSkew: opt.ocsp_max_clock_skew = pargs->r.ret_int; break;
     598           0 :     case oOCSPMaxPeriod: opt.ocsp_max_period = pargs->r.ret_int; break;
     599           0 :     case oOCSPCurrentPeriod: opt.ocsp_current_period = pargs->r.ret_int; break;
     600             : 
     601           0 :     case oMaxReplies: opt.max_replies = pargs->r.ret_int; break;
     602             : 
     603             :     case oHkpCaCert:
     604             :       {
     605             :         char *tmpname;
     606             : 
     607             :         /* Do tilde expansion and make path absolute.  */
     608           0 :         tmpname = make_absfilename (pargs->r.ret_str, NULL);
     609           0 :         http_register_tls_ca (tmpname);
     610           0 :         xfree (tmpname);
     611             :       }
     612           0 :       break;
     613             : 
     614             :     case oIgnoreCertExtension:
     615           0 :       add_to_strlist (&opt.ignored_cert_extensions, pargs->r.ret_str);
     616           0 :       break;
     617             : 
     618           0 :     case oUseTor: opt.use_tor = 1; break;
     619             : 
     620             :     case oKeyServer:
     621           0 :       if (*pargs->r.ret_str)
     622           0 :         add_to_strlist (&opt.keyserver, pargs->r.ret_str);
     623           0 :       break;
     624             : 
     625             :     case oNameServer:
     626           0 :       set_dns_nameserver (pargs->r.ret_str);
     627           0 :       break;
     628             : 
     629             :     default:
     630           0 :       return 0; /* Not handled. */
     631             :     }
     632             : 
     633           0 :   return 1; /* Handled. */
     634             : }
     635             : 
     636             : 
     637             : #ifndef HAVE_W32_SYSTEM
     638             : static int
     639           0 : pid_suffix_callback (unsigned long *r_suffix)
     640             : {
     641             :   union int_and_ptr_u value;
     642             : 
     643           0 :   memset (&value, 0, sizeof value);
     644           0 :   value.aptr = npth_getspecific (my_tlskey_current_fd);
     645           0 :   *r_suffix = value.aint;
     646           0 :   return (*r_suffix != -1);  /* Use decimal representation.  */
     647             : }
     648             : #endif /*!HAVE_W32_SYSTEM*/
     649             : 
     650             : 
     651             : static void
     652           0 : thread_init (void)
     653             : {
     654           0 :   npth_init ();
     655           0 :   gpgrt_set_syscall_clamp (npth_unprotect, npth_protect);
     656             : 
     657             :   /* Now with NPth running we can set the logging callback.  Our
     658             :      windows implementation does not yet feature the NPth TLS
     659             :      functions.  */
     660             : #ifndef HAVE_W32_SYSTEM
     661           0 :   if (npth_key_create (&my_tlskey_current_fd, NULL) == 0)
     662           0 :     if (npth_setspecific (my_tlskey_current_fd, NULL) == 0)
     663           0 :       log_set_pid_suffix_cb (pid_suffix_callback);
     664             : #endif /*!HAVE_W32_SYSTEM*/
     665           0 : }
     666             : 
     667             : 
     668             : int
     669           0 : main (int argc, char **argv)
     670             : {
     671           0 :   enum cmd_and_opt_values cmd = 0;
     672             :   ARGPARSE_ARGS pargs;
     673             :   int orig_argc;
     674             :   char **orig_argv;
     675           0 :   FILE *configfp = NULL;
     676           0 :   char *configname = NULL;
     677             :   const char *shell;
     678             :   unsigned configlineno;
     679           0 :   int parse_debug = 0;
     680           0 :   int default_config =1;
     681           0 :   int greeting = 0;
     682           0 :   int nogreeting = 0;
     683           0 :   int nodetach = 0;
     684           0 :   int csh_style = 0;
     685           0 :   char *logfile = NULL;
     686             : #if USE_LDAP
     687           0 :   char *ldapfile = NULL;
     688             : #endif /*USE_LDAP*/
     689           0 :   int debug_wait = 0;
     690             :   int rc;
     691             :   struct assuan_malloc_hooks malloc_hooks;
     692             : 
     693           0 :   early_system_init ();
     694           0 :   set_strusage (my_strusage);
     695           0 :   log_set_prefix (DIRMNGR_NAME, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_PID);
     696             : 
     697             :   /* Make sure that our subsystems are ready.  */
     698           0 :   i18n_init ();
     699           0 :   init_common_subsystems (&argc, &argv);
     700             : 
     701           0 :   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
     702             : 
     703             :  /* Check that the libraries are suitable.  Do it here because
     704             :     the option parsing may need services of the libraries. */
     705           0 :   if (!ksba_check_version (NEED_KSBA_VERSION) )
     706           0 :     log_fatal( _("%s is too old (need %s, have %s)\n"), "libksba",
     707             :                NEED_KSBA_VERSION, ksba_check_version (NULL) );
     708             : 
     709           0 :   ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
     710           0 :   ksba_set_hash_buffer_function (my_ksba_hash_buffer, NULL);
     711             : 
     712             :   /* Init TLS library.  */
     713             : #if HTTP_USE_NTBTLS
     714             :   if (!ntbtls_check_version (NEED_NTBTLS_VERSION) )
     715             :     log_fatal( _("%s is too old (need %s, have %s)\n"), "ntbtls",
     716             :                NEED_NTBTLS_VERSION, ntbtls_check_version (NULL) );
     717             : #elif HTTP_USE_GNUTLS
     718           0 :   rc = gnutls_global_init ();
     719           0 :   if (rc)
     720           0 :     log_fatal ("gnutls_global_init failed: %s\n", gnutls_strerror (rc));
     721             : #endif /*HTTP_USE_GNUTLS*/
     722             : 
     723             :   /* Init Assuan. */
     724           0 :   malloc_hooks.malloc = gcry_malloc;
     725           0 :   malloc_hooks.realloc = gcry_realloc;
     726           0 :   malloc_hooks.free = gcry_free;
     727           0 :   assuan_set_malloc_hooks (&malloc_hooks);
     728           0 :   assuan_set_assuan_log_prefix (log_get_prefix (NULL));
     729           0 :   assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
     730           0 :   assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
     731           0 :   assuan_sock_init ();
     732           0 :   setup_libassuan_logging (&opt.debug, dirmngr_assuan_log_monitor);
     733             : 
     734           0 :   setup_libgcrypt_logging ();
     735             : 
     736             :   /* Setup defaults. */
     737           0 :   shell = getenv ("SHELL");
     738           0 :   if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
     739           0 :     csh_style = 1;
     740             : 
     741             :   /* Reset rereadable options to default values. */
     742           0 :   parse_rereadable_options (NULL, 0);
     743             : 
     744             :   /* LDAP defaults.  */
     745           0 :   opt.add_new_ldapservers = 0;
     746           0 :   opt.ldaptimeout = DEFAULT_LDAP_TIMEOUT;
     747             : 
     748             :   /* Other defaults.  */
     749             : 
     750             :   /* Check whether we have a config file given on the commandline */
     751           0 :   orig_argc = argc;
     752           0 :   orig_argv = argv;
     753           0 :   pargs.argc = &argc;
     754           0 :   pargs.argv = &argv;
     755           0 :   pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
     756           0 :   while (arg_parse( &pargs, opts))
     757             :     {
     758           0 :       if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
     759           0 :         parse_debug++;
     760           0 :       else if (pargs.r_opt == oOptions)
     761             :         { /* Yes there is one, so we do not try the default one, but
     762             :              read the option file when it is encountered at the
     763             :              commandline */
     764           0 :           default_config = 0;
     765             :         }
     766           0 :       else if (pargs.r_opt == oNoOptions)
     767           0 :         default_config = 0; /* --no-options */
     768           0 :       else if (pargs.r_opt == oHomedir)
     769             :         {
     770           0 :           gnupg_set_homedir (pargs.r.ret_str);
     771             :         }
     772             :     }
     773             : 
     774           0 :   socket_name = dirmngr_socket_name ();
     775           0 :   if (default_config)
     776           0 :     configname = make_filename (gnupg_homedir (), DIRMNGR_NAME".conf", NULL );
     777             : 
     778           0 :   argc = orig_argc;
     779           0 :   argv = orig_argv;
     780           0 :   pargs.argc = &argc;
     781           0 :   pargs.argv = &argv;
     782           0 :   pargs.flags= 1;  /* do not remove the args */
     783             :  next_pass:
     784           0 :   if (configname)
     785             :     {
     786           0 :       configlineno = 0;
     787           0 :       configfp = fopen (configname, "r");
     788           0 :       if (!configfp)
     789             :         {
     790           0 :           if (default_config)
     791             :             {
     792           0 :               if( parse_debug )
     793           0 :                 log_info (_("Note: no default option file '%s'\n"),
     794             :                           configname );
     795             :             }
     796             :           else
     797             :             {
     798           0 :               log_error (_("option file '%s': %s\n"),
     799           0 :                          configname, strerror(errno) );
     800           0 :               exit(2);
     801             :             }
     802           0 :           xfree (configname);
     803           0 :           configname = NULL;
     804             :         }
     805           0 :       if (parse_debug && configname )
     806           0 :         log_info (_("reading options from '%s'\n"), configname );
     807           0 :       default_config = 0;
     808             :     }
     809             : 
     810           0 :   while (optfile_parse( configfp, configname, &configlineno, &pargs, opts) )
     811             :     {
     812           0 :       if (parse_rereadable_options (&pargs, 0))
     813           0 :         continue; /* Already handled */
     814           0 :       switch (pargs.r_opt)
     815             :         {
     816             :         case aServer:
     817             :         case aDaemon:
     818             :         case aSupervised:
     819             :         case aShutdown:
     820             :         case aFlush:
     821             :         case aListCRLs:
     822             :         case aLoadCRL:
     823             :         case aFetchCRL:
     824             :         case aGPGConfList:
     825             :         case aGPGConfTest:
     826           0 :           cmd = pargs.r_opt;
     827           0 :           break;
     828             : 
     829           0 :         case oQuiet: opt.quiet = 1; break;
     830           0 :         case oVerbose: opt.verbose++; break;
     831           0 :         case oBatch: opt.batch=1; break;
     832             : 
     833           0 :         case oDebugWait: debug_wait = pargs.r.ret_int; break;
     834             : 
     835             :         case oOptions:
     836             :           /* Config files may not be nested (silently ignore them) */
     837           0 :           if (!configfp)
     838             :             {
     839           0 :                 xfree(configname);
     840           0 :                 configname = xstrdup(pargs.r.ret_str);
     841           0 :                 goto next_pass;
     842             :             }
     843           0 :           break;
     844           0 :         case oNoGreeting: nogreeting = 1; break;
     845           0 :         case oNoVerbose: opt.verbose = 0; break;
     846           0 :         case oNoOptions: break; /* no-options */
     847           0 :         case oHomedir: /* Ignore this option here. */; break;
     848           0 :         case oNoDetach: nodetach = 1; break;
     849           0 :         case oLogFile: logfile = pargs.r.ret_str; break;
     850           0 :         case oCsh: csh_style = 1; break;
     851           0 :         case oSh: csh_style = 0; break;
     852             :         case oLDAPFile:
     853             : #        if USE_LDAP
     854           0 :           ldapfile = pargs.r.ret_str;
     855             : #        endif /*USE_LDAP*/
     856           0 :           break;
     857           0 :         case oLDAPAddServers: opt.add_new_ldapservers = 1; break;
     858             :         case oLDAPTimeout:
     859           0 :           opt.ldaptimeout = pargs.r.ret_int;
     860           0 :           break;
     861             : 
     862             :         case oFakedSystemTime:
     863           0 :           gnupg_set_time ((time_t)pargs.r.ret_ulong, 0);
     864           0 :           break;
     865             : 
     866           0 :         case oForce: opt.force = 1; break;
     867             : 
     868           0 :         case oSocketName: socket_name = pargs.r.ret_str; break;
     869             : 
     870           0 :         default : pargs.err = configfp? 1:2; break;
     871             :         }
     872             :     }
     873           0 :   if (configfp)
     874             :     {
     875           0 :       fclose (configfp);
     876           0 :       configfp = NULL;
     877             :       /* Keep a copy of the name so that it can be read on SIGHUP. */
     878           0 :       opt.config_filename = configname;
     879           0 :       configname = NULL;
     880           0 :       goto next_pass;
     881             :     }
     882           0 :   xfree (configname);
     883           0 :   configname = NULL;
     884           0 :   if (log_get_errorcount(0))
     885           0 :     exit(2);
     886           0 :   if (nogreeting )
     887           0 :     greeting = 0;
     888             : 
     889           0 :   if (!opt.homedir_cache)
     890           0 :     opt.homedir_cache = xstrdup (gnupg_homedir ());
     891             : 
     892           0 :   if (greeting)
     893             :     {
     894           0 :       es_fprintf (es_stderr, "%s %s; %s\n",
     895             :                   strusage(11), strusage(13), strusage(14) );
     896           0 :       es_fprintf (es_stderr, "%s\n", strusage(15) );
     897             :     }
     898             : 
     899             : #ifdef IS_DEVELOPMENT_VERSION
     900             :   log_info ("NOTE: this is a development version!\n");
     901             : #endif
     902             : 
     903           0 :   if (opt.use_tor)
     904             :     {
     905           0 :       log_info ("WARNING: ***************************************\n");
     906           0 :       log_info ("WARNING: Tor mode (--use-tor) MAY NOT FULLY WORK!\n");
     907           0 :       log_info ("WARNING: ***************************************\n");
     908             :     }
     909             : 
     910             :   /* Print a warning if an argument looks like an option.  */
     911           0 :   if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
     912             :     {
     913             :       int i;
     914             : 
     915           0 :       for (i=0; i < argc; i++)
     916           0 :         if (argv[i][0] == '-' && argv[i][1] == '-')
     917           0 :           log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
     918             :     }
     919             : 
     920           0 :   if (!access ("/etc/"DIRMNGR_NAME, F_OK)
     921           0 :       && !strncmp (gnupg_homedir (), "/etc/", 5))
     922           0 :     log_info
     923             :       ("NOTE: DirMngr is now a proper part of %s.  The configuration and"
     924             :        " other directory names changed.  Please check that no other version"
     925             :        " of dirmngr is still installed.  To disable this warning, remove the"
     926             :        " directory '/etc/dirmngr'.\n", GNUPG_NAME);
     927             : 
     928           0 :   if (gnupg_faked_time_p ())
     929             :     {
     930             :       gnupg_isotime_t tbuf;
     931             : 
     932           0 :       log_info (_("WARNING: running with faked system time: "));
     933           0 :       gnupg_get_isotime (tbuf);
     934           0 :       dump_isotime (tbuf);
     935           0 :       log_printf ("\n");
     936             :     }
     937             : 
     938           0 :   set_debug ();
     939           0 :   set_tor_mode ();
     940             : 
     941             :   /* Get LDAP server list from file. */
     942             : #if USE_LDAP
     943           0 :   if (!ldapfile)
     944             :     {
     945           0 :       ldapfile = make_filename (gnupg_homedir (),
     946             :                                 "dirmngr_ldapservers.conf",
     947             :                                 NULL);
     948           0 :       opt.ldapservers = parse_ldapserver_file (ldapfile);
     949           0 :       xfree (ldapfile);
     950             :     }
     951             :   else
     952           0 :       opt.ldapservers = parse_ldapserver_file (ldapfile);
     953             : #endif /*USE_LDAP*/
     954             : 
     955             : #ifndef HAVE_W32_SYSTEM
     956             :   /* We need to ignore the PIPE signal because the we might log to a
     957             :      socket and that code handles EPIPE properly.  The ldap wrapper
     958             :      also requires us to ignore this silly signal. Assuan would set
     959             :      this signal to ignore anyway.*/
     960           0 :   signal (SIGPIPE, SIG_IGN);
     961             : #endif
     962             : 
     963             :   /* Ready.  Now to our duties. */
     964           0 :   if (!cmd)
     965           0 :     cmd = aServer;
     966           0 :   rc = 0;
     967             : 
     968           0 :   if (cmd == aServer)
     969             :     {
     970             :       /* Note that this server mode is mainly useful for debugging.  */
     971           0 :       if (argc)
     972           0 :         wrong_args ("--server");
     973             : 
     974           0 :       if (logfile)
     975             :         {
     976           0 :           log_set_file (logfile);
     977           0 :           log_set_prefix (NULL, GPGRT_LOG_WITH_TIME | GPGRT_LOG_WITH_PID);
     978             :         }
     979             : 
     980           0 :       if (debug_wait)
     981             :         {
     982           0 :           log_debug ("waiting for debugger - my pid is %u .....\n",
     983           0 :                      (unsigned int)getpid());
     984           0 :           gnupg_sleep (debug_wait);
     985           0 :           log_debug ("... okay\n");
     986             :         }
     987             : 
     988             : 
     989           0 :       thread_init ();
     990           0 :       cert_cache_init ();
     991           0 :       crl_cache_init ();
     992           0 :       http_register_netactivity_cb (netactivity_action);
     993           0 :       start_command_handler (ASSUAN_INVALID_FD);
     994           0 :       shutdown_reaper ();
     995             :     }
     996             : #ifndef HAVE_W32_SYSTEM
     997           0 :   else if (cmd == aSupervised)
     998             :     {
     999             :       /* In supervised mode, we expect file descriptor 3 to be an
    1000             :          already opened, listening socket.
    1001             : 
    1002             :          We will also not detach from the controlling process or close
    1003             :          stderr; the supervisor should handle all of that.  */
    1004             :       struct stat statbuf;
    1005           0 :       if (fstat (3, &statbuf) == -1 && errno == EBADF)
    1006             :         {
    1007           0 :           log_error ("file descriptor 3 must be validin --supervised mode\n");
    1008           0 :           dirmngr_exit (1);
    1009             :         }
    1010           0 :       socket_name = gnupg_get_socket_name (3);
    1011             : 
    1012             :       /* Now start with logging to a file if this is desired. */
    1013           0 :       if (logfile)
    1014             :         {
    1015           0 :           log_set_file (logfile);
    1016           0 :           log_set_prefix (NULL, (GPGRT_LOG_WITH_PREFIX
    1017             :                                  |GPGRT_LOG_WITH_TIME
    1018             :                                  |GPGRT_LOG_WITH_PID));
    1019           0 :           current_logfile = xstrdup (logfile);
    1020             :         }
    1021             :       else
    1022           0 :         log_set_prefix (NULL, 0);
    1023             : 
    1024           0 :       thread_init ();
    1025           0 :       cert_cache_init ();
    1026           0 :       crl_cache_init ();
    1027           0 :       http_register_netactivity_cb (netactivity_action);
    1028           0 :       handle_connections (3);
    1029           0 :       assuan_sock_close (3);
    1030           0 :       shutdown_reaper ();
    1031             :     }
    1032             : #endif /*HAVE_W32_SYSTEM*/
    1033           0 :   else if (cmd == aDaemon)
    1034             :     {
    1035             :       assuan_fd_t fd;
    1036             :       pid_t pid;
    1037             :       int len;
    1038             :       struct sockaddr_un serv_addr;
    1039             : 
    1040           0 :       if (argc)
    1041           0 :         wrong_args ("--daemon");
    1042             : 
    1043             :       /* Now start with logging to a file if this is desired. */
    1044           0 :       if (logfile)
    1045             :         {
    1046           0 :           log_set_file (logfile);
    1047           0 :           log_set_prefix (NULL, (GPGRT_LOG_WITH_PREFIX
    1048             :                                  |GPGRT_LOG_WITH_TIME
    1049             :                                  |GPGRT_LOG_WITH_PID));
    1050           0 :           current_logfile = xstrdup (logfile);
    1051             :         }
    1052             : 
    1053             : #ifndef HAVE_W32_SYSTEM
    1054           0 :       if (strchr (socket_name, ':'))
    1055             :         {
    1056           0 :           log_error (_("colons are not allowed in the socket name\n"));
    1057           0 :           dirmngr_exit (1);
    1058             :         }
    1059             : #endif
    1060           0 :       fd = assuan_sock_new (AF_UNIX, SOCK_STREAM, 0);
    1061           0 :       if (fd == ASSUAN_INVALID_FD)
    1062             :         {
    1063           0 :           log_error (_("can't create socket: %s\n"), strerror (errno));
    1064           0 :           cleanup ();
    1065           0 :           dirmngr_exit (1);
    1066             :         }
    1067             : 
    1068             :       {
    1069             :         int redirected;
    1070             : 
    1071           0 :         if (assuan_sock_set_sockaddr_un (socket_name,
    1072             :                                          (struct sockaddr*)&serv_addr,
    1073             :                                          &redirected))
    1074             :           {
    1075           0 :             if (errno == ENAMETOOLONG)
    1076           0 :               log_error (_("socket name '%s' is too long\n"), socket_name);
    1077             :             else
    1078           0 :               log_error ("error preparing socket '%s': %s\n",
    1079             :                          socket_name,
    1080             :                          gpg_strerror (gpg_error_from_syserror ()));
    1081           0 :             dirmngr_exit (1);
    1082             :           }
    1083           0 :         if (redirected)
    1084             :           {
    1085           0 :             redir_socket_name = xstrdup (serv_addr.sun_path);
    1086           0 :             if (opt.verbose)
    1087           0 :               log_info ("redirecting socket '%s' to '%s'\n",
    1088             :                         socket_name, redir_socket_name);
    1089             :           }
    1090             :       }
    1091             : 
    1092           0 :       len = SUN_LEN (&serv_addr);
    1093             : 
    1094           0 :       rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len);
    1095           0 :       if (rc == -1
    1096           0 :           && (errno == EADDRINUSE
    1097             : #ifdef HAVE_W32_SYSTEM
    1098             :               || errno == EEXIST
    1099             : #endif
    1100             :               ))
    1101             :         {
    1102             :           /* Fixme: We should test whether a dirmngr is already running. */
    1103           0 :           gnupg_remove (redir_socket_name? redir_socket_name : socket_name);
    1104           0 :           rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len);
    1105             :         }
    1106           0 :       if (rc != -1
    1107           0 :           && (rc = assuan_sock_get_nonce ((struct sockaddr*) &serv_addr, len, &socket_nonce)))
    1108           0 :         log_error (_("error getting nonce for the socket\n"));
    1109           0 :       if (rc == -1)
    1110             :         {
    1111           0 :           log_error (_("error binding socket to '%s': %s\n"),
    1112             :                      serv_addr.sun_path,
    1113           0 :                      gpg_strerror (gpg_error_from_errno (errno)));
    1114           0 :           assuan_sock_close (fd);
    1115           0 :           dirmngr_exit (1);
    1116             :         }
    1117           0 :       cleanup_socket = 1;
    1118             : 
    1119           0 :       if (gnupg_chmod (serv_addr.sun_path, "-rwx"))
    1120           0 :         log_error (_("can't set permissions of '%s': %s\n"),
    1121           0 :                    serv_addr.sun_path, strerror (errno));
    1122             : 
    1123           0 :       if (listen (FD2INT (fd), 5) == -1)
    1124             :         {
    1125           0 :           log_error (_("listen() failed: %s\n"), strerror (errno));
    1126           0 :           assuan_sock_close (fd);
    1127           0 :           dirmngr_exit (1);
    1128             :         }
    1129             : 
    1130           0 :       if (opt.verbose)
    1131           0 :         log_info (_("listening on socket '%s'\n"), serv_addr.sun_path);
    1132             : 
    1133           0 :       es_fflush (NULL);
    1134             : 
    1135             :       /* Note: We keep the dirmngr_info output only for the sake of
    1136             :          existing scripts which might use this to detect a successful
    1137             :          start of the dirmngr.  */
    1138             : #ifdef HAVE_W32_SYSTEM
    1139             :       (void)csh_style;
    1140             :       (void)nodetach;
    1141             : 
    1142             :       pid = getpid ();
    1143             :       es_printf ("set %s=%s;%lu;1\n",
    1144             :                  DIRMNGR_INFO_NAME, socket_name, (ulong) pid);
    1145             : #else
    1146           0 :       pid = fork();
    1147           0 :       if (pid == (pid_t)-1)
    1148             :         {
    1149           0 :           log_fatal (_("error forking process: %s\n"), strerror (errno));
    1150             :           dirmngr_exit (1);
    1151             :         }
    1152             : 
    1153           0 :       if (pid)
    1154             :         { /* We are the parent */
    1155             :           char *infostr;
    1156             : 
    1157             :           /* Don't let cleanup() remove the socket - the child is
    1158             :              responsible for doing that.  */
    1159           0 :           cleanup_socket = 0;
    1160             : 
    1161           0 :           close (fd);
    1162             : 
    1163             :           /* Create the info string: <name>:<pid>:<protocol_version> */
    1164           0 :           if (asprintf (&infostr, "%s=%s:%lu:1",
    1165             :                         DIRMNGR_INFO_NAME, serv_addr.sun_path, (ulong)pid ) < 0)
    1166             :             {
    1167           0 :               log_error (_("out of core\n"));
    1168           0 :               kill (pid, SIGTERM);
    1169           0 :               dirmngr_exit (1);
    1170             :             }
    1171             :           /* Print the environment string, so that the caller can use
    1172             :              shell's eval to set it.  But see above.  */
    1173           0 :           if (csh_style)
    1174             :             {
    1175           0 :               *strchr (infostr, '=') = ' ';
    1176           0 :               es_printf ( "setenv %s;\n", infostr);
    1177             :             }
    1178             :           else
    1179             :             {
    1180           0 :               es_printf ( "%s; export %s;\n", infostr, DIRMNGR_INFO_NAME);
    1181             :             }
    1182           0 :           free (infostr);
    1183           0 :           exit (0);
    1184             :           /*NEVER REACHED*/
    1185             :         } /* end parent */
    1186             : 
    1187             : 
    1188             :       /*
    1189             :          This is the child
    1190             :        */
    1191             : 
    1192             :       /* Detach from tty and put process into a new session */
    1193           0 :       if (!nodetach )
    1194             :         {
    1195             :           int i;
    1196             :           unsigned int oldflags;
    1197             : 
    1198             :           /* Close stdin, stdout and stderr unless it is the log stream */
    1199           0 :           for (i=0; i <= 2; i++)
    1200             :             {
    1201           0 :               if (!log_test_fd (i) && i != fd )
    1202             :                 {
    1203           0 :                   if ( !close (i)
    1204           0 :                        && open ("/dev/null", i? O_WRONLY : O_RDONLY) == -1)
    1205             :                     {
    1206           0 :                       log_error ("failed to open '%s': %s\n",
    1207           0 :                                  "/dev/null", strerror (errno));
    1208           0 :                       cleanup ();
    1209           0 :                       dirmngr_exit (1);
    1210             :                     }
    1211             :                 }
    1212             :             }
    1213             : 
    1214           0 :           if (setsid() == -1)
    1215             :             {
    1216           0 :               log_error ("setsid() failed: %s\n", strerror(errno) );
    1217           0 :               dirmngr_exit (1);
    1218             :             }
    1219             : 
    1220           0 :           log_get_prefix (&oldflags);
    1221           0 :           log_set_prefix (NULL, oldflags | GPGRT_LOG_RUN_DETACHED);
    1222           0 :           opt.running_detached = 1;
    1223             : 
    1224           0 :           if (chdir("/"))
    1225             :             {
    1226           0 :               log_error ("chdir to / failed: %s\n", strerror (errno));
    1227           0 :               dirmngr_exit (1);
    1228             :             }
    1229             :         }
    1230             : #endif
    1231             : 
    1232           0 :       thread_init ();
    1233           0 :       cert_cache_init ();
    1234           0 :       crl_cache_init ();
    1235           0 :       http_register_netactivity_cb (netactivity_action);
    1236           0 :       handle_connections (fd);
    1237           0 :       assuan_sock_close (fd);
    1238           0 :       shutdown_reaper ();
    1239             :     }
    1240           0 :   else if (cmd == aListCRLs)
    1241             :     {
    1242             :       /* Just list the CRL cache and exit. */
    1243           0 :       if (argc)
    1244           0 :         wrong_args ("--list-crls");
    1245           0 :       crl_cache_init ();
    1246           0 :       crl_cache_list (es_stdout);
    1247             :     }
    1248           0 :   else if (cmd == aLoadCRL)
    1249             :     {
    1250             :       struct server_control_s ctrlbuf;
    1251             : 
    1252           0 :       memset (&ctrlbuf, 0, sizeof ctrlbuf);
    1253           0 :       dirmngr_init_default_ctrl (&ctrlbuf);
    1254             : 
    1255           0 :       thread_init ();
    1256           0 :       cert_cache_init ();
    1257           0 :       crl_cache_init ();
    1258           0 :       if (!argc)
    1259           0 :         rc = crl_cache_load (&ctrlbuf, NULL);
    1260             :       else
    1261             :         {
    1262           0 :           for (; !rc && argc; argc--, argv++)
    1263           0 :             rc = crl_cache_load (&ctrlbuf, *argv);
    1264             :         }
    1265           0 :       dirmngr_deinit_default_ctrl (&ctrlbuf);
    1266             :     }
    1267           0 :   else if (cmd == aFetchCRL)
    1268             :     {
    1269             :       ksba_reader_t reader;
    1270             :       struct server_control_s ctrlbuf;
    1271             : 
    1272           0 :       if (argc != 1)
    1273           0 :         wrong_args ("--fetch-crl URL");
    1274             : 
    1275           0 :       memset (&ctrlbuf, 0, sizeof ctrlbuf);
    1276           0 :       dirmngr_init_default_ctrl (&ctrlbuf);
    1277             : 
    1278           0 :       thread_init ();
    1279           0 :       cert_cache_init ();
    1280           0 :       crl_cache_init ();
    1281           0 :       rc = crl_fetch (&ctrlbuf, argv[0], &reader);
    1282           0 :       if (rc)
    1283           0 :         log_error (_("fetching CRL from '%s' failed: %s\n"),
    1284             :                      argv[0], gpg_strerror (rc));
    1285             :       else
    1286             :         {
    1287           0 :           rc = crl_cache_insert (&ctrlbuf, argv[0], reader);
    1288           0 :           if (rc)
    1289           0 :             log_error (_("processing CRL from '%s' failed: %s\n"),
    1290             :                        argv[0], gpg_strerror (rc));
    1291           0 :           crl_close_reader (reader);
    1292             :         }
    1293           0 :       dirmngr_deinit_default_ctrl (&ctrlbuf);
    1294             :     }
    1295           0 :   else if (cmd == aFlush)
    1296             :     {
    1297             :       /* Delete cache and exit. */
    1298           0 :       if (argc)
    1299           0 :         wrong_args ("--flush");
    1300           0 :       rc = crl_cache_flush();
    1301             :     }
    1302           0 :   else if (cmd == aGPGConfTest)
    1303           0 :     dirmngr_exit (0);
    1304           0 :   else if (cmd == aGPGConfList)
    1305             :     {
    1306           0 :       unsigned long flags = 0;
    1307             :       char *filename;
    1308             :       char *filename_esc;
    1309             : 
    1310             :       /* First the configuration file.  This is not an option, but it
    1311             :          is vital information for GPG Conf.  */
    1312           0 :       if (!opt.config_filename)
    1313           0 :         opt.config_filename = make_filename (gnupg_homedir (),
    1314             :                                              "dirmngr.conf", NULL );
    1315             : 
    1316           0 :       filename = percent_escape (opt.config_filename, NULL);
    1317           0 :       es_printf ("gpgconf-dirmngr.conf:%lu:\"%s\n",
    1318             :               GC_OPT_FLAG_DEFAULT, filename);
    1319           0 :       xfree (filename);
    1320             : 
    1321           0 :       es_printf ("verbose:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1322           0 :       es_printf ("quiet:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1323           0 :       es_printf ("debug-level:%lu:\"none\n", flags | GC_OPT_FLAG_DEFAULT);
    1324           0 :       es_printf ("log-file:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1325           0 :       es_printf ("force:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1326             : 
    1327             :       /* --csh and --sh are mutually exclusive, something we can not
    1328             :          express in GPG Conf.  --options is only usable from the
    1329             :          command line, really.  --debug-all interacts with --debug,
    1330             :          and having both of them is thus problematic.  --no-detach is
    1331             :          also only usable on the command line.  --batch is unused.  */
    1332             : 
    1333           0 :       filename = make_filename (gnupg_homedir (),
    1334             :                                 "dirmngr_ldapservers.conf",
    1335             :                                 NULL);
    1336           0 :       filename_esc = percent_escape (filename, NULL);
    1337           0 :       es_printf ("ldapserverlist-file:%lu:\"%s\n", flags | GC_OPT_FLAG_DEFAULT,
    1338             :               filename_esc);
    1339           0 :       xfree (filename_esc);
    1340           0 :       xfree (filename);
    1341             : 
    1342           0 :       es_printf ("ldaptimeout:%lu:%u\n",
    1343             :               flags | GC_OPT_FLAG_DEFAULT, DEFAULT_LDAP_TIMEOUT);
    1344           0 :       es_printf ("max-replies:%lu:%u\n",
    1345             :               flags | GC_OPT_FLAG_DEFAULT, DEFAULT_MAX_REPLIES);
    1346           0 :       es_printf ("allow-ocsp:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1347           0 :       es_printf ("allow-version-check:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1348           0 :       es_printf ("ocsp-responder:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1349           0 :       es_printf ("ocsp-signer:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1350             : 
    1351           0 :       es_printf ("faked-system-time:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1352           0 :       es_printf ("no-greeting:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1353             : 
    1354           0 :       es_printf ("disable-http:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1355           0 :       es_printf ("disable-ldap:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1356           0 :       es_printf ("honor-http-proxy:%lu\n", flags | GC_OPT_FLAG_NONE);
    1357           0 :       es_printf ("http-proxy:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1358           0 :       es_printf ("ldap-proxy:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1359           0 :       es_printf ("only-ldap-proxy:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1360           0 :       es_printf ("ignore-ldap-dp:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1361           0 :       es_printf ("ignore-http-dp:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1362           0 :       es_printf ("ignore-ocsp-service-url:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1363             :       /* Note: The next one is to fix a typo in gpgconf - should be
    1364             :          removed eventually. */
    1365           0 :       es_printf ("ignore-ocsp-servic-url:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1366             : 
    1367           0 :       es_printf ("use-tor:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1368           0 :       es_printf ("keyserver:%lu:\n", flags | GC_OPT_FLAG_NONE);
    1369             :     }
    1370           0 :   cleanup ();
    1371           0 :   return !!rc;
    1372             : }
    1373             : 
    1374             : 
    1375             : static void
    1376           0 : cleanup (void)
    1377             : {
    1378           0 :   crl_cache_deinit ();
    1379           0 :   cert_cache_deinit (1);
    1380             : 
    1381             : #if USE_LDAP
    1382           0 :   ldapserver_list_free (opt.ldapservers);
    1383             : #endif /*USE_LDAP*/
    1384           0 :   opt.ldapservers = NULL;
    1385             : 
    1386           0 :   if (cleanup_socket)
    1387             :     {
    1388           0 :       cleanup_socket = 0;
    1389           0 :       if (redir_socket_name)
    1390           0 :         gnupg_remove (redir_socket_name);
    1391           0 :       else if (socket_name && *socket_name)
    1392           0 :         gnupg_remove (socket_name);
    1393             :     }
    1394           0 : }
    1395             : 
    1396             : 
    1397             : void
    1398           0 : dirmngr_exit (int rc)
    1399             : {
    1400           0 :   cleanup ();
    1401           0 :   exit (rc);
    1402             : }
    1403             : 
    1404             : 
    1405             : void
    1406           0 : dirmngr_init_default_ctrl (ctrl_t ctrl)
    1407             : {
    1408           0 :   if (opt.http_proxy)
    1409           0 :     ctrl->http_proxy = xstrdup (opt.http_proxy);
    1410           0 : }
    1411             : 
    1412             : 
    1413             : void
    1414           0 : dirmngr_deinit_default_ctrl (ctrl_t ctrl)
    1415             : {
    1416           0 :   if (!ctrl)
    1417           0 :     return;
    1418           0 :   xfree (ctrl->http_proxy);
    1419           0 :   ctrl->http_proxy = NULL;
    1420             : }
    1421             : 
    1422             : 
    1423             : /* Create a list of LDAP servers from the file FILENAME. Returns the
    1424             :    list or NULL in case of errors.
    1425             : 
    1426             :    The format fo such a file is line oriented where empty lines and
    1427             :    lines starting with a hash mark are ignored.  All other lines are
    1428             :    assumed to be colon seprated with these fields:
    1429             : 
    1430             :    1. field: Hostname
    1431             :    2. field: Portnumber
    1432             :    3. field: Username
    1433             :    4. field: Password
    1434             :    5. field: Base DN
    1435             : 
    1436             : */
    1437             : #if USE_LDAP
    1438             : static ldap_server_t
    1439           0 : parse_ldapserver_file (const char* filename)
    1440             : {
    1441             :   char buffer[1024];
    1442             :   char *p;
    1443             :   ldap_server_t server, serverstart, *serverend;
    1444             :   int c;
    1445           0 :   unsigned int lineno = 0;
    1446             :   estream_t fp;
    1447             : 
    1448           0 :   fp = es_fopen (filename, "r");
    1449           0 :   if (!fp)
    1450             :     {
    1451           0 :       log_error (_("error opening '%s': %s\n"), filename, strerror (errno));
    1452           0 :       return NULL;
    1453             :     }
    1454             : 
    1455           0 :   serverstart = NULL;
    1456           0 :   serverend = &serverstart;
    1457           0 :   while (es_fgets (buffer, sizeof buffer, fp))
    1458             :     {
    1459           0 :       lineno++;
    1460           0 :       if (!*buffer || buffer[strlen(buffer)-1] != '\n')
    1461             :         {
    1462           0 :           if (*buffer && es_feof (fp))
    1463             :             ; /* Last line not terminated - continue. */
    1464             :           else
    1465             :             {
    1466           0 :               log_error (_("%s:%u: line too long - skipped\n"),
    1467             :                          filename, lineno);
    1468           0 :               while ( (c=es_fgetc (fp)) != EOF && c != '\n')
    1469             :                 ; /* Skip until end of line. */
    1470           0 :               continue;
    1471             :             }
    1472             :         }
    1473             :       /* Skip empty and comment lines.*/
    1474           0 :       for (p=buffer; spacep (p); p++)
    1475             :         ;
    1476           0 :       if (!*p || *p == '\n' || *p == '#')
    1477           0 :         continue;
    1478             : 
    1479             :       /* Parse the colon separated fields. */
    1480           0 :       server = ldapserver_parse_one (buffer, filename, lineno);
    1481           0 :       if (server)
    1482             :         {
    1483           0 :           *serverend = server;
    1484           0 :           serverend = &server->next;
    1485             :         }
    1486             :     }
    1487             : 
    1488           0 :   if (es_ferror (fp))
    1489           0 :     log_error (_("error reading '%s': %s\n"), filename, strerror (errno));
    1490           0 :   es_fclose (fp);
    1491             : 
    1492           0 :   return serverstart;
    1493             : }
    1494             : #endif /*USE_LDAP*/
    1495             : 
    1496             : static fingerprint_list_t
    1497           0 : parse_ocsp_signer (const char *string)
    1498             : {
    1499             :   gpg_error_t err;
    1500             :   char *fname;
    1501             :   estream_t fp;
    1502             :   char line[256];
    1503             :   char *p;
    1504             :   fingerprint_list_t list, *list_tail, item;
    1505           0 :   unsigned int lnr = 0;
    1506             :   int c, i, j;
    1507           0 :   int errflag = 0;
    1508             : 
    1509             : 
    1510             :   /* Check whether this is not a filename and treat it as a direct
    1511             :      fingerprint specification.  */
    1512           0 :   if (!strpbrk (string, "/.~\\"))
    1513             :     {
    1514           0 :       item = xcalloc (1, sizeof *item);
    1515           0 :       for (i=j=0; (string[i] == ':' || hexdigitp (string+i)) && j < 40; i++)
    1516           0 :         if ( string[i] != ':' )
    1517           0 :           item->hexfpr[j++] = string[i] >= 'a'? (string[i] & 0xdf): string[i];
    1518           0 :       item->hexfpr[j] = 0;
    1519           0 :       if (j != 40 || !(spacep (string+i) || !string[i]))
    1520             :         {
    1521           0 :           log_error (_("%s:%u: invalid fingerprint detected\n"),
    1522             :                      "--ocsp-signer", 0);
    1523           0 :           xfree (item);
    1524           0 :           return NULL;
    1525             :         }
    1526           0 :       return item;
    1527             :     }
    1528             : 
    1529             :   /* Well, it is a filename.  */
    1530           0 :   if (*string == '/' || (*string == '~' && string[1] == '/'))
    1531           0 :     fname = make_filename (string, NULL);
    1532             :   else
    1533             :     {
    1534           0 :       if (string[0] == '.' && string[1] == '/' )
    1535           0 :         string += 2;
    1536           0 :       fname = make_filename (gnupg_homedir (), string, NULL);
    1537             :     }
    1538             : 
    1539           0 :   fp = es_fopen (fname, "r");
    1540           0 :   if (!fp)
    1541             :     {
    1542           0 :       err = gpg_error_from_syserror ();
    1543           0 :       log_error (_("can't open '%s': %s\n"), fname, gpg_strerror (err));
    1544           0 :       xfree (fname);
    1545           0 :       return NULL;
    1546             :     }
    1547             : 
    1548           0 :   list = NULL;
    1549           0 :   list_tail = &list;
    1550             :   for (;;)
    1551             :     {
    1552           0 :       if (!es_fgets (line, DIM(line)-1, fp) )
    1553             :         {
    1554           0 :           if (!es_feof (fp))
    1555             :             {
    1556           0 :               err = gpg_error_from_syserror ();
    1557           0 :               log_error (_("%s:%u: read error: %s\n"),
    1558             :                          fname, lnr, gpg_strerror (err));
    1559           0 :               errflag = 1;
    1560             :             }
    1561           0 :           es_fclose (fp);
    1562           0 :           if (errflag)
    1563             :             {
    1564           0 :               while (list)
    1565             :                 {
    1566           0 :                   fingerprint_list_t tmp = list->next;
    1567           0 :                   xfree (list);
    1568           0 :                   list = tmp;
    1569             :                 }
    1570             :             }
    1571           0 :           xfree (fname);
    1572           0 :           return list; /* Ready.  */
    1573             :         }
    1574             : 
    1575           0 :       lnr++;
    1576           0 :       if (!*line || line[strlen(line)-1] != '\n')
    1577             :         {
    1578             :           /* Eat until end of line. */
    1579           0 :           while ( (c=es_getc (fp)) != EOF && c != '\n')
    1580             :             ;
    1581           0 :           err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG
    1582             :                            /* */: GPG_ERR_INCOMPLETE_LINE);
    1583           0 :           log_error (_("%s:%u: read error: %s\n"),
    1584             :                      fname, lnr, gpg_strerror (err));
    1585           0 :           errflag = 1;
    1586           0 :           continue;
    1587             :         }
    1588             : 
    1589             :       /* Allow for empty lines and spaces */
    1590           0 :       for (p=line; spacep (p); p++)
    1591             :         ;
    1592           0 :       if (!*p || *p == '\n' || *p == '#')
    1593           0 :         continue;
    1594             : 
    1595           0 :       item = xcalloc (1, sizeof *item);
    1596           0 :       *list_tail = item;
    1597           0 :       list_tail = &item->next;
    1598             : 
    1599           0 :       for (i=j=0; (p[i] == ':' || hexdigitp (p+i)) && j < 40; i++)
    1600           0 :         if ( p[i] != ':' )
    1601           0 :           item->hexfpr[j++] = p[i] >= 'a'? (p[i] & 0xdf): p[i];
    1602           0 :       item->hexfpr[j] = 0;
    1603           0 :       if (j != 40 || !(spacep (p+i) || p[i] == '\n'))
    1604             :         {
    1605           0 :           log_error (_("%s:%u: invalid fingerprint detected\n"), fname, lnr);
    1606           0 :           errflag = 1;
    1607             :         }
    1608           0 :       i++;
    1609           0 :       while (spacep (p+i))
    1610           0 :         i++;
    1611           0 :       if (p[i] && p[i] != '\n')
    1612           0 :         log_info (_("%s:%u: garbage at end of line ignored\n"), fname, lnr);
    1613           0 :     }
    1614             :   /*NOTREACHED*/
    1615             : }
    1616             : 
    1617             : 
    1618             : 
    1619             : 
    1620             : /*
    1621             :    Stuff used in daemon mode.
    1622             :  */
    1623             : 
    1624             : 
    1625             : 
    1626             : /* Reread parts of the configuration.  Note, that this function is
    1627             :    obviously not thread-safe and should only be called from the NPTH
    1628             :    signal handler.
    1629             : 
    1630             :    Fixme: Due to the way the argument parsing works, we create a
    1631             :    memory leak here for all string type arguments.  There is currently
    1632             :    no clean way to tell whether the memory for the argument has been
    1633             :    allocated or points into the process' original arguments.  Unless
    1634             :    we have a mechanism to tell this, we need to live on with this. */
    1635             : static void
    1636           0 : reread_configuration (void)
    1637             : {
    1638             :   ARGPARSE_ARGS pargs;
    1639             :   FILE *fp;
    1640           0 :   unsigned int configlineno = 0;
    1641             :   int dummy;
    1642             : 
    1643           0 :   if (!opt.config_filename)
    1644           0 :     return; /* No config file. */
    1645             : 
    1646           0 :   fp = fopen (opt.config_filename, "r");
    1647           0 :   if (!fp)
    1648             :     {
    1649           0 :       log_error (_("option file '%s': %s\n"),
    1650           0 :                  opt.config_filename, strerror(errno) );
    1651           0 :       return;
    1652             :     }
    1653             : 
    1654           0 :   parse_rereadable_options (NULL, 1); /* Start from the default values. */
    1655             : 
    1656           0 :   memset (&pargs, 0, sizeof pargs);
    1657           0 :   dummy = 0;
    1658           0 :   pargs.argc = &dummy;
    1659           0 :   pargs.flags = 1;  /* do not remove the args */
    1660           0 :   while (optfile_parse (fp, opt.config_filename, &configlineno, &pargs, opts) )
    1661             :     {
    1662           0 :       if (pargs.r_opt < -1)
    1663           0 :         pargs.err = 1; /* Print a warning. */
    1664             :       else /* Try to parse this option - ignore unchangeable ones. */
    1665           0 :         parse_rereadable_options (&pargs, 1);
    1666             :     }
    1667           0 :   fclose (fp);
    1668             : 
    1669           0 :   set_debug ();
    1670           0 :   set_tor_mode ();
    1671             : }
    1672             : 
    1673             : 
    1674             : /* A global function which allows us to trigger the reload stuff from
    1675             :    other places.  */
    1676             : void
    1677           0 : dirmngr_sighup_action (void)
    1678             : {
    1679           0 :   log_info (_("SIGHUP received - "
    1680             :               "re-reading configuration and flushing caches\n"));
    1681           0 :   reread_configuration ();
    1682           0 :   cert_cache_deinit (0);
    1683           0 :   crl_cache_deinit ();
    1684           0 :   cert_cache_init ();
    1685           0 :   crl_cache_init ();
    1686           0 : }
    1687             : 
    1688             : 
    1689             : /* This function is called if some network activity was done.  At this
    1690             :  * point we know the we have a network and we can decide whether to
    1691             :  * run scheduled background tasks soon.  The function should return
    1692             :  * quickly and only trigger actions for another thread. */
    1693             : static void
    1694           0 : netactivity_action (void)
    1695             : {
    1696           0 :   network_activity_seen = 1;
    1697           0 : }
    1698             : 
    1699             : 
    1700             : /* The signal handler. */
    1701             : #ifndef HAVE_W32_SYSTEM
    1702             : static void
    1703           0 : handle_signal (int signo)
    1704             : {
    1705           0 :   switch (signo)
    1706             :     {
    1707             :     case SIGHUP:
    1708           0 :       dirmngr_sighup_action ();
    1709           0 :       break;
    1710             : 
    1711             :     case SIGUSR1:
    1712           0 :       cert_cache_print_stats ();
    1713           0 :       break;
    1714             : 
    1715             :     case SIGUSR2:
    1716           0 :       log_info (_("SIGUSR2 received - no action defined\n"));
    1717           0 :       break;
    1718             : 
    1719             :     case SIGTERM:
    1720           0 :       if (!shutdown_pending)
    1721           0 :         log_info (_("SIGTERM received - shutting down ...\n"));
    1722             :       else
    1723           0 :         log_info (_("SIGTERM received - still %d active connections\n"),
    1724             :                   active_connections);
    1725           0 :       shutdown_pending++;
    1726           0 :       if (shutdown_pending > 2)
    1727             :         {
    1728           0 :           log_info (_("shutdown forced\n"));
    1729           0 :           log_info ("%s %s stopped\n", strusage(11), strusage(13) );
    1730           0 :           cleanup ();
    1731           0 :           dirmngr_exit (0);
    1732             :         }
    1733           0 :       break;
    1734             : 
    1735             :     case SIGINT:
    1736           0 :       log_info (_("SIGINT received - immediate shutdown\n"));
    1737           0 :       log_info( "%s %s stopped\n", strusage(11), strusage(13));
    1738           0 :       cleanup ();
    1739           0 :       dirmngr_exit (0);
    1740           0 :       break;
    1741             : 
    1742             :     default:
    1743           0 :       log_info (_("signal %d received - no action defined\n"), signo);
    1744             :     }
    1745           0 : }
    1746             : #endif /*!HAVE_W32_SYSTEM*/
    1747             : 
    1748             : 
    1749             : /* Thread to do the housekeeping.  */
    1750             : static void *
    1751           0 : housekeeping_thread (void *arg)
    1752             : {
    1753             :   static int sentinel;
    1754             :   time_t curtime;
    1755             :   struct server_control_s ctrlbuf;
    1756             : 
    1757             :   (void)arg;
    1758             : 
    1759           0 :   curtime = gnupg_get_time ();
    1760           0 :   if (sentinel)
    1761             :     {
    1762           0 :       log_info ("housekeeping is already going on\n");
    1763           0 :       return NULL;
    1764             :     }
    1765           0 :   sentinel++;
    1766           0 :   if (opt.verbose > 1)
    1767           0 :     log_info ("starting housekeeping\n");
    1768             : 
    1769           0 :   memset (&ctrlbuf, 0, sizeof ctrlbuf);
    1770           0 :   dirmngr_init_default_ctrl (&ctrlbuf);
    1771             : 
    1772           0 :   ks_hkp_housekeeping (curtime);
    1773           0 :   if (network_activity_seen)
    1774             :     {
    1775           0 :       network_activity_seen = 0;
    1776           0 :       if (opt.use_tor || opt.allow_version_check)
    1777           0 :         dirmngr_load_swdb (&ctrlbuf, 0);
    1778             :     }
    1779             : 
    1780           0 :   dirmngr_deinit_default_ctrl (&ctrlbuf);
    1781             : 
    1782           0 :   if (opt.verbose > 1)
    1783           0 :     log_info ("ready with housekeeping\n");
    1784           0 :   sentinel--;
    1785           0 :   return NULL;
    1786             : 
    1787             : }
    1788             : 
    1789             : 
    1790             : #if GPGRT_GCC_HAVE_PUSH_PRAGMA
    1791             : # pragma GCC push_options
    1792             : # pragma GCC optimize ("no-strict-overflow")
    1793             : #endif
    1794             : static int
    1795           0 : time_for_housekeeping_p (time_t curtime)
    1796             : {
    1797             :   static time_t last_housekeeping;
    1798             : 
    1799           0 :   if (!last_housekeeping)
    1800           0 :     last_housekeeping = curtime;
    1801             : 
    1802           0 :   if (last_housekeeping + HOUSEKEEPING_INTERVAL <= curtime
    1803           0 :       || last_housekeeping > curtime /*(be prepared for y2038)*/)
    1804             :     {
    1805           0 :       last_housekeeping = curtime;
    1806           0 :       return 1;
    1807             :     }
    1808           0 :   return 0;
    1809             : }
    1810             : #if GPGRT_GCC_HAVE_PUSH_PRAGMA
    1811             : # pragma GCC pop_options
    1812             : #endif
    1813             : 
    1814             : 
    1815             : /* This is the worker for the ticker.  It is called every few seconds
    1816             :    and may only do fast operations. */
    1817             : static void
    1818           0 : handle_tick (void)
    1819             : {
    1820           0 :   if (time_for_housekeeping_p (gnupg_get_time ()))
    1821             :     {
    1822             :       npth_t thread;
    1823             :       npth_attr_t tattr;
    1824             :       int err;
    1825             : 
    1826           0 :       err = npth_attr_init (&tattr);
    1827           0 :       if (err)
    1828           0 :         log_error ("error preparing housekeeping thread: %s\n", strerror (err));
    1829             :       else
    1830             :         {
    1831           0 :           npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
    1832           0 :           err = npth_create (&thread, &tattr, housekeeping_thread, NULL);
    1833           0 :           if (err)
    1834           0 :             log_error ("error spawning housekeeping thread: %s\n",
    1835             :                        strerror (err));
    1836           0 :           npth_attr_destroy (&tattr);
    1837             :         }
    1838             :     }
    1839           0 : }
    1840             : 
    1841             : 
    1842             : /* Check the nonce on a new connection.  This is a NOP unless we are
    1843             :    using our Unix domain socket emulation under Windows.  */
    1844             : static int
    1845           0 : check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce)
    1846             : {
    1847           0 :   if (assuan_sock_check_nonce (fd, nonce))
    1848             :     {
    1849           0 :       log_info (_("error reading nonce on fd %d: %s\n"),
    1850           0 :                 FD2INT (fd), strerror (errno));
    1851           0 :       assuan_sock_close (fd);
    1852           0 :       return -1;
    1853             :     }
    1854             :   else
    1855           0 :     return 0;
    1856             : }
    1857             : 
    1858             : 
    1859             : /* Helper to call a connection's main function. */
    1860             : static void *
    1861           0 : start_connection_thread (void *arg)
    1862             : {
    1863             :   union int_and_ptr_u argval;
    1864             :   gnupg_fd_t fd;
    1865             : 
    1866           0 :   memset (&argval, 0, sizeof argval);
    1867           0 :   argval.aptr = arg;
    1868           0 :   fd = argval.afd;
    1869             : 
    1870           0 :   if (check_nonce (fd, &socket_nonce))
    1871             :     {
    1872           0 :       log_error ("handler nonce check FAILED\n");
    1873           0 :       return NULL;
    1874             :     }
    1875             : 
    1876             : #ifndef HAVE_W32_SYSTEM
    1877           0 :   npth_setspecific (my_tlskey_current_fd, argval.aptr);
    1878             : #endif
    1879             : 
    1880           0 :   active_connections++;
    1881           0 :   if (opt.verbose)
    1882           0 :     log_info (_("handler for fd %d started\n"), FD2INT (fd));
    1883             : 
    1884           0 :   start_command_handler (fd);
    1885             : 
    1886           0 :   if (opt.verbose)
    1887           0 :     log_info (_("handler for fd %d terminated\n"), FD2INT (fd));
    1888           0 :   active_connections--;
    1889             : 
    1890             : #ifndef HAVE_W32_SYSTEM
    1891           0 :   argval.afd = ASSUAN_INVALID_FD;
    1892           0 :   npth_setspecific (my_tlskey_current_fd, argval.aptr);
    1893             : #endif
    1894             : 
    1895           0 :   return NULL;
    1896             : }
    1897             : 
    1898             : 
    1899             : #ifdef HAVE_INOTIFY_INIT
    1900             : /* Read an inotify event and return true if it matches NAME.  */
    1901             : static int
    1902           0 : my_inotify_is_name (int fd, const char *name)
    1903             : {
    1904             :   union {
    1905             :     struct inotify_event ev;
    1906             :     char _buf[sizeof (struct inotify_event) + 100 + 1];
    1907             :   } buf;
    1908             :   int n;
    1909             :   const char *s;
    1910             : 
    1911           0 :   s = strrchr (name, '/');
    1912           0 :   if (s && s[1])
    1913           0 :     name = s + 1;
    1914             : 
    1915           0 :   n = npth_read (fd, &buf, sizeof buf);
    1916           0 :   if (n < sizeof (struct inotify_event))
    1917           0 :     return 0;
    1918           0 :   if (buf.ev.len < strlen (name)+1)
    1919           0 :     return 0;
    1920           0 :   if (strcmp (buf.ev.name, name))
    1921           0 :     return 0; /* Not the desired file.  */
    1922             : 
    1923           0 :   return 1; /* Found.  */
    1924             : }
    1925             : #endif /*HAVE_INOTIFY_INIT*/
    1926             : 
    1927             : 
    1928             : /* Main loop in daemon mode. */
    1929             : static void
    1930           0 : handle_connections (assuan_fd_t listen_fd)
    1931             : {
    1932             :   npth_attr_t tattr;
    1933             : #ifndef HAVE_W32_SYSTEM
    1934             :   int signo;
    1935             : #endif
    1936             :   struct sockaddr_un paddr;
    1937           0 :   socklen_t plen = sizeof( paddr );
    1938             :   gnupg_fd_t fd;
    1939             :   int nfd, ret;
    1940             :   fd_set fdset, read_fdset;
    1941             :   struct timespec abstime;
    1942             :   struct timespec curtime;
    1943             :   struct timespec timeout;
    1944             :   int saved_errno;
    1945             : #ifdef HAVE_INOTIFY_INIT
    1946             :   int my_inotify_fd;
    1947             : #endif /*HAVE_INOTIFY_INIT*/
    1948             : 
    1949           0 :   npth_attr_init (&tattr);
    1950           0 :   npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
    1951             : 
    1952             : #ifndef HAVE_W32_SYSTEM /* FIXME */
    1953           0 :   npth_sigev_init ();
    1954           0 :   npth_sigev_add (SIGHUP);
    1955           0 :   npth_sigev_add (SIGUSR1);
    1956           0 :   npth_sigev_add (SIGUSR2);
    1957           0 :   npth_sigev_add (SIGINT);
    1958           0 :   npth_sigev_add (SIGTERM);
    1959           0 :   npth_sigev_fini ();
    1960             : #endif
    1961             : 
    1962             : #ifdef HAVE_INOTIFY_INIT
    1963           0 :   if (disable_check_own_socket)
    1964           0 :     my_inotify_fd = -1;
    1965           0 :   else if ((my_inotify_fd = inotify_init ()) == -1)
    1966           0 :     log_info ("error enabling fast daemon termination: %s\n",
    1967           0 :               strerror (errno));
    1968             :   else
    1969             :     {
    1970             :       /* We need to watch the directory for the file because there
    1971             :        * won't be an IN_DELETE_SELF for a socket file.  */
    1972           0 :       char *slash = strrchr (socket_name, '/');
    1973           0 :       log_assert (slash && slash[1]);
    1974           0 :       *slash = 0;
    1975           0 :       if (inotify_add_watch (my_inotify_fd, socket_name, IN_DELETE) == -1)
    1976             :         {
    1977           0 :           close (my_inotify_fd);
    1978           0 :           my_inotify_fd = -1;
    1979             :         }
    1980           0 :       *slash = '/';
    1981             :     }
    1982             : #endif /*HAVE_INOTIFY_INIT*/
    1983             : 
    1984             : 
    1985             :   /* Setup the fdset.  It has only one member.  This is because we use
    1986             :      pth_select instead of pth_accept to properly sync timeouts with
    1987             :      to full second.  */
    1988           0 :   FD_ZERO (&fdset);
    1989           0 :   FD_SET (FD2INT (listen_fd), &fdset);
    1990           0 :   nfd = FD2INT (listen_fd);
    1991             : #ifdef HAVE_INOTIFY_INIT
    1992           0 :   if (my_inotify_fd != -1)
    1993             :     {
    1994           0 :       FD_SET (my_inotify_fd, &fdset);
    1995           0 :       if (my_inotify_fd > nfd)
    1996           0 :         nfd = my_inotify_fd;
    1997             :     }
    1998             : #endif /*HAVE_INOTIFY_INIT*/
    1999             : 
    2000           0 :   npth_clock_gettime (&abstime);
    2001           0 :   abstime.tv_sec += TIMERTICK_INTERVAL;
    2002             : 
    2003             :   /* Main loop.  */
    2004             :   for (;;)
    2005             :     {
    2006             :       /* Shutdown test.  */
    2007           0 :       if (shutdown_pending)
    2008             :         {
    2009           0 :           if (!active_connections)
    2010           0 :             break; /* ready */
    2011             : 
    2012             :           /* Do not accept new connections but keep on running the
    2013             :              loop to cope with the timer events.  */
    2014           0 :           FD_ZERO (&fdset);
    2015             :         }
    2016             : 
    2017             :       /* Take a copy of the fdset.  */
    2018           0 :       read_fdset = fdset;
    2019             : 
    2020           0 :       npth_clock_gettime (&curtime);
    2021           0 :       if (!(npth_timercmp (&curtime, &abstime, <)))
    2022             :         {
    2023             :           /* Timeout.  */
    2024           0 :           handle_tick ();
    2025           0 :           npth_clock_gettime (&abstime);
    2026           0 :           abstime.tv_sec += TIMERTICK_INTERVAL;
    2027             :         }
    2028           0 :       npth_timersub (&abstime, &curtime, &timeout);
    2029             : 
    2030             : #ifndef HAVE_W32_SYSTEM
    2031           0 :       ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask());
    2032           0 :       saved_errno = errno;
    2033             : 
    2034           0 :       while (npth_sigev_get_pending(&signo))
    2035           0 :         handle_signal (signo);
    2036             : #else
    2037             :       ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout, NULL, NULL);
    2038             :       saved_errno = errno;
    2039             : #endif
    2040             : 
    2041           0 :       if (ret == -1 && saved_errno != EINTR)
    2042             :         {
    2043           0 :           log_error (_("npth_pselect failed: %s - waiting 1s\n"),
    2044             :                      strerror (saved_errno));
    2045           0 :           npth_sleep (1);
    2046           0 :           continue;
    2047             :         }
    2048             : 
    2049           0 :       if (ret <= 0)
    2050             :         {
    2051             :           /* Interrupt or timeout.  Will be handled when calculating the
    2052             :              next timeout.  */
    2053           0 :           continue;
    2054             :         }
    2055             : 
    2056           0 :       if (shutdown_pending)
    2057             :         {
    2058             :           /* Do not anymore accept connections.  */
    2059           0 :           continue;
    2060             :         }
    2061             : 
    2062             : #ifdef HAVE_INOTIFY_INIT
    2063           0 :       if (my_inotify_fd != -1 && FD_ISSET (my_inotify_fd, &read_fdset)
    2064           0 :           && my_inotify_is_name (my_inotify_fd, socket_name))
    2065             :         {
    2066           0 :           shutdown_pending = 1;
    2067           0 :           log_info ("socket file has been removed - shutting down\n");
    2068             :         }
    2069             : #endif /*HAVE_INOTIFY_INIT*/
    2070             : 
    2071           0 :       if (FD_ISSET (FD2INT (listen_fd), &read_fdset))
    2072             :         {
    2073           0 :           plen = sizeof paddr;
    2074           0 :           fd = INT2FD (npth_accept (FD2INT(listen_fd),
    2075             :                                     (struct sockaddr *)&paddr, &plen));
    2076           0 :           if (fd == GNUPG_INVALID_FD)
    2077             :             {
    2078           0 :               log_error ("accept failed: %s\n", strerror (errno));
    2079             :             }
    2080             :           else
    2081             :             {
    2082             :               char threadname[50];
    2083             :               union int_and_ptr_u argval;
    2084             :               npth_t thread;
    2085             : 
    2086           0 :               memset (&argval, 0, sizeof argval);
    2087           0 :               argval.afd = fd;
    2088           0 :               snprintf (threadname, sizeof threadname,
    2089             :                         "conn fd=%d", FD2INT(fd));
    2090             : 
    2091           0 :               ret = npth_create (&thread, &tattr,
    2092             :                                  start_connection_thread, argval.aptr);
    2093           0 :               if (ret)
    2094             :                 {
    2095           0 :                   log_error ("error spawning connection handler: %s\n",
    2096             :                              strerror (ret) );
    2097           0 :                   assuan_sock_close (fd);
    2098             :                 }
    2099           0 :               npth_setname_np (thread, threadname);
    2100             :             }
    2101           0 :           fd = GNUPG_INVALID_FD;
    2102             :         }
    2103           0 :     }
    2104             : 
    2105             : #ifdef HAVE_INOTIFY_INIT
    2106           0 :   if (my_inotify_fd != -1)
    2107           0 :     close (my_inotify_fd);
    2108             : #endif /*HAVE_INOTIFY_INIT*/
    2109           0 :   npth_attr_destroy (&tattr);
    2110           0 :   cleanup ();
    2111           0 :   log_info ("%s %s stopped\n", strusage(11), strusage(13));
    2112           0 : }
    2113             : 
    2114             : const char*
    2115           0 : dirmngr_get_current_socket_name (void)
    2116             : {
    2117           0 :   if (socket_name)
    2118           0 :     return socket_name;
    2119             :   else
    2120           0 :     return dirmngr_socket_name ();
    2121             : }

Generated by: LCOV version 1.11