LCOV - code coverage report
Current view: top level - dirmngr - dirmngr.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 869 0.0 %
Date: 2016-12-01 18:37:21 Functions: 0 36 0.0 %

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

Generated by: LCOV version 1.11