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