LCOV - code coverage report
Current view: top level - agent - gpg-agent.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 411 942 43.6 %
Date: 2015-11-05 17:10:59 Functions: 23 40 57.5 %

          Line data    Source code
       1             : /* gpg-agent.c  -  The GnuPG Agent
       2             :  * Copyright (C) 2000-2007, 2009-2010 Free Software Foundation, Inc.
       3             :  * Copyright (C) 2000-2014 Werner Koch
       4             :  *
       5             :  * This file is part of GnuPG.
       6             :  *
       7             :  * GnuPG is free software; you can redistribute it and/or modify
       8             :  * it under the terms of the GNU General Public License as published by
       9             :  * the Free Software Foundation; either version 3 of the License, or
      10             :  * (at your option) any later version.
      11             :  *
      12             :  * GnuPG is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  * GNU General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License
      18             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : #include <config.h>
      22             : 
      23             : #include <stdio.h>
      24             : #include <stdlib.h>
      25             : #include <stddef.h>
      26             : #include <stdarg.h>
      27             : #include <string.h>
      28             : #include <errno.h>
      29             : #include <assert.h>
      30             : #include <time.h>
      31             : #include <fcntl.h>
      32             : #include <sys/stat.h>
      33             : #ifdef HAVE_W32_SYSTEM
      34             : # ifndef WINVER
      35             : #  define WINVER 0x0500  /* Same as in common/sysutils.c */
      36             : # endif
      37             : # ifdef HAVE_WINSOCK2_H
      38             : #  include <winsock2.h>
      39             : # endif
      40             : # include <aclapi.h>
      41             : # include <sddl.h>
      42             : #else /*!HAVE_W32_SYSTEM*/
      43             : # include <sys/socket.h>
      44             : # include <sys/un.h>
      45             : #endif /*!HAVE_W32_SYSTEM*/
      46             : #include <unistd.h>
      47             : #ifdef HAVE_SIGNAL_H
      48             : # include <signal.h>
      49             : #endif
      50             : #include <npth.h>
      51             : 
      52             : #define GNUPG_COMMON_NEED_AFLOCAL
      53             : #include "agent.h"
      54             : #include <assuan.h> /* Malloc hooks  and socket wrappers. */
      55             : 
      56             : #include "i18n.h"
      57             : #include "sysutils.h"
      58             : #include "gc-opt-flags.h"
      59             : #include "exechelp.h"
      60             : #include "asshelp.h"
      61             : #include "openpgpdefs.h"  /* for PUBKEY_ALGO_ECDSA, PUBKEY_ALGO_ECDH */
      62             : #include "../common/init.h"
      63             : 
      64             : 
      65             : enum cmd_and_opt_values
      66             : { aNull = 0,
      67             :   oCsh            = 'c',
      68             :   oQuiet          = 'q',
      69             :   oSh             = 's',
      70             :   oVerbose        = 'v',
      71             : 
      72             :   oNoVerbose = 500,
      73             :   aGPGConfList,
      74             :   aGPGConfTest,
      75             :   aUseStandardSocketP,
      76             :   oOptions,
      77             :   oDebug,
      78             :   oDebugAll,
      79             :   oDebugLevel,
      80             :   oDebugWait,
      81             :   oDebugQuickRandom,
      82             :   oDebugPinentry,
      83             :   oNoGreeting,
      84             :   oNoOptions,
      85             :   oHomedir,
      86             :   oNoDetach,
      87             :   oNoGrab,
      88             :   oLogFile,
      89             :   oServer,
      90             :   oDaemon,
      91             :   oBatch,
      92             : 
      93             :   oPinentryProgram,
      94             :   oPinentryTouchFile,
      95             :   oPinentryInvisibleChar,
      96             :   oDisplay,
      97             :   oTTYname,
      98             :   oTTYtype,
      99             :   oLCctype,
     100             :   oLCmessages,
     101             :   oXauthority,
     102             :   oScdaemonProgram,
     103             :   oDefCacheTTL,
     104             :   oDefCacheTTLSSH,
     105             :   oMaxCacheTTL,
     106             :   oMaxCacheTTLSSH,
     107             :   oEnforcePassphraseConstraints,
     108             :   oMinPassphraseLen,
     109             :   oMinPassphraseNonalpha,
     110             :   oCheckPassphrasePattern,
     111             :   oMaxPassphraseDays,
     112             :   oEnablePassphraseHistory,
     113             :   oUseStandardSocket,
     114             :   oNoUseStandardSocket,
     115             :   oExtraSocket,
     116             :   oBrowserSocket,
     117             :   oFakedSystemTime,
     118             : 
     119             :   oIgnoreCacheForSigning,
     120             :   oAllowMarkTrusted,
     121             :   oNoAllowMarkTrusted,
     122             :   oAllowPresetPassphrase,
     123             :   oAllowLoopbackPinentry,
     124             :   oNoAllowExternalCache,
     125             :   oAllowEmacsPinentry,
     126             :   oKeepTTY,
     127             :   oKeepDISPLAY,
     128             :   oSSHSupport,
     129             :   oPuttySupport,
     130             :   oDisableScdaemon,
     131             :   oDisableCheckOwnSocket,
     132             :   oWriteEnvFile
     133             : };
     134             : 
     135             : 
     136             : #ifndef ENAMETOOLONG
     137             : # define ENAMETOOLONG EINVAL
     138             : #endif
     139             : 
     140             : 
     141             : static ARGPARSE_OPTS opts[] = {
     142             : 
     143             :   ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"),
     144             :   ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"),
     145             :   ARGPARSE_c (aUseStandardSocketP, "use-standard-socket-p", "@"),
     146             : 
     147             :   ARGPARSE_group (301, N_("@Options:\n ")),
     148             : 
     149             :   ARGPARSE_s_n (oDaemon,  "daemon", N_("run in daemon mode (background)")),
     150             :   ARGPARSE_s_n (oServer,  "server", N_("run in server mode (foreground)")),
     151             :   ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
     152             :   ARGPARSE_s_n (oQuiet,   "quiet",     N_("be somewhat more quiet")),
     153             :   ARGPARSE_s_n (oSh,      "sh",        N_("sh-style command output")),
     154             :   ARGPARSE_s_n (oCsh,     "csh",       N_("csh-style command output")),
     155             :   ARGPARSE_s_s (oOptions, "options", N_("|FILE|read options from FILE")),
     156             : 
     157             :   ARGPARSE_s_s (oDebug,      "debug",       "@"),
     158             :   ARGPARSE_s_n (oDebugAll,   "debug-all",   "@"),
     159             :   ARGPARSE_s_s (oDebugLevel, "debug-level", "@"),
     160             :   ARGPARSE_s_i (oDebugWait,"  debug-wait",  "@"),
     161             :   ARGPARSE_s_n (oDebugQuickRandom, "debug-quick-random", "@"),
     162             :   ARGPARSE_s_n (oDebugPinentry, "debug-pinentry", "@"),
     163             : 
     164             :   ARGPARSE_s_n (oNoDetach,  "no-detach", N_("do not detach from the console")),
     165             :   ARGPARSE_s_n (oNoGrab,    "no-grab",   N_("do not grab keyboard and mouse")),
     166             :   ARGPARSE_s_s (oLogFile,   "log-file",  N_("use a log file for the server")),
     167             :   ARGPARSE_s_s (oPinentryProgram, "pinentry-program",
     168             :                 /* */             N_("|PGM|use PGM as the PIN-Entry program")),
     169             :   ARGPARSE_s_s (oPinentryTouchFile, "pinentry-touch-file", "@"),
     170             :   ARGPARSE_s_s (oPinentryInvisibleChar, "pinentry-invisible-char", "@"),
     171             :   ARGPARSE_s_s (oScdaemonProgram, "scdaemon-program",
     172             :                 /* */             N_("|PGM|use PGM as the SCdaemon program") ),
     173             :   ARGPARSE_s_n (oDisableScdaemon, "disable-scdaemon",
     174             :                 /* */             N_("do not use the SCdaemon") ),
     175             :   ARGPARSE_s_n (oDisableCheckOwnSocket, "disable-check-own-socket", "@"),
     176             : 
     177             :   ARGPARSE_s_s (oExtraSocket, "extra-socket",
     178             :                 /* */       N_("|NAME|accept some commands via NAME")),
     179             : 
     180             :   ARGPARSE_s_s (oBrowserSocket, "browser-socket", "@"),
     181             : 
     182             :   ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"),
     183             : 
     184             :   ARGPARSE_s_n (oBatch,      "batch",        "@"),
     185             :   ARGPARSE_s_s (oHomedir,    "homedir",      "@"),
     186             : 
     187             :   ARGPARSE_s_s (oDisplay,    "display",     "@"),
     188             :   ARGPARSE_s_s (oTTYname,    "ttyname",     "@"),
     189             :   ARGPARSE_s_s (oTTYtype,    "ttytype",     "@"),
     190             :   ARGPARSE_s_s (oLCctype,    "lc-ctype",    "@"),
     191             :   ARGPARSE_s_s (oLCmessages, "lc-messages", "@"),
     192             :   ARGPARSE_s_s (oXauthority, "xauthority",  "@"),
     193             :   ARGPARSE_s_n (oKeepTTY,    "keep-tty",
     194             :                 /* */        N_("ignore requests to change the TTY")),
     195             :   ARGPARSE_s_n (oKeepDISPLAY, "keep-display",
     196             :                 /* */        N_("ignore requests to change the X display")),
     197             : 
     198             :   ARGPARSE_s_u (oDefCacheTTL,    "default-cache-ttl",
     199             :                                  N_("|N|expire cached PINs after N seconds")),
     200             :   ARGPARSE_s_u (oDefCacheTTLSSH, "default-cache-ttl-ssh", "@" ),
     201             :   ARGPARSE_s_u (oMaxCacheTTL,    "max-cache-ttl",         "@" ),
     202             :   ARGPARSE_s_u (oMaxCacheTTLSSH, "max-cache-ttl-ssh",     "@" ),
     203             : 
     204             :   ARGPARSE_s_n (oEnforcePassphraseConstraints, "enforce-passphrase-constraints",
     205             :                 /* */                          "@"),
     206             :   ARGPARSE_s_u (oMinPassphraseLen,        "min-passphrase-len", "@"),
     207             :   ARGPARSE_s_u (oMinPassphraseNonalpha,   "min-passphrase-nonalpha", "@"),
     208             :   ARGPARSE_s_s (oCheckPassphrasePattern,  "check-passphrase-pattern", "@"),
     209             :   ARGPARSE_s_u (oMaxPassphraseDays,       "max-passphrase-days", "@"),
     210             :   ARGPARSE_s_n (oEnablePassphraseHistory, "enable-passphrase-history", "@"),
     211             : 
     212             :   ARGPARSE_s_n (oIgnoreCacheForSigning, "ignore-cache-for-signing",
     213             :                 /* */    N_("do not use the PIN cache when signing")),
     214             :   ARGPARSE_s_n (oNoAllowExternalCache,  "no-allow-external-cache",
     215             :                 /* */    N_("disallow the use of an external password cache")),
     216             :   ARGPARSE_s_n (oNoAllowMarkTrusted, "no-allow-mark-trusted",
     217             :                 /* */    N_("disallow clients to mark keys as \"trusted\"")),
     218             :   ARGPARSE_s_n (oAllowMarkTrusted,   "allow-mark-trusted", "@"),
     219             :   ARGPARSE_s_n (oAllowPresetPassphrase, "allow-preset-passphrase",
     220             :                 /* */                    N_("allow presetting passphrase")),
     221             :   ARGPARSE_s_n (oAllowLoopbackPinentry, "allow-loopback-pinentry",
     222             :                                    N_("allow caller to override the pinentry")),
     223             :   ARGPARSE_s_n (oAllowEmacsPinentry,  "allow-emacs-pinentry",
     224             :                 /* */    N_("allow passphrase to be prompted through Emacs")),
     225             : 
     226             :   ARGPARSE_s_n (oSSHSupport,   "enable-ssh-support", N_("enable ssh support")),
     227             :   ARGPARSE_s_n (oPuttySupport, "enable-putty-support",
     228             : #ifdef HAVE_W32_SYSTEM
     229             :                 /* */           N_("enable putty support")
     230             : #else
     231             :                 /* */           "@"
     232             : #endif
     233             :                 ),
     234             : 
     235             :   /* Dummy options for backward compatibility.  */
     236             :   ARGPARSE_o_s (oWriteEnvFile, "write-env-file", "@"),
     237             :   ARGPARSE_s_n (oUseStandardSocket, "use-standard-socket", "@"),
     238             :   ARGPARSE_s_n (oNoUseStandardSocket, "no-use-standard-socket", "@"),
     239             : 
     240             :   {0} /* End of list */
     241             : };
     242             : 
     243             : 
     244             : /* The list of supported debug flags.  */
     245             : static struct debug_flags_s debug_flags [] =
     246             :   {
     247             :     { DBG_COMMAND_VALUE, "command"  },
     248             :     { DBG_MPI_VALUE    , "mpi"     },
     249             :     { DBG_CRYPTO_VALUE , "crypto"  },
     250             :     { DBG_MEMORY_VALUE , "memory"  },
     251             :     { DBG_CACHE_VALUE  , "cache"   },
     252             :     { DBG_MEMSTAT_VALUE, "memstat" },
     253             :     { DBG_HASHING_VALUE, "hashing" },
     254             :     { DBG_IPC_VALUE    , "ipc"     },
     255             :     { 77, NULL } /* 77 := Do not exit on "help" or "?".  */
     256             :   };
     257             : 
     258             : 
     259             : 
     260             : #define DEFAULT_CACHE_TTL     (10*60)  /* 10 minutes */
     261             : #define DEFAULT_CACHE_TTL_SSH (30*60)  /* 30 minutes */
     262             : #define MAX_CACHE_TTL         (120*60) /* 2 hours */
     263             : #define MAX_CACHE_TTL_SSH     (120*60) /* 2 hours */
     264             : #define MIN_PASSPHRASE_LEN    (8)
     265             : #define MIN_PASSPHRASE_NONALPHA (1)
     266             : #define MAX_PASSPHRASE_DAYS   (0)
     267             : 
     268             : /* The timer tick used for housekeeping stuff.  For Windows we use a
     269             :    longer period as the SetWaitableTimer seems to signal earlier than
     270             :    the 2 seconds.  CHECK_OWN_SOCKET_INTERVAL defines how often we
     271             :    check our own socket in standard socket mode.  If that value is 0
     272             :    we don't check at all.   All values are in seconds. */
     273             : #if defined(HAVE_W32CE_SYSTEM)
     274             : # define TIMERTICK_INTERVAL         (60)
     275             : # define CHECK_OWN_SOCKET_INTERVAL   (0)  /* Never */
     276             : #elif defined(HAVE_W32_SYSTEM)
     277             : # define TIMERTICK_INTERVAL          (4)
     278             : # define CHECK_OWN_SOCKET_INTERVAL  (60)
     279             : #else
     280             : # define TIMERTICK_INTERVAL          (2)
     281             : # define CHECK_OWN_SOCKET_INTERVAL  (60)
     282             : #endif
     283             : 
     284             : 
     285             : /* Flag indicating that the ssh-agent subsystem has been enabled.  */
     286             : static int ssh_support;
     287             : 
     288             : #ifdef HAVE_W32_SYSTEM
     289             : /* Flag indicating that support for Putty has been enabled.  */
     290             : static int putty_support;
     291             : /* A magic value used with WM_COPYDATA.  */
     292             : #define PUTTY_IPC_MAGIC 0x804e50ba
     293             : /* To avoid surprises we limit the size of the mapped IPC file to this
     294             :    value.  Putty currently (0.62) uses 8k, thus 16k should be enough
     295             :    for the foreseeable future.  */
     296             : #define PUTTY_IPC_MAXLEN 16384
     297             : #endif /*HAVE_W32_SYSTEM*/
     298             : 
     299             : /* The list of open file descriptors at startup.  Note that this list
     300             :    has been allocated using the standard malloc.  */
     301             : static int *startup_fd_list;
     302             : 
     303             : /* The signal mask at startup and a flag telling whether it is valid.  */
     304             : #ifdef HAVE_SIGPROCMASK
     305             : static sigset_t startup_signal_mask;
     306             : static int startup_signal_mask_valid;
     307             : #endif
     308             : 
     309             : /* Flag to indicate that a shutdown was requested.  */
     310             : static int shutdown_pending;
     311             : 
     312             : /* Counter for the currently running own socket checks.  */
     313             : static int check_own_socket_running;
     314             : 
     315             : /* Flags to indicate that check_own_socket shall not be called.  */
     316             : static int disable_check_own_socket;
     317             : 
     318             : /* It is possible that we are currently running under setuid permissions */
     319             : static int maybe_setuid = 1;
     320             : 
     321             : /* Name of the communication socket used for native gpg-agent
     322             :    requests. The second variable is either NULL or a malloced string
     323             :    with the real socket name in case it has been redirected.  */
     324             : static char *socket_name;
     325             : static char *redir_socket_name;
     326             : 
     327             : /* Name of the optional extra socket used for native gpg-agent requests.  */
     328             : static char *socket_name_extra;
     329             : static char *redir_socket_name_extra;
     330             : 
     331             : /* Name of the optional browser socket used for native gpg-agent requests.  */
     332             : static char *socket_name_browser;
     333             : static char *redir_socket_name_browser;
     334             : 
     335             : /* Name of the communication socket used for ssh-agent-emulation.  */
     336             : static char *socket_name_ssh;
     337             : static char *redir_socket_name_ssh;
     338             : 
     339             : /* We need to keep track of the server's nonces (these are dummies for
     340             :    POSIX systems). */
     341             : static assuan_sock_nonce_t socket_nonce;
     342             : static assuan_sock_nonce_t socket_nonce_extra;
     343             : static assuan_sock_nonce_t socket_nonce_browser;
     344             : static assuan_sock_nonce_t socket_nonce_ssh;
     345             : 
     346             : 
     347             : /* Default values for options passed to the pinentry. */
     348             : static char *default_display;
     349             : static char *default_ttyname;
     350             : static char *default_ttytype;
     351             : static char *default_lc_ctype;
     352             : static char *default_lc_messages;
     353             : static char *default_xauthority;
     354             : 
     355             : /* Name of a config file, which will be reread on a HUP if it is not NULL. */
     356             : static char *config_filename;
     357             : 
     358             : /* Helper to implement --debug-level */
     359             : static const char *debug_level;
     360             : 
     361             : /* Keep track of the current log file so that we can avoid updating
     362             :    the log file after a SIGHUP if it didn't changed. Malloced. */
     363             : static char *current_logfile;
     364             : 
     365             : /* The handle_tick() function may test whether a parent is still
     366             :    running.  We record the PID of the parent here or -1 if it should be
     367             :    watched. */
     368             : static pid_t parent_pid = (pid_t)(-1);
     369             : 
     370             : /* Number of active connections.  */
     371             : static int active_connections;
     372             : 
     373             : 
     374             : /*
     375             :    Local prototypes.
     376             :  */
     377             : 
     378             : static char *create_socket_name (char *standard_name, int with_homedir);
     379             : static gnupg_fd_t create_server_socket (char *name, int primary, int cygwin,
     380             :                                         char **r_redir_name,
     381             :                                         assuan_sock_nonce_t *nonce);
     382             : static void create_directories (void);
     383             : 
     384             : static void agent_init_default_ctrl (ctrl_t ctrl);
     385             : static void agent_deinit_default_ctrl (ctrl_t ctrl);
     386             : 
     387             : static void handle_connections (gnupg_fd_t listen_fd,
     388             :                                 gnupg_fd_t listen_fd_extra,
     389             :                                 gnupg_fd_t listen_fd_browser,
     390             :                                 gnupg_fd_t listen_fd_ssh);
     391             : static void check_own_socket (void);
     392             : static int check_for_running_agent (int silent);
     393             : 
     394             : /* Pth wrapper function definitions. */
     395       22375 : ASSUAN_SYSTEM_NPTH_IMPL;
     396             : 
     397             : 
     398             : /*
     399             :    Functions.
     400             :  */
     401             : 
     402             : /* Allocate a string describing a library version by calling a GETFNC.
     403             :    This function is expected to be called only once.  GETFNC is
     404             :    expected to have a semantic like gcry_check_version ().  */
     405             : static char *
     406           0 : make_libversion (const char *libname, const char *(*getfnc)(const char*))
     407             : {
     408             :   const char *s;
     409             :   char *result;
     410             : 
     411           0 :   if (maybe_setuid)
     412             :     {
     413           0 :       gcry_control (GCRYCTL_INIT_SECMEM, 0, 0);  /* Drop setuid. */
     414           0 :       maybe_setuid = 0;
     415             :     }
     416           0 :   s = getfnc (NULL);
     417           0 :   result = xmalloc (strlen (libname) + 1 + strlen (s) + 1);
     418           0 :   strcpy (stpcpy (stpcpy (result, libname), " "), s);
     419           0 :   return result;
     420             : }
     421             : 
     422             : /* Return strings describing this program.  The case values are
     423             :    described in common/argparse.c:strusage.  The values here override
     424             :    the default values given by strusage.  */
     425             : static const char *
     426           2 : my_strusage (int level)
     427             : {
     428             :   static char *ver_gcry;
     429             :   const char *p;
     430             : 
     431           2 :   switch (level)
     432             :     {
     433           1 :     case 11: p = "@GPG_AGENT@ (@GNUPG@)";
     434           1 :       break;
     435           1 :     case 13: p = VERSION; break;
     436           0 :     case 17: p = PRINTABLE_OS_NAME; break;
     437             :       /* TRANSLATORS: @EMAIL@ will get replaced by the actual bug
     438             :          reporting address.  This is so that we can change the
     439             :          reporting address without breaking the translations.  */
     440           0 :     case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
     441             : 
     442             :     case 20:
     443           0 :       if (!ver_gcry)
     444           0 :         ver_gcry = make_libversion ("libgcrypt", gcry_check_version);
     445           0 :       p = ver_gcry;
     446           0 :       break;
     447             : 
     448             :     case 1:
     449           0 :     case 40: p =  _("Usage: @GPG_AGENT@ [options] (-h for help)");
     450           0 :       break;
     451           0 :     case 41: p =  _("Syntax: @GPG_AGENT@ [options] [command [args]]\n"
     452             :                     "Secret key management for @GNUPG@\n");
     453           0 :     break;
     454             : 
     455           0 :     default: p = NULL;
     456             :     }
     457           2 :   return p;
     458             : }
     459             : 
     460             : 
     461             : 
     462             : /* Setup the debugging.  With the global variable DEBUG_LEVEL set to NULL
     463             :    only the active debug flags are propagated to the subsystems.  With
     464             :    DEBUG_LEVEL set, a specific set of debug flags is set; thus overriding
     465             :    all flags already set. Note that we don't fail here, because it is
     466             :    important to keep gpg-agent running even after re-reading the
     467             :    options due to a SIGHUP. */
     468             : static void
     469           3 : set_debug (void)
     470             : {
     471           3 :   int numok = (debug_level && digitp (debug_level));
     472           3 :   int numlvl = numok? atoi (debug_level) : 0;
     473             : 
     474           3 :   if (!debug_level)
     475             :     ;
     476           0 :   else if (!strcmp (debug_level, "none") || (numok && numlvl < 1))
     477           0 :     opt.debug = 0;
     478           0 :   else if (!strcmp (debug_level, "basic") || (numok && numlvl <= 2))
     479           0 :     opt.debug = DBG_IPC_VALUE;
     480           0 :   else if (!strcmp (debug_level, "advanced") || (numok && numlvl <= 5))
     481           0 :     opt.debug = DBG_IPC_VALUE|DBG_COMMAND_VALUE;
     482           0 :   else if (!strcmp (debug_level, "expert") || (numok && numlvl <= 8))
     483           0 :     opt.debug = (DBG_IPC_VALUE|DBG_COMMAND_VALUE
     484             :                  |DBG_CACHE_VALUE);
     485           0 :   else if (!strcmp (debug_level, "guru") || numok)
     486             :     {
     487           0 :       opt.debug = ~0;
     488             :       /* Unless the "guru" string has been used we don't want to allow
     489             :          hashing debugging.  The rationale is that people tend to
     490             :          select the highest debug value and would then clutter their
     491             :          disk with debug files which may reveal confidential data.  */
     492           0 :       if (numok)
     493           0 :         opt.debug &= ~(DBG_HASHING_VALUE);
     494             :     }
     495             :   else
     496             :     {
     497           0 :       log_error (_("invalid debug-level '%s' given\n"), debug_level);
     498           0 :       opt.debug = 0; /* Reset debugging, so that prior debug
     499             :                         statements won't have an undesired effect. */
     500             :     }
     501             : 
     502           3 :   if (opt.debug && !opt.verbose)
     503           0 :     opt.verbose = 1;
     504           3 :   if (opt.debug && opt.quiet)
     505           0 :     opt.quiet = 0;
     506             : 
     507           3 :   if (opt.debug & DBG_MPI_VALUE)
     508           0 :     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
     509           3 :   if (opt.debug & DBG_CRYPTO_VALUE )
     510           0 :     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
     511           3 :   gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
     512             : 
     513           3 :   if (opt.debug)
     514           0 :     parse_debug_flag (NULL, &opt.debug, debug_flags);
     515           3 : }
     516             : 
     517             : 
     518             : /* Helper for cleanup to remove one socket with NAME.  REDIR_NAME is
     519             :    the corresponding real name if the socket has been redirected.  */
     520             : static void
     521           8 : remove_socket (char *name, char *redir_name)
     522             : {
     523           8 :   if (name && *name)
     524             :     {
     525             :       char *p;
     526             : 
     527           1 :       if (redir_name)
     528           0 :         name = redir_name;
     529             : 
     530           1 :       gnupg_remove (name);
     531           1 :       p = strrchr (name, '/');
     532           1 :       if (p)
     533             :         {
     534           1 :           *p = 0;
     535           1 :           rmdir (name);
     536           1 :           *p = '/';
     537             :         }
     538           1 :       *name = 0;
     539             :     }
     540           8 : }
     541             : 
     542             : 
     543             : /* Cleanup code for this program.  This is either called has an atexit
     544             :    handler or directly.  */
     545             : static void
     546           5 : cleanup (void)
     547             : {
     548             :   static int done;
     549             : 
     550           5 :   if (done)
     551           6 :     return;
     552           4 :   done = 1;
     553           4 :   deinitialize_module_cache ();
     554           4 :   remove_socket (socket_name, redir_socket_name);
     555           4 :   if (opt.extra_socket > 1)
     556           0 :     remove_socket (socket_name_extra, redir_socket_name_extra);
     557           4 :   if (opt.browser_socket > 1)
     558           0 :     remove_socket (socket_name_browser, redir_socket_name_browser);
     559           4 :   remove_socket (socket_name_ssh, redir_socket_name_ssh);
     560             : }
     561             : 
     562             : 
     563             : 
     564             : /* Handle options which are allowed to be reset after program start.
     565             :    Return true when the current option in PARGS could be handled and
     566             :    false if not.  As a special feature, passing a value of NULL for
     567             :    PARGS, resets the options to the default.  REREAD should be set
     568             :    true if it is not the initial option parsing. */
     569             : static int
     570          21 : parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
     571             : {
     572          21 :   if (!pargs)
     573             :     { /* reset mode */
     574           3 :       opt.quiet = 0;
     575           3 :       opt.verbose = 0;
     576           3 :       opt.debug = 0;
     577           3 :       opt.no_grab = 0;
     578           3 :       opt.debug_pinentry = 0;
     579           3 :       opt.pinentry_program = NULL;
     580           3 :       opt.pinentry_touch_file = NULL;
     581           3 :       xfree (opt.pinentry_invisible_char);
     582           3 :       opt.pinentry_invisible_char = NULL;
     583           3 :       opt.scdaemon_program = NULL;
     584           3 :       opt.def_cache_ttl = DEFAULT_CACHE_TTL;
     585           3 :       opt.def_cache_ttl_ssh = DEFAULT_CACHE_TTL_SSH;
     586           3 :       opt.max_cache_ttl = MAX_CACHE_TTL;
     587           3 :       opt.max_cache_ttl_ssh = MAX_CACHE_TTL_SSH;
     588           3 :       opt.enforce_passphrase_constraints = 0;
     589           3 :       opt.min_passphrase_len = MIN_PASSPHRASE_LEN;
     590           3 :       opt.min_passphrase_nonalpha = MIN_PASSPHRASE_NONALPHA;
     591           3 :       opt.check_passphrase_pattern = NULL;
     592           3 :       opt.max_passphrase_days = MAX_PASSPHRASE_DAYS;
     593           3 :       opt.enable_passhrase_history = 0;
     594           3 :       opt.ignore_cache_for_signing = 0;
     595           3 :       opt.allow_mark_trusted = 1;
     596           3 :       opt.allow_external_cache = 1;
     597           3 :       opt.allow_emacs_pinentry = 0;
     598           3 :       opt.disable_scdaemon = 0;
     599           3 :       disable_check_own_socket = 0;
     600           3 :       return 1;
     601             :     }
     602             : 
     603          18 :   switch (pargs->r_opt)
     604             :     {
     605           2 :     case oQuiet: opt.quiet = 1; break;
     606           0 :     case oVerbose: opt.verbose++; break;
     607             : 
     608             :     case oDebug:
     609           0 :       parse_debug_flag (pargs->r.ret_str, &opt.debug, debug_flags);
     610           0 :       break;
     611           0 :     case oDebugAll: opt.debug = ~0; break;
     612           0 :     case oDebugLevel: debug_level = pargs->r.ret_str; break;
     613           0 :     case oDebugPinentry: opt.debug_pinentry = 1; break;
     614             : 
     615             :     case oLogFile:
     616           0 :       if (!reread)
     617           0 :         return 0; /* not handeld */
     618           0 :       if (!current_logfile || !pargs->r.ret_str
     619           0 :           || strcmp (current_logfile, pargs->r.ret_str))
     620             :         {
     621           0 :           log_set_file (pargs->r.ret_str);
     622           0 :           xfree (current_logfile);
     623           0 :           current_logfile = xtrystrdup (pargs->r.ret_str);
     624             :         }
     625           0 :       break;
     626             : 
     627           3 :     case oNoGrab: opt.no_grab = 1; break;
     628             : 
     629           3 :     case oPinentryProgram: opt.pinentry_program = pargs->r.ret_str; break;
     630           0 :     case oPinentryTouchFile: opt.pinentry_touch_file = pargs->r.ret_str; break;
     631             :     case oPinentryInvisibleChar:
     632           0 :       xfree (opt.pinentry_invisible_char);
     633           0 :       opt.pinentry_invisible_char = xtrystrdup (pargs->r.ret_str); break;
     634             :       break;
     635           0 :     case oScdaemonProgram: opt.scdaemon_program = pargs->r.ret_str; break;
     636           0 :     case oDisableScdaemon: opt.disable_scdaemon = 1; break;
     637           0 :     case oDisableCheckOwnSocket: disable_check_own_socket = 1; break;
     638             : 
     639           0 :     case oDefCacheTTL: opt.def_cache_ttl = pargs->r.ret_ulong; break;
     640           0 :     case oDefCacheTTLSSH: opt.def_cache_ttl_ssh = pargs->r.ret_ulong; break;
     641           0 :     case oMaxCacheTTL: opt.max_cache_ttl = pargs->r.ret_ulong; break;
     642           0 :     case oMaxCacheTTLSSH: opt.max_cache_ttl_ssh = pargs->r.ret_ulong; break;
     643             : 
     644             :     case oEnforcePassphraseConstraints:
     645           0 :       opt.enforce_passphrase_constraints=1;
     646           0 :       break;
     647           0 :     case oMinPassphraseLen: opt.min_passphrase_len = pargs->r.ret_ulong; break;
     648             :     case oMinPassphraseNonalpha:
     649           0 :       opt.min_passphrase_nonalpha = pargs->r.ret_ulong;
     650           0 :       break;
     651             :     case oCheckPassphrasePattern:
     652           0 :       opt.check_passphrase_pattern = pargs->r.ret_str;
     653           0 :       break;
     654             :     case oMaxPassphraseDays:
     655           0 :       opt.max_passphrase_days = pargs->r.ret_ulong;
     656           0 :       break;
     657             :     case oEnablePassphraseHistory:
     658           0 :       opt.enable_passhrase_history = 1;
     659           0 :       break;
     660             : 
     661           0 :     case oIgnoreCacheForSigning: opt.ignore_cache_for_signing = 1; break;
     662             : 
     663           0 :     case oAllowMarkTrusted: opt.allow_mark_trusted = 1; break;
     664           0 :     case oNoAllowMarkTrusted: opt.allow_mark_trusted = 0; break;
     665             : 
     666           3 :     case oAllowPresetPassphrase: opt.allow_preset_passphrase = 1; break;
     667             : 
     668           0 :     case oAllowLoopbackPinentry: opt.allow_loopback_pinentry = 1; break;
     669             : 
     670           0 :     case oNoAllowExternalCache: opt.allow_external_cache = 0;
     671           0 :       break;
     672             : 
     673           0 :     case oAllowEmacsPinentry: opt.allow_emacs_pinentry = 1;
     674           0 :       break;
     675             : 
     676             :     default:
     677           7 :       return 0; /* not handled */
     678             :     }
     679             : 
     680          11 :   return 1; /* handled */
     681             : }
     682             : 
     683             : 
     684             : /* Fixup some options after all have been processed.  */
     685             : static void
     686           3 : finalize_rereadable_options (void)
     687             : {
     688           3 : }
     689             : 
     690             : 
     691             : 
     692             : /* The main entry point.  */
     693             : int
     694           3 : main (int argc, char **argv )
     695             : {
     696             :   ARGPARSE_ARGS pargs;
     697             :   int orig_argc;
     698             :   char **orig_argv;
     699           3 :   FILE *configfp = NULL;
     700           3 :   char *configname = NULL;
     701             :   const char *shell;
     702             :   unsigned configlineno;
     703           3 :   int parse_debug = 0;
     704           3 :   int default_config =1;
     705           3 :   int pipe_server = 0;
     706           3 :   int is_daemon = 0;
     707           3 :   int nodetach = 0;
     708           3 :   int csh_style = 0;
     709           3 :   char *logfile = NULL;
     710           3 :   int debug_wait = 0;
     711           3 :   int gpgconf_list = 0;
     712             :   gpg_error_t err;
     713             :   struct assuan_malloc_hooks malloc_hooks;
     714             : 
     715           3 :   early_system_init ();
     716             : 
     717             :   /* Before we do anything else we save the list of currently open
     718             :      file descriptors and the signal mask.  This info is required to
     719             :      do the exec call properly. */
     720           3 :   startup_fd_list = get_all_open_fds ();
     721             : #ifdef HAVE_SIGPROCMASK
     722           3 :   if (!sigprocmask (SIG_UNBLOCK, NULL, &startup_signal_mask))
     723           3 :     startup_signal_mask_valid = 1;
     724             : #endif /*HAVE_SIGPROCMASK*/
     725             : 
     726             :   /* Set program name etc.  */
     727           3 :   set_strusage (my_strusage);
     728           3 :   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
     729             :   /* Please note that we may running SUID(ROOT), so be very CAREFUL
     730             :      when adding any stuff between here and the call to INIT_SECMEM()
     731             :      somewhere after the option parsing */
     732           3 :   log_set_prefix (GPG_AGENT_NAME, GPGRT_LOG_WITH_PREFIX|GPGRT_LOG_WITH_PID);
     733             : 
     734             :   /* Make sure that our subsystems are ready.  */
     735           3 :   i18n_init ();
     736           3 :   init_common_subsystems (&argc, &argv);
     737             : 
     738           3 :   npth_init ();
     739             : 
     740             :   /* Check that the libraries are suitable.  Do it here because
     741             :      the option parsing may need services of the library. */
     742           3 :   if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
     743             :     {
     744           0 :       log_fatal( _("%s is too old (need %s, have %s)\n"), "libgcrypt",
     745             :                  NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
     746             :     }
     747             : 
     748           3 :   malloc_hooks.malloc = gcry_malloc;
     749           3 :   malloc_hooks.realloc = gcry_realloc;
     750           3 :   malloc_hooks.free = gcry_free;
     751           3 :   assuan_set_malloc_hooks (&malloc_hooks);
     752           3 :   assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
     753           3 :   assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
     754           3 :   assuan_sock_init ();
     755           3 :   setup_libassuan_logging (&opt.debug);
     756             : 
     757           3 :   setup_libgcrypt_logging ();
     758           3 :   gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
     759             : 
     760           3 :   disable_core_dumps ();
     761             : 
     762             :   /* Set default options.  */
     763           3 :   parse_rereadable_options (NULL, 0); /* Reset them to default values. */
     764             : 
     765           3 :   shell = getenv ("SHELL");
     766           3 :   if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
     767           0 :     csh_style = 1;
     768             : 
     769           3 :   opt.homedir = default_homedir ();
     770             : 
     771             :   /* Record some of the original environment strings. */
     772             :   {
     773             :     const char *s;
     774             :     int idx;
     775             :     static const char *names[] =
     776             :       { "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL };
     777             : 
     778           3 :     err = 0;
     779           3 :     opt.startup_env = session_env_new ();
     780           3 :     if (!opt.startup_env)
     781           0 :       err = gpg_error_from_syserror ();
     782          15 :     for (idx=0; !err && names[idx]; idx++)
     783             :       {
     784          12 :         s = getenv (names[idx]);
     785          12 :         if (s)
     786           6 :           err = session_env_setenv (opt.startup_env, names[idx], s);
     787             :       }
     788           3 :     if (!err)
     789             :       {
     790           3 :         s = gnupg_ttyname (0);
     791           3 :         if (s)
     792           2 :           err = session_env_setenv (opt.startup_env, "GPG_TTY", s);
     793             :       }
     794           3 :     if (err)
     795           0 :       log_fatal ("error recording startup environment: %s\n",
     796             :                  gpg_strerror (err));
     797             : 
     798             :     /* Fixme: Better use the locale function here.  */
     799           3 :     opt.startup_lc_ctype = getenv ("LC_CTYPE");
     800           3 :     if (opt.startup_lc_ctype)
     801           3 :       opt.startup_lc_ctype = xstrdup (opt.startup_lc_ctype);
     802           3 :     opt.startup_lc_messages = getenv ("LC_MESSAGES");
     803           3 :     if (opt.startup_lc_messages)
     804           0 :       opt.startup_lc_messages = xstrdup (opt.startup_lc_messages);
     805             :   }
     806             : 
     807             :   /* Check whether we have a config file on the commandline */
     808           3 :   orig_argc = argc;
     809           3 :   orig_argv = argv;
     810           3 :   pargs.argc = &argc;
     811           3 :   pargs.argv = &argv;
     812           3 :   pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
     813          12 :   while (arg_parse( &pargs, opts))
     814             :     {
     815           6 :       if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
     816           0 :         parse_debug++;
     817           6 :       else if (pargs.r_opt == oOptions)
     818             :         { /* yes there is one, so we do not try the default one, but
     819             :              read the option file when it is encountered at the
     820             :              commandline */
     821           0 :           default_config = 0;
     822             :         }
     823           6 :         else if (pargs.r_opt == oNoOptions)
     824           0 :           default_config = 0; /* --no-options */
     825           6 :         else if (pargs.r_opt == oHomedir)
     826           1 :           opt.homedir = pargs.r.ret_str;
     827           5 :         else if (pargs.r_opt == oDebugQuickRandom)
     828             :           {
     829           1 :             gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
     830             :           }
     831             : 
     832             :     }
     833             : 
     834             :   /* Initialize the secure memory. */
     835           3 :   gcry_control (GCRYCTL_INIT_SECMEM, 32768, 0);
     836           3 :   maybe_setuid = 0;
     837             : 
     838             :   /*
     839             :      Now we are now working under our real uid
     840             :   */
     841             : 
     842           3 :   if (default_config)
     843           3 :     configname = make_filename (opt.homedir, GPG_AGENT_NAME EXTSEP_S "conf",
     844             :                                 NULL );
     845             : 
     846           3 :   argc = orig_argc;
     847           3 :   argv = orig_argv;
     848           3 :   pargs.argc = &argc;
     849           3 :   pargs.argv = &argv;
     850           3 :   pargs.flags=  1;  /* do not remove the args */
     851             :  next_pass:
     852           6 :   if (configname)
     853             :     {
     854           3 :       configlineno = 0;
     855           3 :       configfp = fopen (configname, "r");
     856           3 :       if (!configfp)
     857             :         {
     858           0 :           if (default_config)
     859             :             {
     860           0 :               if( parse_debug )
     861           0 :                 log_info (_("Note: no default option file '%s'\n"),
     862             :                           configname );
     863             :               /* Save the default conf file name so that
     864             :                  reread_configuration is able to test whether the
     865             :                  config file has been created in the meantime.  */
     866           0 :               xfree (config_filename);
     867           0 :               config_filename = configname;
     868           0 :               configname = NULL;
     869             :             }
     870             :           else
     871             :             {
     872           0 :               log_error (_("option file '%s': %s\n"),
     873           0 :                          configname, strerror(errno) );
     874           0 :               exit(2);
     875             :             }
     876           0 :           xfree (configname);
     877           0 :           configname = NULL;
     878             :         }
     879           3 :       if (parse_debug && configname )
     880           0 :         log_info (_("reading options from '%s'\n"), configname );
     881           3 :       default_config = 0;
     882             :     }
     883             : 
     884          30 :   while (optfile_parse( configfp, configname, &configlineno, &pargs, opts) )
     885             :     {
     886          18 :       if (parse_rereadable_options (&pargs, 0))
     887          11 :         continue; /* Already handled */
     888           7 :       switch (pargs.r_opt)
     889             :         {
     890           0 :         case aGPGConfList: gpgconf_list = 1; break;
     891           0 :         case aGPGConfTest: gpgconf_list = 2; break;
     892           0 :         case aUseStandardSocketP: gpgconf_list = 3; break;
     893           0 :         case oBatch: opt.batch=1; break;
     894             : 
     895           0 :         case oDebugWait: debug_wait = pargs.r.ret_int; break;
     896             : 
     897             :         case oOptions:
     898             :           /* config files may not be nested (silently ignore them) */
     899           0 :           if (!configfp)
     900             :             {
     901           0 :                 xfree(configname);
     902           0 :                 configname = xstrdup(pargs.r.ret_str);
     903           0 :                 goto next_pass;
     904             :             }
     905           0 :           break;
     906           0 :         case oNoGreeting: /* Dummy option.  */ break;
     907           0 :         case oNoVerbose: opt.verbose = 0; break;
     908           0 :         case oNoOptions: break; /* no-options */
     909           1 :         case oHomedir: opt.homedir = pargs.r.ret_str; break;
     910           0 :         case oNoDetach: nodetach = 1; break;
     911           0 :         case oLogFile: logfile = pargs.r.ret_str; break;
     912           0 :         case oCsh: csh_style = 1; break;
     913           0 :         case oSh: csh_style = 0; break;
     914           0 :         case oServer: pipe_server = 1; break;
     915           1 :         case oDaemon: is_daemon = 1; break;
     916             : 
     917           0 :         case oDisplay: default_display = xstrdup (pargs.r.ret_str); break;
     918           0 :         case oTTYname: default_ttyname = xstrdup (pargs.r.ret_str); break;
     919           0 :         case oTTYtype: default_ttytype = xstrdup (pargs.r.ret_str); break;
     920           0 :         case oLCctype: default_lc_ctype = xstrdup (pargs.r.ret_str); break;
     921           0 :         case oLCmessages: default_lc_messages = xstrdup (pargs.r.ret_str);
     922           0 :           break;
     923           0 :         case oXauthority: default_xauthority = xstrdup (pargs.r.ret_str);
     924           0 :           break;
     925             : 
     926             :         case oUseStandardSocket:
     927             :         case oNoUseStandardSocket:
     928           4 :           obsolete_option (configname, configlineno, "use-standard-socket");
     929           4 :           break;
     930             : 
     931             :         case oFakedSystemTime:
     932             :           {
     933           0 :             time_t faked_time = isotime2epoch (pargs.r.ret_str);
     934           0 :             if (faked_time == (time_t)(-1))
     935           0 :               faked_time = (time_t)strtoul (pargs.r.ret_str, NULL, 10);
     936           0 :             gnupg_set_time (faked_time, 0);
     937             :           }
     938           0 :           break;
     939             : 
     940           0 :         case oKeepTTY: opt.keep_tty = 1; break;
     941           0 :         case oKeepDISPLAY: opt.keep_display = 1; break;
     942             : 
     943             :         case oSSHSupport:
     944           0 :           ssh_support = 1;
     945           0 :           break;
     946             :         case oPuttySupport:
     947             : #        ifdef HAVE_W32_SYSTEM
     948             :           putty_support = 1;
     949             : #        endif
     950           0 :           break;
     951             : 
     952             :         case oExtraSocket:
     953           0 :           opt.extra_socket = 1;  /* (1 = points into argv)  */
     954           0 :           socket_name_extra = pargs.r.ret_str;
     955           0 :           break;
     956             : 
     957             :         case oBrowserSocket:
     958           0 :           opt.browser_socket = 1;  /* (1 = points into argv)  */
     959           0 :           socket_name_browser = pargs.r.ret_str;
     960           0 :           break;
     961             : 
     962             :         case oDebugQuickRandom:
     963             :           /* Only used by the first stage command line parser.  */
     964           1 :           break;
     965             : 
     966             :         case oWriteEnvFile:
     967           0 :           obsolete_option (configname, configlineno, "write-env-file");
     968           0 :           break;
     969             : 
     970           0 :         default : pargs.err = configfp? 1:2; break;
     971             :         }
     972             :     }
     973           6 :   if (configfp)
     974             :     {
     975           3 :       fclose( configfp );
     976           3 :       configfp = NULL;
     977             :       /* Keep a copy of the name so that it can be read on SIGHUP. */
     978           3 :       if (config_filename != configname)
     979             :         {
     980           3 :           xfree (config_filename);
     981           3 :           config_filename = configname;
     982             :         }
     983           3 :       configname = NULL;
     984           3 :       goto next_pass;
     985             :     }
     986             : 
     987           3 :   xfree (configname);
     988           3 :   configname = NULL;
     989           3 :   if (log_get_errorcount(0))
     990           0 :     exit(2);
     991             : 
     992           3 :   finalize_rereadable_options ();
     993             : 
     994             :   /* Turn the homedir into an absolute one. */
     995           3 :   opt.homedir = make_absfilename (opt.homedir, NULL);
     996             : 
     997             :   /* Print a warning if an argument looks like an option.  */
     998           3 :   if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
     999             :     {
    1000             :       int i;
    1001             : 
    1002           1 :       for (i=0; i < argc; i++)
    1003           0 :         if (argv[i][0] == '-' && argv[i][1] == '-')
    1004           0 :           log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
    1005             :     }
    1006             : 
    1007             : #ifdef ENABLE_NLS
    1008             :   /* gpg-agent usually does not output any messages because it runs in
    1009             :      the background.  For log files it is acceptable to have messages
    1010             :      always encoded in utf-8.  We switch here to utf-8, so that
    1011             :      commands like --help still give native messages.  It is far
    1012             :      easier to switch only once instead of for every message and it
    1013             :      actually helps when more then one thread is active (avoids an
    1014             :      extra copy step). */
    1015           3 :     bind_textdomain_codeset (PACKAGE_GT, "UTF-8");
    1016             : #endif
    1017             : 
    1018           3 :   if (!pipe_server && !is_daemon && !gpgconf_list)
    1019             :     {
    1020             :      /* We have been called without any options and thus we merely
    1021             :         check whether an agent is already running.  We do this right
    1022             :         here so that we don't clobber a logfile with this check but
    1023             :         print the status directly to stderr. */
    1024           2 :       opt.debug = 0;
    1025           2 :       set_debug ();
    1026           2 :       check_for_running_agent (0);
    1027           2 :       agent_exit (0);
    1028             :     }
    1029             : 
    1030           1 :   set_debug ();
    1031             : 
    1032           1 :   if (atexit (cleanup))
    1033             :     {
    1034           0 :       log_error ("atexit failed\n");
    1035           0 :       cleanup ();
    1036           0 :       exit (1);
    1037             :     }
    1038             : 
    1039           1 :   initialize_module_cache ();
    1040           1 :   initialize_module_call_pinentry ();
    1041           1 :   initialize_module_call_scd ();
    1042           1 :   initialize_module_trustlist ();
    1043             : 
    1044             :   /* Try to create missing directories. */
    1045           1 :   create_directories ();
    1046             : 
    1047           1 :   if (debug_wait && pipe_server)
    1048             :     {
    1049           0 :       log_debug ("waiting for debugger - my pid is %u .....\n",
    1050           0 :                  (unsigned int)getpid());
    1051           0 :       gnupg_sleep (debug_wait);
    1052           0 :       log_debug ("... okay\n");
    1053             :     }
    1054             : 
    1055           1 :   if (gpgconf_list == 3)
    1056             :     {
    1057             :       /* We now use the standard socket always - return true for
    1058             :          backward compatibility.  */
    1059           0 :       agent_exit (0);
    1060             :     }
    1061           1 :   else if (gpgconf_list == 2)
    1062           0 :     agent_exit (0);
    1063           1 :   else if (gpgconf_list)
    1064             :     {
    1065             :       char *filename;
    1066             :       char *filename_esc;
    1067             : 
    1068             :       /* List options and default values in the GPG Conf format.  */
    1069           0 :       filename = make_filename (opt.homedir, GPG_AGENT_NAME EXTSEP_S "conf",
    1070             :                                 NULL );
    1071           0 :       filename_esc = percent_escape (filename, NULL);
    1072             : 
    1073           0 :       es_printf ("%s-%s.conf:%lu:\"%s\n",
    1074             :                  GPGCONF_NAME, GPG_AGENT_NAME,
    1075             :                  GC_OPT_FLAG_DEFAULT, filename_esc);
    1076           0 :       xfree (filename);
    1077           0 :       xfree (filename_esc);
    1078             : 
    1079           0 :       es_printf ("verbose:%lu:\n"
    1080             :               "quiet:%lu:\n"
    1081             :               "debug-level:%lu:\"none:\n"
    1082             :               "log-file:%lu:\n",
    1083             :               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME,
    1084             :               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME,
    1085             :               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME,
    1086             :               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME );
    1087           0 :       es_printf ("default-cache-ttl:%lu:%d:\n",
    1088             :               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, DEFAULT_CACHE_TTL );
    1089           0 :       es_printf ("default-cache-ttl-ssh:%lu:%d:\n",
    1090             :               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, DEFAULT_CACHE_TTL_SSH );
    1091           0 :       es_printf ("max-cache-ttl:%lu:%d:\n",
    1092             :               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, MAX_CACHE_TTL );
    1093           0 :       es_printf ("max-cache-ttl-ssh:%lu:%d:\n",
    1094             :               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, MAX_CACHE_TTL_SSH );
    1095           0 :       es_printf ("enforce-passphrase-constraints:%lu:\n",
    1096             :               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
    1097           0 :       es_printf ("min-passphrase-len:%lu:%d:\n",
    1098             :               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, MIN_PASSPHRASE_LEN );
    1099           0 :       es_printf ("min-passphrase-nonalpha:%lu:%d:\n",
    1100             :               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME,
    1101             :               MIN_PASSPHRASE_NONALPHA);
    1102           0 :       es_printf ("check-passphrase-pattern:%lu:\n",
    1103             :               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME);
    1104           0 :       es_printf ("max-passphrase-days:%lu:%d:\n",
    1105             :               GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME,
    1106             :               MAX_PASSPHRASE_DAYS);
    1107           0 :       es_printf ("enable-passphrase-history:%lu:\n",
    1108             :               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
    1109           0 :       es_printf ("no-grab:%lu:\n",
    1110             :               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
    1111           0 :       es_printf ("ignore-cache-for-signing:%lu:\n",
    1112             :               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
    1113           0 :       es_printf ("no-allow-external-cache:%lu:\n",
    1114             :               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
    1115           0 :       es_printf ("no-allow-mark-trusted:%lu:\n",
    1116             :               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
    1117           0 :       es_printf ("disable-scdaemon:%lu:\n",
    1118             :               GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
    1119           0 :       es_printf ("enable-ssh-support:%lu:\n", GC_OPT_FLAG_NONE);
    1120             : #ifdef HAVE_W32_SYSTEM
    1121             :       es_printf ("enable-putty-support:%lu:\n", GC_OPT_FLAG_NONE);
    1122             : #endif
    1123           0 :       es_printf ("allow-loopback-pinentry:%lu:\n",
    1124             :                  GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
    1125           0 :       es_printf ("allow-emacs-pinentry:%lu:\n",
    1126             :                  GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME);
    1127             : 
    1128           0 :       agent_exit (0);
    1129             :     }
    1130             : 
    1131             :   /* Now start with logging to a file if this is desired. */
    1132           1 :   if (logfile)
    1133             :     {
    1134           0 :       log_set_file (logfile);
    1135           0 :       log_set_prefix (NULL, (GPGRT_LOG_WITH_PREFIX
    1136             :                              | GPGRT_LOG_WITH_TIME
    1137             :                              | GPGRT_LOG_WITH_PID));
    1138           0 :       current_logfile = xstrdup (logfile);
    1139             :     }
    1140             : 
    1141             :   /* Make sure that we have a default ttyname. */
    1142           1 :   if (!default_ttyname && gnupg_ttyname (1))
    1143           0 :     default_ttyname = xstrdup (gnupg_ttyname (1));
    1144           1 :   if (!default_ttytype && getenv ("TERM"))
    1145           1 :     default_ttytype = xstrdup (getenv ("TERM"));
    1146             : 
    1147             : 
    1148           1 :   if (pipe_server)
    1149             :     {
    1150             :       /* This is the simple pipe based server */
    1151             :       ctrl_t ctrl;
    1152             : 
    1153           0 :       ctrl = xtrycalloc (1, sizeof *ctrl);
    1154           0 :       if (!ctrl)
    1155             :         {
    1156           0 :           log_error ("error allocating connection control data: %s\n",
    1157           0 :                      strerror (errno) );
    1158           0 :           agent_exit (1);
    1159             :         }
    1160           0 :       ctrl->session_env = session_env_new ();
    1161           0 :       if (!ctrl->session_env)
    1162             :         {
    1163           0 :           log_error ("error allocating session environment block: %s\n",
    1164           0 :                      strerror (errno) );
    1165           0 :           xfree (ctrl);
    1166           0 :           agent_exit (1);
    1167             :         }
    1168           0 :       agent_init_default_ctrl (ctrl);
    1169           0 :       start_command_handler (ctrl, GNUPG_INVALID_FD, GNUPG_INVALID_FD);
    1170           0 :       agent_deinit_default_ctrl (ctrl);
    1171           0 :       xfree (ctrl);
    1172             :     }
    1173           1 :   else if (!is_daemon)
    1174             :     ; /* NOTREACHED */
    1175             :   else
    1176             :     { /* Regular server mode */
    1177             :       gnupg_fd_t fd;
    1178           1 :       gnupg_fd_t fd_extra = GNUPG_INVALID_FD;
    1179           1 :       gnupg_fd_t fd_browser = GNUPG_INVALID_FD;
    1180           1 :       gnupg_fd_t fd_ssh = GNUPG_INVALID_FD;
    1181             :       pid_t pid;
    1182             : 
    1183             :       /* Remove the DISPLAY variable so that a pinentry does not
    1184             :          default to a specific display.  There is still a default
    1185             :          display when gpg-agent was started using --display or a
    1186             :          client requested this using an OPTION command.  Note, that we
    1187             :          don't do this when running in reverse daemon mode (i.e. when
    1188             :          exec the program given as arguments). */
    1189             : #ifndef HAVE_W32_SYSTEM
    1190           1 :       if (!opt.keep_display && !argc)
    1191           1 :         gnupg_unsetenv ("DISPLAY");
    1192             : #endif
    1193             : 
    1194             :       /* Remove the INSIDE_EMACS variable so that a pinentry does not
    1195             :          always try to interact with Emacs.  The variable is set when
    1196             :          a client requested this using an OPTION command.  */
    1197           1 :       gnupg_unsetenv ("INSIDE_EMACS");
    1198             : 
    1199             :       /* Create the sockets.  */
    1200           1 :       socket_name = create_socket_name (GPG_AGENT_SOCK_NAME, 1);
    1201           1 :       fd = create_server_socket (socket_name, 1, 0,
    1202             :                                  &redir_socket_name, &socket_nonce);
    1203             : 
    1204           1 :       if (opt.extra_socket)
    1205             :         {
    1206           0 :           socket_name_extra = create_socket_name (socket_name_extra, 0);
    1207           0 :           opt.extra_socket = 2; /* Indicate that it has been malloced.  */
    1208           0 :           fd_extra = create_server_socket (socket_name_extra, 0, 0,
    1209             :                                            &redir_socket_name_extra,
    1210             :                                            &socket_nonce_extra);
    1211             :         }
    1212             : 
    1213           1 :       if (opt.browser_socket)
    1214             :         {
    1215           0 :           socket_name_browser = create_socket_name (socket_name_browser, 0);
    1216           0 :           opt.browser_socket = 2; /* Indicate that it has been malloced.  */
    1217           0 :           fd_browser = create_server_socket (socket_name_browser, 0, 0,
    1218             :                                              &redir_socket_name_browser,
    1219             :                                              &socket_nonce_browser);
    1220             :         }
    1221             : 
    1222           1 :       if (ssh_support)
    1223             :         {
    1224           0 :           socket_name_ssh = create_socket_name (GPG_AGENT_SSH_SOCK_NAME, 1);
    1225           0 :           fd_ssh = create_server_socket (socket_name_ssh, 0, 1,
    1226             :                                          &redir_socket_name_ssh,
    1227             :                                          &socket_nonce_ssh);
    1228             :         }
    1229             : 
    1230             :       /* If we are going to exec a program in the parent, we record
    1231             :          the PID, so that the child may check whether the program is
    1232             :          still alive. */
    1233           1 :       if (argc)
    1234           0 :         parent_pid = getpid ();
    1235             : 
    1236           1 :       fflush (NULL);
    1237             : #ifdef HAVE_W32_SYSTEM
    1238             :       (void)csh_style;
    1239             :       (void)nodetach;
    1240             :       pid = getpid ();
    1241             : #else /*!HAVE_W32_SYSTEM*/
    1242           1 :       pid = fork ();
    1243           2 :       if (pid == (pid_t)-1)
    1244             :         {
    1245           0 :           log_fatal ("fork failed: %s\n", strerror (errno) );
    1246             :           exit (1);
    1247             :         }
    1248           2 :       else if (pid)
    1249             :         { /* We are the parent */
    1250             :           char *infostr_ssh_sock, *infostr_ssh_valid;
    1251             : 
    1252             :           /* Close the socket FD. */
    1253           1 :           close (fd);
    1254             : 
    1255             :           /* The signal mask might not be correct right now and thus
    1256             :              we restore it.  That is not strictly necessary but some
    1257             :              programs falsely assume a cleared signal mask.  */
    1258             : 
    1259             : #ifdef HAVE_SIGPROCMASK
    1260           1 :           if (startup_signal_mask_valid)
    1261             :             {
    1262           1 :               if (sigprocmask (SIG_SETMASK, &startup_signal_mask, NULL))
    1263           0 :                 log_error ("error restoring signal mask: %s\n",
    1264           0 :                            strerror (errno));
    1265             :             }
    1266             :           else
    1267           0 :             log_info ("no saved signal mask\n");
    1268             : #endif /*HAVE_SIGPROCMASK*/
    1269             : 
    1270             :           /* Create the SSH info string if enabled. */
    1271           1 :           if (ssh_support)
    1272             :             {
    1273           0 :               if (asprintf (&infostr_ssh_sock, "SSH_AUTH_SOCK=%s",
    1274             :                             socket_name_ssh) < 0)
    1275             :                 {
    1276           0 :                   log_error ("out of core\n");
    1277           0 :                   kill (pid, SIGTERM);
    1278           0 :                   exit (1);
    1279             :                 }
    1280           0 :               if (asprintf (&infostr_ssh_valid, "gnupg_SSH_AUTH_SOCK_by=%lu",
    1281           0 :                             (unsigned long)getpid()) < 0)
    1282             :                 {
    1283           0 :                   log_error ("out of core\n");
    1284           0 :                   kill (pid, SIGTERM);
    1285           0 :                   exit (1);
    1286             :                 }
    1287             :             }
    1288             : 
    1289           1 :           *socket_name = 0; /* Don't let cleanup() remove the socket -
    1290             :                                the child should do this from now on */
    1291           1 :           if (opt.extra_socket)
    1292           0 :             *socket_name_extra = 0;
    1293           1 :           if (opt.browser_socket)
    1294           0 :             *socket_name_browser = 0;
    1295           1 :           if (ssh_support)
    1296           0 :             *socket_name_ssh = 0;
    1297             : 
    1298           1 :           if (argc)
    1299             :             { /* Run the program given on the commandline.  */
    1300           0 :               if (ssh_support && (putenv (infostr_ssh_sock)
    1301           0 :                                   || putenv (infostr_ssh_valid)))
    1302             :                 {
    1303           0 :                   log_error ("failed to set environment: %s\n",
    1304           0 :                              strerror (errno) );
    1305           0 :                   kill (pid, SIGTERM );
    1306           0 :                   exit (1);
    1307             :                 }
    1308             : 
    1309             :               /* Close all the file descriptors except the standard
    1310             :                  ones and those open at startup.  We explicitly don't
    1311             :                  close 0,1,2 in case something went wrong collecting
    1312             :                  them at startup.  */
    1313           0 :               close_all_fds (3, startup_fd_list);
    1314             : 
    1315             :               /* Run the command.  */
    1316           0 :               execvp (argv[0], argv);
    1317           0 :               log_error ("failed to run the command: %s\n", strerror (errno));
    1318           0 :               kill (pid, SIGTERM);
    1319           0 :               exit (1);
    1320             :             }
    1321             :           else
    1322             :             {
    1323             :               /* Print the environment string, so that the caller can use
    1324             :                  shell's eval to set it */
    1325           1 :               if (csh_style)
    1326             :                 {
    1327           0 :                   if (ssh_support)
    1328             :                     {
    1329           0 :                       *strchr (infostr_ssh_sock, '=') = ' ';
    1330           0 :                       es_printf ("setenv %s;\n", infostr_ssh_sock);
    1331             :                     }
    1332             :                 }
    1333             :               else
    1334             :                 {
    1335           1 :                   if (ssh_support)
    1336             :                     {
    1337           0 :                       es_printf ("%s; export SSH_AUTH_SOCK;\n",
    1338             :                                  infostr_ssh_sock);
    1339             :                     }
    1340             :                 }
    1341           1 :               if (ssh_support)
    1342             :                 {
    1343           0 :                   xfree (infostr_ssh_sock);
    1344           0 :                   xfree (infostr_ssh_valid);
    1345             :                 }
    1346           1 :               exit (0);
    1347             :             }
    1348             :           /*NOTREACHED*/
    1349             :         } /* End parent */
    1350             : 
    1351             :       /*
    1352             :          This is the child
    1353             :        */
    1354             : 
    1355             :       /* Detach from tty and put process into a new session */
    1356           1 :       if (!nodetach )
    1357             :         {
    1358             :           int i;
    1359             :           unsigned int oldflags;
    1360             : 
    1361             :           /* Close stdin, stdout and stderr unless it is the log stream */
    1362           4 :           for (i=0; i <= 2; i++)
    1363             :             {
    1364           3 :               if (!log_test_fd (i) && i != fd )
    1365             :                 {
    1366           2 :                   if ( ! close (i)
    1367           2 :                        && open ("/dev/null", i? O_WRONLY : O_RDONLY) == -1)
    1368             :                     {
    1369           0 :                       log_error ("failed to open '%s': %s\n",
    1370           0 :                                  "/dev/null", strerror (errno));
    1371           0 :                       cleanup ();
    1372           0 :                       exit (1);
    1373             :                     }
    1374             :                 }
    1375             :             }
    1376           1 :           if (setsid() == -1)
    1377             :             {
    1378           0 :               log_error ("setsid() failed: %s\n", strerror(errno) );
    1379           0 :               cleanup ();
    1380           0 :               exit (1);
    1381             :             }
    1382             : 
    1383           1 :           log_get_prefix (&oldflags);
    1384           1 :           log_set_prefix (NULL, oldflags | GPGRT_LOG_RUN_DETACHED);
    1385           1 :           opt.running_detached = 1;
    1386             :         }
    1387             : 
    1388           1 :       if (chdir("/"))
    1389             :         {
    1390           0 :           log_error ("chdir to / failed: %s\n", strerror (errno));
    1391           0 :           exit (1);
    1392             :         }
    1393             : 
    1394             :       {
    1395             :         struct sigaction sa;
    1396             : 
    1397           1 :         sa.sa_handler = SIG_IGN;
    1398           1 :         sigemptyset (&sa.sa_mask);
    1399           1 :         sa.sa_flags = 0;
    1400           1 :         sigaction (SIGPIPE, &sa, NULL);
    1401             :       }
    1402             : #endif /*!HAVE_W32_SYSTEM*/
    1403             : 
    1404           1 :       log_info ("%s %s started\n", strusage(11), strusage(13) );
    1405           1 :       handle_connections (fd, fd_extra, fd_browser, fd_ssh);
    1406           0 :       assuan_sock_close (fd);
    1407             :     }
    1408             : 
    1409           0 :   return 0;
    1410             : }
    1411             : 
    1412             : 
    1413             : /* Exit entry point.  This function should be called instead of a
    1414             :    plain exit.  */
    1415             : void
    1416           3 : agent_exit (int rc)
    1417             : {
    1418             :   /*FIXME: update_random_seed_file();*/
    1419             : 
    1420             :   /* We run our cleanup handler because that may close cipher contexts
    1421             :      stored in secure memory and thus this needs to be done before we
    1422             :      explicitly terminate secure memory.  */
    1423           3 :   cleanup ();
    1424             : 
    1425             : #if 1
    1426             :   /* at this time a bit annoying */
    1427           3 :   if (opt.debug & DBG_MEMSTAT_VALUE)
    1428             :     {
    1429           0 :       gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
    1430           0 :       gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
    1431             :     }
    1432           3 :   if (opt.debug)
    1433           0 :     gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
    1434             : #endif
    1435           3 :   gcry_control (GCRYCTL_TERM_SECMEM );
    1436           3 :   rc = rc? rc : log_get_errorcount(0)? 2 : 0;
    1437           3 :   exit (rc);
    1438             : }
    1439             : 
    1440             : 
    1441             : /* Each thread has its own local variables conveyed by a control
    1442             :    structure usually identified by an argument named CTRL.  This
    1443             :    function is called immediately after allocating the control
    1444             :    structure.  Its purpose is to setup the default values for that
    1445             :    structure.  Note that some values may have already been set.  */
    1446             : static void
    1447         404 : agent_init_default_ctrl (ctrl_t ctrl)
    1448             : {
    1449         404 :   assert (ctrl->session_env);
    1450             : 
    1451             :   /* Note we ignore malloc errors because we can't do much about it
    1452             :      and the request will fail anyway shortly after this
    1453             :      initialization. */
    1454         404 :   session_env_setenv (ctrl->session_env, "DISPLAY", default_display);
    1455         404 :   session_env_setenv (ctrl->session_env, "GPG_TTY", default_ttyname);
    1456         404 :   session_env_setenv (ctrl->session_env, "TERM", default_ttytype);
    1457         404 :   session_env_setenv (ctrl->session_env, "XAUTHORITY", default_xauthority);
    1458         404 :   session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", NULL);
    1459             : 
    1460         404 :   if (ctrl->lc_ctype)
    1461           0 :     xfree (ctrl->lc_ctype);
    1462         404 :   ctrl->lc_ctype = default_lc_ctype? xtrystrdup (default_lc_ctype) : NULL;
    1463             : 
    1464         404 :   if (ctrl->lc_messages)
    1465           0 :     xfree (ctrl->lc_messages);
    1466         808 :   ctrl->lc_messages = default_lc_messages? xtrystrdup (default_lc_messages)
    1467         404 :                                     /**/ : NULL;
    1468         404 :   ctrl->cache_ttl_opt_preset = CACHE_TTL_OPT_PRESET;
    1469         404 : }
    1470             : 
    1471             : 
    1472             : /* Release all resources allocated by default in the control
    1473             :    structure.  This is the counterpart to agent_init_default_ctrl.  */
    1474             : static void
    1475         403 : agent_deinit_default_ctrl (ctrl_t ctrl)
    1476             : {
    1477         403 :   session_env_release (ctrl->session_env);
    1478             : 
    1479         403 :   if (ctrl->lc_ctype)
    1480         314 :     xfree (ctrl->lc_ctype);
    1481         403 :   if (ctrl->lc_messages)
    1482         314 :     xfree (ctrl->lc_messages);
    1483         403 : }
    1484             : 
    1485             : 
    1486             : /* Because the ssh protocol does not send us information about the
    1487             :    current TTY setting, we use this function to use those from startup
    1488             :    or those explictly set.  This is also used for the restricted mode
    1489             :    where we ignore requests to change the environment.  */
    1490             : gpg_error_t
    1491           0 : agent_copy_startup_env (ctrl_t ctrl)
    1492             : {
    1493             :   static const char *names[] =
    1494             :     {"GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL};
    1495           0 :   gpg_error_t err = 0;
    1496             :   int idx;
    1497             :   const char *value;
    1498             : 
    1499           0 :   for (idx=0; !err && names[idx]; idx++)
    1500           0 :       if ((value = session_env_getenv (opt.startup_env, names[idx])))
    1501           0 :       err = session_env_setenv (ctrl->session_env, names[idx], value);
    1502             : 
    1503           0 :   if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype)
    1504           0 :     if (!(ctrl->lc_ctype = xtrystrdup (opt.startup_lc_ctype)))
    1505           0 :       err = gpg_error_from_syserror ();
    1506             : 
    1507           0 :   if (!err && !ctrl->lc_messages && opt.startup_lc_messages)
    1508           0 :     if (!(ctrl->lc_messages = xtrystrdup (opt.startup_lc_messages)))
    1509           0 :       err = gpg_error_from_syserror ();
    1510             : 
    1511           0 :   if (err)
    1512           0 :     log_error ("error setting default session environment: %s\n",
    1513             :                gpg_strerror (err));
    1514             : 
    1515           0 :   return err;
    1516             : }
    1517             : 
    1518             : 
    1519             : /* Reread parts of the configuration.  Note, that this function is
    1520             :    obviously not thread-safe and should only be called from the PTH
    1521             :    signal handler.
    1522             : 
    1523             :    Fixme: Due to the way the argument parsing works, we create a
    1524             :    memory leak here for all string type arguments.  There is currently
    1525             :    no clean way to tell whether the memory for the argument has been
    1526             :    allocated or points into the process' original arguments.  Unless
    1527             :    we have a mechanism to tell this, we need to live on with this. */
    1528             : static void
    1529           0 : reread_configuration (void)
    1530             : {
    1531             :   ARGPARSE_ARGS pargs;
    1532             :   FILE *fp;
    1533           0 :   unsigned int configlineno = 0;
    1534             :   int dummy;
    1535             : 
    1536           0 :   if (!config_filename)
    1537           0 :     return; /* No config file. */
    1538             : 
    1539           0 :   fp = fopen (config_filename, "r");
    1540           0 :   if (!fp)
    1541             :     {
    1542           0 :       log_info (_("option file '%s': %s\n"),
    1543           0 :                 config_filename, strerror(errno) );
    1544           0 :       return;
    1545             :     }
    1546             : 
    1547           0 :   parse_rereadable_options (NULL, 1); /* Start from the default values. */
    1548             : 
    1549           0 :   memset (&pargs, 0, sizeof pargs);
    1550           0 :   dummy = 0;
    1551           0 :   pargs.argc = &dummy;
    1552           0 :   pargs.flags = 1;  /* do not remove the args */
    1553           0 :   while (optfile_parse (fp, config_filename, &configlineno, &pargs, opts) )
    1554             :     {
    1555           0 :       if (pargs.r_opt < -1)
    1556           0 :         pargs.err = 1; /* Print a warning. */
    1557             :       else /* Try to parse this option - ignore unchangeable ones. */
    1558           0 :         parse_rereadable_options (&pargs, 1);
    1559             :     }
    1560           0 :   fclose (fp);
    1561           0 :   finalize_rereadable_options ();
    1562           0 :   set_debug ();
    1563             : }
    1564             : 
    1565             : 
    1566             : /* Return the file name of the socket we are using for native
    1567             :    requests.  */
    1568             : const char *
    1569           0 : get_agent_socket_name (void)
    1570             : {
    1571           0 :   const char *s = socket_name;
    1572             : 
    1573           0 :   return (s && *s)? s : NULL;
    1574             : }
    1575             : 
    1576             : /* Return the file name of the socket we are using for SSH
    1577             :    requests.  */
    1578             : const char *
    1579           0 : get_agent_ssh_socket_name (void)
    1580             : {
    1581           0 :   const char *s = socket_name_ssh;
    1582             : 
    1583           0 :   return (s && *s)? s : NULL;
    1584             : }
    1585             : 
    1586             : 
    1587             : /* Under W32, this function returns the handle of the scdaemon
    1588             :    notification event.  Calling it the first time creates that
    1589             :    event.  */
    1590             : #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
    1591             : void *
    1592             : get_agent_scd_notify_event (void)
    1593             : {
    1594             :   static HANDLE the_event = INVALID_HANDLE_VALUE;
    1595             : 
    1596             :   if (the_event == INVALID_HANDLE_VALUE)
    1597             :     {
    1598             :       HANDLE h, h2;
    1599             :       SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE};
    1600             : 
    1601             :       /* We need to use a manual reset event object due to the way our
    1602             :          w32-pth wait function works: If we would use an automatic
    1603             :          reset event we are not able to figure out which handle has
    1604             :          been signaled because at the time we single out the signaled
    1605             :          handles using WFSO the event has already been reset due to
    1606             :          the WFMO.  */
    1607             :       h = CreateEvent (&sa, TRUE, FALSE, NULL);
    1608             :       if (!h)
    1609             :         log_error ("can't create scd notify event: %s\n", w32_strerror (-1) );
    1610             :       else if (!DuplicateHandle (GetCurrentProcess(), h,
    1611             :                                  GetCurrentProcess(), &h2,
    1612             :                                  EVENT_MODIFY_STATE|SYNCHRONIZE, TRUE, 0))
    1613             :         {
    1614             :           log_error ("setting syncronize for scd notify event failed: %s\n",
    1615             :                      w32_strerror (-1) );
    1616             :           CloseHandle (h);
    1617             :         }
    1618             :       else
    1619             :         {
    1620             :           CloseHandle (h);
    1621             :           the_event = h2;
    1622             :         }
    1623             :     }
    1624             : 
    1625             :   return the_event;
    1626             : }
    1627             : #endif /*HAVE_W32_SYSTEM && !HAVE_W32CE_SYSTEM*/
    1628             : 
    1629             : 
    1630             : 
    1631             : /* Create a name for the socket in the home directory as using
    1632             :    STANDARD_NAME.  We also check for valid characters as well as
    1633             :    against a maximum allowed length for a unix domain socket is done.
    1634             :    The function terminates the process in case of an error.  Returns:
    1635             :    Pointer to an allocated string with the absolute name of the socket
    1636             :    used.  */
    1637             : static char *
    1638           1 : create_socket_name (char *standard_name, int with_homedir)
    1639             : {
    1640             :   char *name;
    1641             : 
    1642           1 :   if (with_homedir)
    1643           1 :     name = make_filename (opt.homedir, standard_name, NULL);
    1644             :   else
    1645           0 :     name = make_filename (standard_name, NULL);
    1646           1 :   if (strchr (name, PATHSEP_C))
    1647             :     {
    1648           0 :       log_error (("'%s' are not allowed in the socket name\n"), PATHSEP_S);
    1649           0 :       agent_exit (2);
    1650             :     }
    1651           1 :   return name;
    1652             : }
    1653             : 
    1654             : 
    1655             : 
    1656             : /* Create a Unix domain socket with NAME.  Returns the file descriptor
    1657             :    or terminates the process in case of an error.  Note that this
    1658             :    function needs to be used for the regular socket first (indicated
    1659             :    by PRIMARY) and only then for the extra and the ssh sockets.  If
    1660             :    the socket has been redirected the name of the real socket is
    1661             :    stored as a malloced string at R_REDIR_NAME.  If CYGWIN is set a
    1662             :    Cygwin compatible socket is created (Windows only). */
    1663             : static gnupg_fd_t
    1664           1 : create_server_socket (char *name, int primary, int cygwin,
    1665             :                       char **r_redir_name, assuan_sock_nonce_t *nonce)
    1666             : {
    1667             :   struct sockaddr *addr;
    1668             :   struct sockaddr_un *unaddr;
    1669             :   socklen_t len;
    1670             :   gnupg_fd_t fd;
    1671             :   int rc;
    1672             : 
    1673           1 :   xfree (*r_redir_name);
    1674           1 :   *r_redir_name = NULL;
    1675             : 
    1676           1 :   fd = assuan_sock_new (AF_UNIX, SOCK_STREAM, 0);
    1677           1 :   if (fd == ASSUAN_INVALID_FD)
    1678             :     {
    1679           0 :       log_error (_("can't create socket: %s\n"), strerror (errno));
    1680           0 :       *name = 0; /* Inhibit removal of the socket by cleanup(). */
    1681           0 :       agent_exit (2);
    1682             :     }
    1683             : 
    1684             : #if ASSUAN_VERSION_NUMBER >= 0x020300 /* >= 2.3.0 */
    1685           1 :   if (cygwin)
    1686           0 :     assuan_sock_set_flag (fd, "cygwin", 1);
    1687             : #else
    1688             :   (void)cygwin;
    1689             : #endif
    1690             : 
    1691           1 :   unaddr = xmalloc (sizeof *unaddr);
    1692           1 :   addr = (struct sockaddr*)unaddr;
    1693             : 
    1694             : #if ASSUAN_VERSION_NUMBER >= 0x020104 /* >= 2.1.4 */
    1695             :   {
    1696             :     int redirected;
    1697             : 
    1698           1 :     if (assuan_sock_set_sockaddr_un (name, addr, &redirected))
    1699             :       {
    1700           0 :         if (errno == ENAMETOOLONG)
    1701           0 :           log_error (_("socket name '%s' is too long\n"), name);
    1702             :         else
    1703           0 :           log_error ("error preparing socket '%s': %s\n",
    1704             :                      name, gpg_strerror (gpg_error_from_syserror ()));
    1705           0 :         *name = 0; /* Inhibit removal of the socket by cleanup(). */
    1706           0 :         agent_exit (2);
    1707             :       }
    1708           1 :     if (redirected)
    1709             :       {
    1710           0 :         *r_redir_name = xstrdup (unaddr->sun_path);
    1711           0 :         if (opt.verbose)
    1712           0 :           log_info ("redirecting socket '%s' to '%s'\n", name, *r_redir_name);
    1713             :       }
    1714             :   }
    1715             : #else /* Assuan < 2.1.4 */
    1716             :   memset (unaddr, 0, sizeof *unaddr);
    1717             :   unaddr->sun_family = AF_UNIX;
    1718             :   if (strlen (name) + 1 >= sizeof (unaddr->sun_path))
    1719             :     {
    1720             :       log_error (_("socket name '%s' is too long\n"), name);
    1721             :       *name = 0; /* Inhibit removal of the socket by cleanup(). */
    1722             :       agent_exit (2);
    1723             :     }
    1724             :   strcpy (unaddr->sun_path, name);
    1725             : #endif /* Assuan < 2.1.4 */
    1726             : 
    1727           1 :   len = SUN_LEN (unaddr);
    1728           1 :   rc = assuan_sock_bind (fd, addr, len);
    1729             : 
    1730             :   /* Our error code mapping on W32CE returns EEXIST thus we also test
    1731             :      for this. */
    1732           1 :   if (rc == -1
    1733           0 :       && (errno == EADDRINUSE
    1734             : #ifdef HAVE_W32_SYSTEM
    1735             :           || errno == EEXIST
    1736             : #endif
    1737             :           ))
    1738             :     {
    1739             :       /* Check whether a gpg-agent is already running.  We do this
    1740             :          test only if this is the primary socket.  For secondary
    1741             :          sockets we assume that a test for gpg-agent has already been
    1742             :          done and reuse the requested socket.  Testing the ssh-socket
    1743             :          is not possible because at this point, though we know the new
    1744             :          Assuan socket, the Assuan server and thus the ssh-agent
    1745             :          server is not yet operational; this would lead to a hang.  */
    1746           0 :       if (primary && !check_for_running_agent (1))
    1747             :         {
    1748           0 :           log_set_prefix (NULL, GPGRT_LOG_WITH_PREFIX);
    1749           0 :           log_set_file (NULL);
    1750           0 :           log_error (_("a gpg-agent is already running - "
    1751             :                        "not starting a new one\n"));
    1752           0 :           *name = 0; /* Inhibit removal of the socket by cleanup(). */
    1753           0 :           assuan_sock_close (fd);
    1754           0 :           agent_exit (2);
    1755             :         }
    1756           0 :       gnupg_remove (unaddr->sun_path);
    1757           0 :       rc = assuan_sock_bind (fd, addr, len);
    1758             :     }
    1759           1 :   if (rc != -1 && (rc=assuan_sock_get_nonce (addr, len, nonce)))
    1760           0 :     log_error (_("error getting nonce for the socket\n"));
    1761           1 :   if (rc == -1)
    1762             :     {
    1763             :       /* We use gpg_strerror here because it allows us to get strings
    1764             :          for some W32 socket error codes.  */
    1765           0 :       log_error (_("error binding socket to '%s': %s\n"),
    1766           0 :                  unaddr->sun_path,
    1767             :                  gpg_strerror (gpg_error_from_syserror ()));
    1768             : 
    1769           0 :       assuan_sock_close (fd);
    1770           0 :       *name = 0; /* Inhibit removal of the socket by cleanup(). */
    1771           0 :       agent_exit (2);
    1772             :     }
    1773             : 
    1774           1 :   if (listen (FD2INT(fd), 5 ) == -1)
    1775             :     {
    1776           0 :       log_error (_("listen() failed: %s\n"), strerror (errno));
    1777           0 :       *name = 0; /* Inhibit removal of the socket by cleanup(). */
    1778           0 :       assuan_sock_close (fd);
    1779           0 :       agent_exit (2);
    1780             :     }
    1781             : 
    1782           1 :   if (opt.verbose)
    1783           0 :     log_info (_("listening on socket '%s'\n"), unaddr->sun_path);
    1784             : 
    1785           1 :   return fd;
    1786             : }
    1787             : 
    1788             : 
    1789             : /* Check that the directory for storing the private keys exists and
    1790             :    create it if not.  This function won't fail as it is only a
    1791             :    convenience function and not strictly necessary.  */
    1792             : static void
    1793           1 : create_private_keys_directory (const char *home)
    1794             : {
    1795             :   char *fname;
    1796             :   struct stat statbuf;
    1797             : 
    1798           1 :   fname = make_filename (home, GNUPG_PRIVATE_KEYS_DIR, NULL);
    1799           1 :   if (stat (fname, &statbuf) && errno == ENOENT)
    1800             :     {
    1801           1 :       if (gnupg_mkdir (fname, "-rwx"))
    1802           0 :         log_error (_("can't create directory '%s': %s\n"),
    1803           0 :                    fname, strerror (errno) );
    1804           1 :       else if (!opt.quiet)
    1805           1 :         log_info (_("directory '%s' created\n"), fname);
    1806             :     }
    1807           1 :   xfree (fname);
    1808           1 : }
    1809             : 
    1810             : /* Create the directory only if the supplied directory name is the
    1811             :    same as the default one.  This way we avoid to create arbitrary
    1812             :    directories when a non-default home directory is used.  To cope
    1813             :    with HOME, we compare only the suffix if we see that the default
    1814             :    homedir does start with a tilde.  We don't stop here in case of
    1815             :    problems because other functions will throw an error anyway.*/
    1816             : static void
    1817           1 : create_directories (void)
    1818             : {
    1819             :   struct stat statbuf;
    1820           1 :   const char *defhome = standard_homedir ();
    1821             :   char *home;
    1822             : 
    1823           1 :   home = make_filename (opt.homedir, NULL);
    1824           1 :   if ( stat (home, &statbuf) )
    1825             :     {
    1826           0 :       if (errno == ENOENT)
    1827             :         {
    1828           0 :           if (
    1829             : #ifdef HAVE_W32_SYSTEM
    1830             :               ( !compare_filenames (home, defhome) )
    1831             : #else
    1832           0 :               (*defhome == '~'
    1833           0 :                 && (strlen (home) >= strlen (defhome+1)
    1834           0 :                     && !strcmp (home + strlen(home)
    1835           0 :                                 - strlen (defhome+1), defhome+1)))
    1836           0 :                || (*defhome != '~' && !strcmp (home, defhome) )
    1837             : #endif
    1838             :                )
    1839             :             {
    1840           0 :               if (gnupg_mkdir (home, "-rwx"))
    1841           0 :                 log_error (_("can't create directory '%s': %s\n"),
    1842           0 :                            home, strerror (errno) );
    1843             :               else
    1844             :                 {
    1845           0 :                   if (!opt.quiet)
    1846           0 :                     log_info (_("directory '%s' created\n"), home);
    1847           0 :                   create_private_keys_directory (home);
    1848             :                 }
    1849             :             }
    1850             :         }
    1851             :       else
    1852           0 :         log_error (_("stat() failed for '%s': %s\n"), home, strerror (errno));
    1853             :     }
    1854           1 :   else if ( !S_ISDIR(statbuf.st_mode))
    1855             :     {
    1856           0 :       log_error (_("can't use '%s' as home directory\n"), home);
    1857             :     }
    1858             :   else /* exists and is a directory. */
    1859             :     {
    1860           1 :       create_private_keys_directory (home);
    1861             :     }
    1862           1 :   xfree (home);
    1863           1 : }
    1864             : 
    1865             : 
    1866             : 
    1867             : /* This is the worker for the ticker.  It is called every few seconds
    1868             :    and may only do fast operations. */
    1869             : static void
    1870          16 : handle_tick (void)
    1871             : {
    1872             :   static time_t last_minute;
    1873             : 
    1874          16 :   if (!last_minute)
    1875           1 :     last_minute = time (NULL);
    1876             : 
    1877             :   /* Check whether the scdaemon has died and cleanup in this case. */
    1878          16 :   agent_scd_check_aliveness ();
    1879             : 
    1880             :   /* If we are running as a child of another process, check whether
    1881             :      the parent is still alive and shutdown if not. */
    1882             : #ifndef HAVE_W32_SYSTEM
    1883          16 :   if (parent_pid != (pid_t)(-1))
    1884             :     {
    1885           0 :       if (kill (parent_pid, 0))
    1886             :         {
    1887           0 :           shutdown_pending = 2;
    1888           0 :           log_info ("parent process died - shutting down\n");
    1889           0 :           log_info ("%s %s stopped\n", strusage(11), strusage(13) );
    1890           0 :           cleanup ();
    1891           0 :           agent_exit (0);
    1892             :         }
    1893             :     }
    1894             : #endif /*HAVE_W32_SYSTEM*/
    1895             : 
    1896             :   /* Code to be run from time to time.  */
    1897             : #if CHECK_OWN_SOCKET_INTERVAL > 0
    1898          16 :   if (last_minute + CHECK_OWN_SOCKET_INTERVAL <= time (NULL))
    1899             :     {
    1900           0 :       check_own_socket ();
    1901           0 :       last_minute = time (NULL);
    1902             :     }
    1903             : #endif
    1904             : 
    1905          16 : }
    1906             : 
    1907             : 
    1908             : /* A global function which allows us to call the reload stuff from
    1909             :    other places too.  This is only used when build for W32.  */
    1910             : void
    1911           0 : agent_sighup_action (void)
    1912             : {
    1913           0 :   log_info ("SIGHUP received - "
    1914             :             "re-reading configuration and flushing cache\n");
    1915             : 
    1916           0 :   agent_flush_cache ();
    1917           0 :   reread_configuration ();
    1918           0 :   agent_reload_trustlist ();
    1919             :   /* We flush the module name cache so that after installing a
    1920             :      "pinentry" binary that one can be used in case the
    1921             :      "pinentry-basic" fallback was in use.  */
    1922           0 :   gnupg_module_name_flush_some ();
    1923           0 : }
    1924             : 
    1925             : 
    1926             : /* A helper function to handle SIGUSR2.  */
    1927             : static void
    1928           0 : agent_sigusr2_action (void)
    1929             : {
    1930           0 :   if (opt.verbose)
    1931           0 :     log_info ("SIGUSR2 received - updating card event counter\n");
    1932             :   /* Nothing to check right now.  We only increment a counter.  */
    1933           0 :   bump_card_eventcounter ();
    1934           0 : }
    1935             : 
    1936             : 
    1937             : #ifndef HAVE_W32_SYSTEM
    1938             : /* The signal handler for this program.  It is expected to be run in
    1939             :    its own trhead and not in the context of a signal handler.  */
    1940             : static void
    1941           0 : handle_signal (int signo)
    1942             : {
    1943           0 :   switch (signo)
    1944             :     {
    1945             : #ifndef HAVE_W32_SYSTEM
    1946             :     case SIGHUP:
    1947           0 :       agent_sighup_action ();
    1948           0 :       break;
    1949             : 
    1950             :     case SIGUSR1:
    1951           0 :       log_info ("SIGUSR1 received - printing internal information:\n");
    1952             :       /* Fixme: We need to see how to integrate pth dumping into our
    1953             :          logging system.  */
    1954             :       /* pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ()); */
    1955           0 :       agent_query_dump_state ();
    1956           0 :       agent_scd_dump_state ();
    1957           0 :       break;
    1958             : 
    1959             :     case SIGUSR2:
    1960           0 :       agent_sigusr2_action ();
    1961           0 :       break;
    1962             : 
    1963             :     case SIGTERM:
    1964           0 :       if (!shutdown_pending)
    1965           0 :         log_info ("SIGTERM received - shutting down ...\n");
    1966             :       else
    1967           0 :         log_info ("SIGTERM received - still %i open connections\n",
    1968             :                   active_connections);
    1969           0 :       shutdown_pending++;
    1970           0 :       if (shutdown_pending > 2)
    1971             :         {
    1972           0 :           log_info ("shutdown forced\n");
    1973           0 :           log_info ("%s %s stopped\n", strusage(11), strusage(13) );
    1974           0 :           cleanup ();
    1975           0 :           agent_exit (0);
    1976             :         }
    1977           0 :       break;
    1978             : 
    1979             :     case SIGINT:
    1980           0 :       log_info ("SIGINT received - immediate shutdown\n");
    1981           0 :       log_info( "%s %s stopped\n", strusage(11), strusage(13));
    1982           0 :       cleanup ();
    1983           0 :       agent_exit (0);
    1984             :       break;
    1985             : #endif
    1986             :     default:
    1987           0 :       log_info ("signal %d received - no action defined\n", signo);
    1988             :     }
    1989           0 : }
    1990             : #endif
    1991             : 
    1992             : /* Check the nonce on a new connection.  This is a NOP unless we we
    1993             :    are using our Unix domain socket emulation under Windows.  */
    1994             : static int
    1995         404 : check_nonce (ctrl_t ctrl, assuan_sock_nonce_t *nonce)
    1996             : {
    1997         404 :   if (assuan_sock_check_nonce (ctrl->thread_startup.fd, nonce))
    1998             :     {
    1999           0 :       log_info (_("error reading nonce on fd %d: %s\n"),
    2000           0 :                 FD2INT(ctrl->thread_startup.fd), strerror (errno));
    2001           0 :       assuan_sock_close (ctrl->thread_startup.fd);
    2002           0 :       xfree (ctrl);
    2003           0 :       return -1;
    2004             :     }
    2005             :   else
    2006         404 :     return 0;
    2007             : }
    2008             : 
    2009             : 
    2010             : #ifdef HAVE_W32_SYSTEM
    2011             : /* The window message processing function for Putty.  Warning: This
    2012             :    code runs as a native Windows thread.  Use of our own functions
    2013             :    needs to be bracket with pth_leave/pth_enter. */
    2014             : static LRESULT CALLBACK
    2015             : putty_message_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
    2016             : {
    2017             :   int ret = 0;
    2018             :   int w32rc;
    2019             :   COPYDATASTRUCT *cds;
    2020             :   const char *mapfile;
    2021             :   HANDLE maphd;
    2022             :   PSID mysid = NULL;
    2023             :   PSID mapsid = NULL;
    2024             :   void *data = NULL;
    2025             :   PSECURITY_DESCRIPTOR psd = NULL;
    2026             :   ctrl_t ctrl = NULL;
    2027             : 
    2028             :   if (msg != WM_COPYDATA)
    2029             :     {
    2030             :       return DefWindowProc (hwnd, msg, wparam, lparam);
    2031             :     }
    2032             : 
    2033             :   cds = (COPYDATASTRUCT*)lparam;
    2034             :   if (cds->dwData != PUTTY_IPC_MAGIC)
    2035             :     return 0;  /* Ignore data with the wrong magic.  */
    2036             :   mapfile = cds->lpData;
    2037             :   if (!cds->cbData || mapfile[cds->cbData - 1])
    2038             :     return 0;  /* Ignore empty and non-properly terminated strings.  */
    2039             : 
    2040             :   if (DBG_IPC)
    2041             :     {
    2042             :       npth_protect ();
    2043             :       log_debug ("ssh map file '%s'", mapfile);
    2044             :       npth_unprotect ();
    2045             :     }
    2046             : 
    2047             :   maphd = OpenFileMapping (FILE_MAP_ALL_ACCESS, FALSE, mapfile);
    2048             :   if (DBG_IPC)
    2049             :     {
    2050             :       npth_protect ();
    2051             :       log_debug ("ssh map handle %p\n", maphd);
    2052             :       npth_unprotect ();
    2053             :     }
    2054             : 
    2055             :   if (!maphd || maphd == INVALID_HANDLE_VALUE)
    2056             :     return 0;
    2057             : 
    2058             :   npth_protect ();
    2059             : 
    2060             :   mysid = w32_get_user_sid ();
    2061             :   if (!mysid)
    2062             :     {
    2063             :       log_error ("error getting my sid\n");
    2064             :       goto leave;
    2065             :     }
    2066             : 
    2067             :   w32rc = GetSecurityInfo (maphd, SE_KERNEL_OBJECT,
    2068             :                            OWNER_SECURITY_INFORMATION,
    2069             :                            &mapsid, NULL, NULL, NULL,
    2070             :                            &psd);
    2071             :   if (w32rc)
    2072             :     {
    2073             :       log_error ("error getting sid of ssh map file: rc=%d", w32rc);
    2074             :       goto leave;
    2075             :     }
    2076             : 
    2077             :   if (DBG_IPC)
    2078             :     {
    2079             :       char *sidstr;
    2080             : 
    2081             :       if (!ConvertSidToStringSid (mysid, &sidstr))
    2082             :         sidstr = NULL;
    2083             :       log_debug ("          my sid: '%s'", sidstr? sidstr: "[error]");
    2084             :       LocalFree (sidstr);
    2085             :       if (!ConvertSidToStringSid (mapsid, &sidstr))
    2086             :         sidstr = NULL;
    2087             :       log_debug ("ssh map file sid: '%s'", sidstr? sidstr: "[error]");
    2088             :       LocalFree (sidstr);
    2089             :     }
    2090             : 
    2091             :   if (!EqualSid (mysid, mapsid))
    2092             :     {
    2093             :       log_error ("ssh map file has a non-matching sid\n");
    2094             :       goto leave;
    2095             :     }
    2096             : 
    2097             :   data = MapViewOfFile (maphd, FILE_MAP_ALL_ACCESS, 0, 0, 0);
    2098             :   if (DBG_IPC)
    2099             :     log_debug ("ssh IPC buffer at %p\n", data);
    2100             :   if (!data)
    2101             :     goto leave;
    2102             : 
    2103             :   /* log_printhex ("request:", data, 20); */
    2104             : 
    2105             :   ctrl = xtrycalloc (1, sizeof *ctrl);
    2106             :   if (!ctrl)
    2107             :     {
    2108             :       log_error ("error allocating connection control data: %s\n",
    2109             :                  strerror (errno) );
    2110             :       goto leave;
    2111             :     }
    2112             :   ctrl->session_env = session_env_new ();
    2113             :   if (!ctrl->session_env)
    2114             :     {
    2115             :       log_error ("error allocating session environment block: %s\n",
    2116             :                  strerror (errno) );
    2117             :       goto leave;
    2118             :     }
    2119             : 
    2120             :   agent_init_default_ctrl (ctrl);
    2121             :   if (!serve_mmapped_ssh_request (ctrl, data, PUTTY_IPC_MAXLEN))
    2122             :     ret = 1; /* Valid ssh message has been constructed.  */
    2123             :   agent_deinit_default_ctrl (ctrl);
    2124             :   /* log_printhex ("  reply:", data, 20); */
    2125             : 
    2126             :  leave:
    2127             :   xfree (ctrl);
    2128             :   if (data)
    2129             :     UnmapViewOfFile (data);
    2130             :   xfree (mapsid);
    2131             :   if (psd)
    2132             :     LocalFree (psd);
    2133             :   xfree (mysid);
    2134             :   CloseHandle (maphd);
    2135             : 
    2136             :   npth_unprotect ();
    2137             : 
    2138             :   return ret;
    2139             : }
    2140             : #endif /*HAVE_W32_SYSTEM*/
    2141             : 
    2142             : 
    2143             : #ifdef HAVE_W32_SYSTEM
    2144             : /* The thread handling Putty's IPC requests.  */
    2145             : static void *
    2146             : putty_message_thread (void *arg)
    2147             : {
    2148             :   WNDCLASS wndwclass = {0, putty_message_proc, 0, 0,
    2149             :                         NULL, NULL, NULL, NULL, NULL, "Pageant"};
    2150             :   HWND hwnd;
    2151             :   MSG msg;
    2152             : 
    2153             :   (void)arg;
    2154             : 
    2155             :   if (opt.verbose)
    2156             :     log_info ("putty message loop thread started\n");
    2157             : 
    2158             :   /* The message loop runs as thread independent from our nPth system.
    2159             :      This also means that we need to make sure that we switch back to
    2160             :      our system before calling any no-windows function.  */
    2161             :   npth_unprotect ();
    2162             : 
    2163             :   /* First create a window to make sure that a message queue exists
    2164             :      for this thread.  */
    2165             :   if (!RegisterClass (&wndwclass))
    2166             :     {
    2167             :       npth_protect ();
    2168             :       log_error ("error registering Pageant window class");
    2169             :       return NULL;
    2170             :     }
    2171             :   hwnd = CreateWindowEx (0, "Pageant", "Pageant", 0,
    2172             :                          0, 0, 0, 0,
    2173             :                          HWND_MESSAGE,  /* hWndParent */
    2174             :                          NULL,          /* hWndMenu   */
    2175             :                          NULL,          /* hInstance  */
    2176             :                          NULL);         /* lpParm     */
    2177             :   if (!hwnd)
    2178             :     {
    2179             :       npth_protect ();
    2180             :       log_error ("error creating Pageant window");
    2181             :       return NULL;
    2182             :     }
    2183             : 
    2184             :   while (GetMessage(&msg, NULL, 0, 0))
    2185             :     {
    2186             :       TranslateMessage(&msg);
    2187             :       DispatchMessage(&msg);
    2188             :     }
    2189             : 
    2190             :   /* Back to nPth.  */
    2191             :   npth_protect ();
    2192             : 
    2193             :   if (opt.verbose)
    2194             :     log_info ("putty message loop thread stopped\n");
    2195             :   return NULL;
    2196             : }
    2197             : #endif /*HAVE_W32_SYSTEM*/
    2198             : 
    2199             : 
    2200             : static void *
    2201         404 : do_start_connection_thread (ctrl_t ctrl)
    2202             : {
    2203         404 :   agent_init_default_ctrl (ctrl);
    2204         404 :   if (opt.verbose)
    2205           0 :     log_info (_("handler 0x%lx for fd %d started\n"),
    2206             :               (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd));
    2207             : 
    2208         404 :   start_command_handler (ctrl, GNUPG_INVALID_FD, ctrl->thread_startup.fd);
    2209         403 :   if (opt.verbose)
    2210           0 :     log_info (_("handler 0x%lx for fd %d terminated\n"),
    2211             :               (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd));
    2212             : 
    2213         403 :   agent_deinit_default_ctrl (ctrl);
    2214         403 :   xfree (ctrl);
    2215         403 :   return NULL;
    2216             : }
    2217             : 
    2218             : 
    2219             : /* This is the standard connection thread's main function.  */
    2220             : static void *
    2221         404 : start_connection_thread_std (void *arg)
    2222             : {
    2223         404 :   ctrl_t ctrl = arg;
    2224             : 
    2225         404 :   if (check_nonce (ctrl, &socket_nonce))
    2226             :     {
    2227           0 :       log_error ("handler 0x%lx nonce check FAILED\n",
    2228             :                  (unsigned long) npth_self());
    2229           0 :       return NULL;
    2230             :     }
    2231             : 
    2232         404 :   return do_start_connection_thread (ctrl);
    2233             : }
    2234             : 
    2235             : 
    2236             : /* This is the extra socket connection thread's main function.  */
    2237             : static void *
    2238           0 : start_connection_thread_extra (void *arg)
    2239             : {
    2240           0 :   ctrl_t ctrl = arg;
    2241             : 
    2242           0 :   if (check_nonce (ctrl, &socket_nonce_extra))
    2243             :     {
    2244           0 :       log_error ("handler 0x%lx nonce check FAILED\n",
    2245             :                  (unsigned long) npth_self());
    2246           0 :       return NULL;
    2247             :     }
    2248             : 
    2249           0 :   ctrl->restricted = 1;
    2250           0 :   return do_start_connection_thread (ctrl);
    2251             : }
    2252             : 
    2253             : 
    2254             : /* This is the browser socket connection thread's main function.  */
    2255             : static void *
    2256           0 : start_connection_thread_browser (void *arg)
    2257             : {
    2258           0 :   ctrl_t ctrl = arg;
    2259             : 
    2260           0 :   if (check_nonce (ctrl, &socket_nonce_browser))
    2261             :     {
    2262           0 :       log_error ("handler 0x%lx nonce check FAILED\n",
    2263             :                  (unsigned long) npth_self());
    2264           0 :       return NULL;
    2265             :     }
    2266             : 
    2267           0 :   ctrl->restricted = 2;
    2268           0 :   return do_start_connection_thread (ctrl);
    2269             : }
    2270             : 
    2271             : 
    2272             : /* This is the ssh connection thread's main function.  */
    2273             : static void *
    2274           0 : start_connection_thread_ssh (void *arg)
    2275             : {
    2276           0 :   ctrl_t ctrl = arg;
    2277             : 
    2278           0 :   if (check_nonce (ctrl, &socket_nonce_ssh))
    2279           0 :     return NULL;
    2280             : 
    2281           0 :   agent_init_default_ctrl (ctrl);
    2282           0 :   if (opt.verbose)
    2283           0 :     log_info (_("ssh handler 0x%lx for fd %d started\n"),
    2284             :               (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd));
    2285             : 
    2286           0 :   start_command_handler_ssh (ctrl, ctrl->thread_startup.fd);
    2287           0 :   if (opt.verbose)
    2288           0 :     log_info (_("ssh handler 0x%lx for fd %d terminated\n"),
    2289             :               (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd));
    2290             : 
    2291           0 :   agent_deinit_default_ctrl (ctrl);
    2292           0 :   xfree (ctrl);
    2293           0 :   return NULL;
    2294             : }
    2295             : 
    2296             : 
    2297             : /* Connection handler loop.  Wait for connection requests and spawn a
    2298             :    thread after accepting a connection.  */
    2299             : static void
    2300           1 : handle_connections (gnupg_fd_t listen_fd,
    2301             :                     gnupg_fd_t listen_fd_extra,
    2302             :                     gnupg_fd_t listen_fd_browser,
    2303             :                     gnupg_fd_t listen_fd_ssh)
    2304             : {
    2305             :   npth_attr_t tattr;
    2306             :   struct sockaddr_un paddr;
    2307             :   socklen_t plen;
    2308             :   fd_set fdset, read_fdset;
    2309             :   int ret;
    2310             :   gnupg_fd_t fd;
    2311             :   int nfd;
    2312             :   int saved_errno;
    2313             :   struct timespec abstime;
    2314             :   struct timespec curtime;
    2315             :   struct timespec timeout;
    2316             : #ifdef HAVE_W32_SYSTEM
    2317             :   HANDLE events[2];
    2318             :   unsigned int events_set;
    2319             : #endif
    2320             :   struct {
    2321             :     const char *name;
    2322             :     void *(*func) (void *arg);
    2323             :     gnupg_fd_t l_fd;
    2324           1 :   } listentbl[] = {
    2325             :     { "std",     start_connection_thread_std   },
    2326             :     { "extra",   start_connection_thread_extra },
    2327             :     { "browser", start_connection_thread_browser },
    2328             :     { "ssh",    start_connection_thread_ssh   }
    2329             :   };
    2330             : 
    2331             : 
    2332           1 :   ret = npth_attr_init(&tattr);
    2333           1 :   if (ret)
    2334           0 :     log_fatal ("error allocating thread attributes: %s\n",
    2335             :                strerror (ret));
    2336           1 :   npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
    2337             : 
    2338             : #ifndef HAVE_W32_SYSTEM
    2339           1 :   npth_sigev_init ();
    2340           1 :   npth_sigev_add (SIGHUP);
    2341           1 :   npth_sigev_add (SIGUSR1);
    2342           1 :   npth_sigev_add (SIGUSR2);
    2343           1 :   npth_sigev_add (SIGINT);
    2344           1 :   npth_sigev_add (SIGTERM);
    2345           1 :   npth_sigev_fini ();
    2346             : #else
    2347             : # ifdef HAVE_W32CE_SYSTEM
    2348             :   /* Use a dummy event. */
    2349             :   sigs = 0;
    2350             :   ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
    2351             : # else
    2352             :   events[0] = get_agent_scd_notify_event ();
    2353             :   events[1] = INVALID_HANDLE_VALUE;
    2354             : # endif
    2355             : #endif
    2356             : 
    2357             :   /* On Windows we need to fire up a separate thread to listen for
    2358             :      requests from Putty (an SSH client), so we can replace Putty's
    2359             :      Pageant (its ssh-agent implementation). */
    2360             : #ifdef HAVE_W32_SYSTEM
    2361             :   if (putty_support)
    2362             :     {
    2363             :       npth_t thread;
    2364             : 
    2365             :       ret = npth_create (&thread, &tattr, putty_message_thread, NULL);
    2366             :       if (ret)
    2367             :         {
    2368             :           log_error ("error spawning putty message loop: %s\n", strerror (ret));
    2369             :         }
    2370             :     }
    2371             : #endif /*HAVE_W32_SYSTEM*/
    2372             : 
    2373             :   /* Set a flag to tell call-scd.c that it may enable event
    2374             :      notifications.  */
    2375           1 :   opt.sigusr2_enabled = 1;
    2376             : 
    2377           1 :   FD_ZERO (&fdset);
    2378           1 :   FD_SET (FD2INT (listen_fd), &fdset);
    2379           1 :   nfd = FD2INT (listen_fd);
    2380           1 :   if (listen_fd_extra != GNUPG_INVALID_FD)
    2381             :     {
    2382           0 :       FD_SET ( FD2INT(listen_fd_extra), &fdset);
    2383           0 :       if (FD2INT (listen_fd_extra) > nfd)
    2384           0 :         nfd = FD2INT (listen_fd_extra);
    2385             :     }
    2386           1 :   if (listen_fd_browser != GNUPG_INVALID_FD)
    2387             :     {
    2388           0 :       FD_SET ( FD2INT(listen_fd_browser), &fdset);
    2389           0 :       if (FD2INT (listen_fd_browser) > nfd)
    2390           0 :         nfd = FD2INT (listen_fd_browser);
    2391             :     }
    2392           1 :   if (listen_fd_ssh != GNUPG_INVALID_FD)
    2393             :     {
    2394           0 :       FD_SET ( FD2INT(listen_fd_ssh), &fdset);
    2395           0 :       if (FD2INT (listen_fd_ssh) > nfd)
    2396           0 :         nfd = FD2INT (listen_fd_ssh);
    2397             :     }
    2398             : 
    2399           1 :   listentbl[0].l_fd = listen_fd;
    2400           1 :   listentbl[1].l_fd = listen_fd_extra;
    2401           1 :   listentbl[2].l_fd = listen_fd_browser;
    2402           1 :   listentbl[3].l_fd = listen_fd_ssh;
    2403             : 
    2404           1 :   npth_clock_gettime (&abstime);
    2405           1 :   abstime.tv_sec += TIMERTICK_INTERVAL;
    2406             : 
    2407             :   for (;;)
    2408             :     {
    2409             :       /* Shutdown test.  */
    2410         421 :       if (shutdown_pending)
    2411             :         {
    2412           0 :           if (active_connections == 0)
    2413           0 :             break; /* ready */
    2414             : 
    2415             :           /* Do not accept new connections but keep on running the
    2416             :              loop to cope with the timer events.  */
    2417           0 :           FD_ZERO (&fdset);
    2418             :         }
    2419             : 
    2420             :       /* POSIX says that fd_set should be implemented as a structure,
    2421             :          thus a simple assignment is fine to copy the entire set.  */
    2422         421 :       read_fdset = fdset;
    2423             : 
    2424         421 :       npth_clock_gettime (&curtime);
    2425         421 :       if (!(npth_timercmp (&curtime, &abstime, <)))
    2426             :         {
    2427             :           /* Timeout.  */
    2428          16 :           handle_tick ();
    2429          16 :           npth_clock_gettime (&abstime);
    2430          16 :           abstime.tv_sec += TIMERTICK_INTERVAL;
    2431             :         }
    2432         421 :       npth_timersub (&abstime, &curtime, &timeout);
    2433             : 
    2434             : #ifndef HAVE_W32_SYSTEM
    2435         421 :       ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout,
    2436         421 :                           npth_sigev_sigmask ());
    2437         420 :       saved_errno = errno;
    2438             : 
    2439             :       {
    2440             :         int signo;
    2441         840 :         while (npth_sigev_get_pending (&signo))
    2442           0 :           handle_signal (signo);
    2443             :       }
    2444             : #else
    2445             :       ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout,
    2446             :                           events, &events_set);
    2447             :       saved_errno = errno;
    2448             : 
    2449             :       /* This is valid even if npth_eselect returns an error.  */
    2450             :       if (events_set & 1)
    2451             :         agent_sigusr2_action ();
    2452             : #endif
    2453             : 
    2454         420 :       if (ret == -1 && saved_errno != EINTR)
    2455             :         {
    2456           0 :           log_error (_("npth_pselect failed: %s - waiting 1s\n"),
    2457             :                      strerror (saved_errno));
    2458           0 :           npth_sleep (1);
    2459           0 :           continue;
    2460             :         }
    2461         420 :       if (ret <= 0)
    2462             :         /* Interrupt or timeout.  Will be handled when calculating the
    2463             :            next timeout.  */
    2464          16 :         continue;
    2465             : 
    2466         404 :       if (!shutdown_pending)
    2467             :         {
    2468             :           int idx;
    2469             :           ctrl_t ctrl;
    2470             :           npth_t thread;
    2471             : 
    2472        2020 :           for (idx=0; idx < DIM(listentbl); idx++)
    2473             :             {
    2474        1616 :               if (listentbl[idx].l_fd == GNUPG_INVALID_FD)
    2475        1212 :                 continue;
    2476         404 :               if (!FD_ISSET (FD2INT (listentbl[idx].l_fd), &read_fdset))
    2477           0 :                 continue;
    2478             : 
    2479         404 :               plen = sizeof paddr;
    2480         404 :               fd = INT2FD (npth_accept (FD2INT(listentbl[idx].l_fd),
    2481             :                                         (struct sockaddr *)&paddr, &plen));
    2482         404 :               if (fd == GNUPG_INVALID_FD)
    2483             :                 {
    2484           0 :                   log_error ("accept failed for %s: %s\n",
    2485           0 :                              listentbl[idx].name, strerror (errno));
    2486             :                 }
    2487         404 :               else if ( !(ctrl = xtrycalloc (1, sizeof *ctrl)))
    2488             :                 {
    2489           0 :                   log_error ("error allocating connection data for %s: %s\n",
    2490           0 :                              listentbl[idx].name, strerror (errno) );
    2491           0 :                   assuan_sock_close (fd);
    2492             :                 }
    2493         404 :               else if ( !(ctrl->session_env = session_env_new ()))
    2494             :                 {
    2495           0 :                   log_error ("error allocating session env block for %s: %s\n",
    2496           0 :                              listentbl[idx].name, strerror (errno) );
    2497           0 :                   xfree (ctrl);
    2498           0 :                   assuan_sock_close (fd);
    2499             :                 }
    2500             :               else
    2501             :                 {
    2502         404 :                   ctrl->thread_startup.fd = fd;
    2503         404 :                   ret = npth_create (&thread, &tattr,
    2504             :                                      listentbl[idx].func, ctrl);
    2505         404 :                   if (ret)
    2506             :                     {
    2507           0 :                       log_error ("error spawning connection handler for %s:"
    2508             :                                  " %s\n", listentbl[idx].name, strerror (ret));
    2509           0 :                       assuan_sock_close (fd);
    2510           0 :                       xfree (ctrl);
    2511             :                     }
    2512             :                 }
    2513         404 :               fd = GNUPG_INVALID_FD;
    2514             :             }
    2515             :         }
    2516         420 :     }
    2517             : 
    2518           0 :   cleanup ();
    2519           0 :   log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
    2520           0 :   npth_attr_destroy (&tattr);
    2521           0 : }
    2522             : 
    2523             : 
    2524             : 
    2525             : /* Helper for check_own_socket.  */
    2526             : static gpg_error_t
    2527           0 : check_own_socket_pid_cb (void *opaque, const void *buffer, size_t length)
    2528             : {
    2529           0 :   membuf_t *mb = opaque;
    2530           0 :   put_membuf (mb, buffer, length);
    2531           0 :   return 0;
    2532             : }
    2533             : 
    2534             : 
    2535             : /* The thread running the actual check.  We need to run this in a
    2536             :    separate thread so that check_own_thread can be called from the
    2537             :    timer tick.  */
    2538             : static void *
    2539           0 : check_own_socket_thread (void *arg)
    2540             : {
    2541             :   int rc;
    2542           0 :   char *sockname = arg;
    2543           0 :   assuan_context_t ctx = NULL;
    2544             :   membuf_t mb;
    2545             :   char *buffer;
    2546             : 
    2547           0 :   check_own_socket_running++;
    2548             : 
    2549           0 :   rc = assuan_new (&ctx);
    2550           0 :   if (rc)
    2551             :     {
    2552           0 :       log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc));
    2553           0 :       goto leave;
    2554             :     }
    2555             : 
    2556           0 :   rc = assuan_socket_connect (ctx, sockname, (pid_t)(-1), 0);
    2557           0 :   if (rc)
    2558             :     {
    2559           0 :       log_error ("can't connect my own socket: %s\n", gpg_strerror (rc));
    2560           0 :       goto leave;
    2561             :     }
    2562             : 
    2563           0 :   init_membuf (&mb, 100);
    2564           0 :   rc = assuan_transact (ctx, "GETINFO pid", check_own_socket_pid_cb, &mb,
    2565             :                         NULL, NULL, NULL, NULL);
    2566           0 :   put_membuf (&mb, "", 1);
    2567           0 :   buffer = get_membuf (&mb, NULL);
    2568           0 :   if (rc || !buffer)
    2569             :     {
    2570           0 :       log_error ("sending command \"%s\" to my own socket failed: %s\n",
    2571             :                  "GETINFO pid", gpg_strerror (rc));
    2572           0 :       rc = 1;
    2573             :     }
    2574           0 :   else if ( (pid_t)strtoul (buffer, NULL, 10) != getpid ())
    2575             :     {
    2576           0 :       log_error ("socket is now serviced by another server\n");
    2577           0 :       rc = 1;
    2578             :     }
    2579           0 :   else if (opt.verbose > 1)
    2580           0 :     log_error ("socket is still served by this server\n");
    2581             : 
    2582           0 :   xfree (buffer);
    2583             : 
    2584             :  leave:
    2585           0 :   xfree (sockname);
    2586           0 :   if (ctx)
    2587           0 :     assuan_release (ctx);
    2588           0 :   if (rc)
    2589             :     {
    2590             :       /* We may not remove the socket as it is now in use by another
    2591             :          server.  Setting the name to empty does this.  */
    2592           0 :       if (socket_name)
    2593           0 :         *socket_name = 0;
    2594           0 :       if (socket_name_ssh)
    2595           0 :         *socket_name_ssh = 0;
    2596           0 :       shutdown_pending = 2;
    2597           0 :       log_info ("this process is useless - shutting down\n");
    2598             :     }
    2599           0 :   check_own_socket_running--;
    2600           0 :   return NULL;
    2601             : }
    2602             : 
    2603             : 
    2604             : /* Check whether we are still listening on our own socket.  In case
    2605             :    another gpg-agent process started after us has taken ownership of
    2606             :    our socket, we would linger around without any real task.  Thus we
    2607             :    better check once in a while whether we are really needed.  */
    2608             : static void
    2609           0 : check_own_socket (void)
    2610             : {
    2611             :   char *sockname;
    2612             :   npth_t thread;
    2613             :   npth_attr_t tattr;
    2614             :   int err;
    2615             : 
    2616           0 :   if (disable_check_own_socket)
    2617           0 :     return;
    2618             : 
    2619           0 :   if (check_own_socket_running || shutdown_pending)
    2620           0 :     return;  /* Still running or already shutting down.  */
    2621             : 
    2622           0 :   sockname = make_filename (opt.homedir, GPG_AGENT_SOCK_NAME, NULL);
    2623           0 :   if (!sockname)
    2624           0 :     return; /* Out of memory.  */
    2625             : 
    2626           0 :   err = npth_attr_init (&tattr);
    2627           0 :   if (err)
    2628           0 :     return;
    2629           0 :   npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
    2630           0 :   err = npth_create (&thread, &tattr, check_own_socket_thread, sockname);
    2631           0 :   if (err)
    2632           0 :     log_error ("error spawning check_own_socket_thread: %s\n", strerror (err));
    2633           0 :   npth_attr_destroy (&tattr);
    2634             : }
    2635             : 
    2636             : 
    2637             : 
    2638             : /* Figure out whether an agent is available and running. Prints an
    2639             :    error if not.  If SILENT is true, no messages are printed.
    2640             :    Returns 0 if the agent is running. */
    2641             : static int
    2642           2 : check_for_running_agent (int silent)
    2643             : {
    2644             :   gpg_error_t err;
    2645             :   char *sockname;
    2646           2 :   assuan_context_t ctx = NULL;
    2647             : 
    2648           2 :   sockname = make_filename (opt.homedir, GPG_AGENT_SOCK_NAME, NULL);
    2649             : 
    2650           2 :   err = assuan_new (&ctx);
    2651           2 :   if (!err)
    2652           2 :     err = assuan_socket_connect (ctx, sockname, (pid_t)(-1), 0);
    2653           2 :   xfree (sockname);
    2654           2 :   if (err)
    2655             :     {
    2656           1 :       if (!silent)
    2657           1 :         log_error (_("no gpg-agent running in this session\n"));
    2658             : 
    2659           1 :       if (ctx)
    2660           1 :         assuan_release (ctx);
    2661           1 :       return -1;
    2662             :     }
    2663             : 
    2664           1 :   if (!opt.quiet && !silent)
    2665           0 :     log_info ("gpg-agent running and available\n");
    2666             : 
    2667           1 :   assuan_release (ctx);
    2668           1 :   return 0;
    2669             : }

Generated by: LCOV version 1.11