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