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

Generated by: LCOV version 1.11