conversion from 8 spaces to 4 spaces per tab
[strongswan.git] / src / pluto / plutomain.c
1 /* Pluto main program
2 * Copyright (C) 1997 Angelos D. Keromytis.
3 * Copyright (C) 1998-2001 D. Hugh Redelmeier.
4 * Copyright (C) 2009 Andreas Steffen
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * RCSID $Id$
17 */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <syslog.h>
22 #include <unistd.h>
23 #include <ctype.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/un.h>
29 #include <fcntl.h>
30 #include <getopt.h>
31 #include <resolv.h>
32 #include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
33 #include <sys/queue.h>
34 #include <sys/prctl.h>
35 #include <pwd.h>
36 #include <grp.h>
37
38 #ifdef CAPABILITIES
39 #include <sys/capability.h>
40 #endif /* CAPABILITIES */
41
42 #include <freeswan.h>
43 #include <library.h>
44 #include <debug.h>
45
46 #include <pfkeyv2.h>
47 #include <pfkey.h>
48
49 #include "constants.h"
50 #include "defs.h"
51 #include "id.h"
52 #include "ca.h"
53 #include "certs.h"
54 #include "ac.h"
55 #include "connections.h"
56 #include "foodgroups.h"
57 #include "packet.h"
58 #include "demux.h" /* needs packet.h */
59 #include "server.h"
60 #include "kernel.h"
61 #include "log.h"
62 #include "keys.h"
63 #include "adns.h" /* needs <resolv.h> */
64 #include "dnskey.h" /* needs keys.h and adns.h */
65 #include "rnd.h"
66 #include "state.h"
67 #include "ipsec_doi.h" /* needs demux.h and state.h */
68 #include "ocsp.h"
69 #include "crl.h"
70 #include "fetch.h"
71 #include "xauth.h"
72 #include "sha1.h"
73 #include "md5.h"
74 #include "crypto.h" /* requires sha1.h and md5.h */
75 #include "nat_traversal.h"
76 #include "virtual.h"
77
78 static void
79 usage(const char *mess)
80 {
81 if (mess != NULL && *mess != '\0')
82 fprintf(stderr, "%s\n", mess);
83 fprintf(stderr
84 , "Usage: pluto"
85 " [--help]"
86 " [--version]"
87 " [--optionsfrom <filename>]"
88 " \\\n\t"
89 "[--nofork]"
90 " [--stderrlog]"
91 " [--noklips]"
92 " [--nocrsend]"
93 " \\\n\t"
94 "[--strictcrlpolicy]"
95 " [--crlcheckinterval <interval>]"
96 " [--cachecrls]"
97 " [--uniqueids]"
98 " \\\n\t"
99 "[--interface <ifname>]"
100 " [--ikeport <port-number>]"
101 " \\\n\t"
102 "[--ctlbase <path>]"
103 " \\\n\t"
104 "[--perpeerlogbase <path>] [--perpeerlog]"
105 " \\\n\t"
106 "[--secretsfile <secrets-file>]"
107 " [--policygroupsdir <policygroups-dir>]"
108 " \\\n\t"
109 "[--adns <pathname>]"
110 "[--pkcs11module <path>]"
111 "[--pkcs11keepstate]"
112 "[--pkcs11initargs <string>]"
113 #ifdef DEBUG
114 " \\\n\t"
115 "[--debug-none]"
116 " [--debug-all]"
117 " \\\n\t"
118 "[--debug-raw]"
119 " [--debug-crypt]"
120 " [--debug-parsing]"
121 " [--debug-emitting]"
122 " \\\n\t"
123 "[--debug-control]"
124 " [--debug-lifecycle]"
125 " [--debug-klips]"
126 " [--debug-dns]"
127 " \\\n\t"
128 "[--debug-oppo]"
129 " [--debug-controlmore]"
130 " [--debug-private]"
131 #endif
132 " [ --debug-natt]"
133 " \\\n\t"
134 "[--nat_traversal] [--keep_alive <delay_sec>]"
135 " \\\n\t"
136 "[--force_keepalive] [--disable_port_floating]"
137 " \\\n\t"
138 "[--virtual_private <network_list>]"
139 "\n"
140 "strongSwan %s\n"
141 , ipsec_version_code());
142 exit_pluto(mess == NULL? 0 : 1);
143 }
144
145
146 /* lock file support
147 * - provides convenient way for scripts to find Pluto's pid
148 * - prevents multiple Plutos competing for the same port
149 * - same basename as unix domain control socket
150 * NOTE: will not take account of sharing LOCK_DIR with other systems.
151 */
152
153 static char pluto_lock[sizeof(ctl_addr.sun_path)] = DEFAULT_CTLBASE LOCK_SUFFIX;
154 static bool pluto_lock_created = FALSE;
155
156 /* create lockfile, or die in the attempt */
157 static int
158 create_lock(void)
159 {
160 int fd = open(pluto_lock, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC
161 , S_IRUSR | S_IRGRP | S_IROTH);
162
163 if (fd < 0)
164 {
165 if (errno == EEXIST)
166 {
167 fprintf(stderr, "pluto: lock file \"%s\" already exists\n"
168 , pluto_lock);
169 exit_pluto(10);
170 }
171 else
172 {
173 fprintf(stderr
174 , "pluto: unable to create lock file \"%s\" (%d %s)\n"
175 , pluto_lock, errno, strerror(errno));
176 exit_pluto(1);
177 }
178 }
179 pluto_lock_created = TRUE;
180 return fd;
181 }
182
183 static bool
184 fill_lock(int lockfd, pid_t pid)
185 {
186 char buf[30]; /* holds "<pid>\n" */
187 int len = snprintf(buf, sizeof(buf), "%u\n", (unsigned int) pid);
188 bool ok = len > 0 && write(lockfd, buf, len) == len;
189
190 close(lockfd);
191 return ok;
192 }
193
194 static void delete_lock(void)
195 {
196 if (pluto_lock_created)
197 {
198 delete_ctl_socket();
199 unlink(pluto_lock); /* is noting failure useful? */
200 }
201 }
202
203 static int debug_level = 1;
204
205 /**
206 * pluto dbg function
207 */
208 static void pluto_dbg(int level, char *fmt, ...)
209 {
210 int priority = LOG_INFO;
211 char buffer[8192];
212 char *current = buffer, *next;
213 va_list args;
214
215 if (level <= debug_level)
216 {
217 va_start(args, fmt);
218
219 if (log_to_stderr)
220 {
221 vfprintf(stderr, fmt, args);
222 fprintf(stderr, "\n");
223 }
224 if (log_to_syslog)
225 {
226 /* write in memory buffer first */
227 vsnprintf(buffer, sizeof(buffer), fmt, args);
228
229 /* do a syslog with every line */
230 while (current)
231 {
232 next = strchr(current, '\n');
233 if (next)
234 {
235 *(next++) = '\0';
236 }
237 syslog(priority, "%s\n", current);
238 current = next;
239 }
240 }
241 va_end(args);
242 }
243 }
244
245 /* by default pluto sends certificate requests to its peers */
246 bool no_cr_send = FALSE;
247
248 /* by default the CRL policy is lenient */
249 bool strict_crl_policy = FALSE;
250
251 /* by default CRLs are cached locally as files */
252 bool cache_crls = FALSE;
253
254 /* by default pluto does not check crls dynamically */
255 long crl_check_interval = 0;
256
257 /* path to the PKCS#11 module */
258 char *pkcs11_module_path = NULL;
259
260 /* by default pluto logs out after every smartcard use */
261 bool pkcs11_keep_state = FALSE;
262
263 /* by default pluto does not allow pkcs11 proxy access via whack */
264 bool pkcs11_proxy = FALSE;
265
266 /* argument string to pass to PKCS#11 module.
267 * Not used for compliant modules, just for NSS softoken
268 */
269 static const char *pkcs11_init_args = NULL;
270
271 int
272 main(int argc, char **argv)
273 {
274 bool fork_desired = TRUE;
275 bool log_to_stderr_desired = FALSE;
276 bool nat_traversal = FALSE;
277 bool nat_t_spf = TRUE; /* support port floating */
278 unsigned int keep_alive = 0;
279 bool force_keepalive = FALSE;
280 char *virtual_private = NULL;
281 int lockfd;
282 #ifdef CAPABILITIES
283 cap_t caps;
284 int keep[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE };
285 #endif /* CAPABILITIES */
286
287 library_init(STRONGSWAN_CONF);
288
289 /* handle arguments */
290 for (;;)
291 {
292 # define DBG_OFFSET 256
293 static const struct option long_opts[] = {
294 /* name, has_arg, flag, val */
295 { "help", no_argument, NULL, 'h' },
296 { "version", no_argument, NULL, 'v' },
297 { "optionsfrom", required_argument, NULL, '+' },
298 { "nofork", no_argument, NULL, 'd' },
299 { "stderrlog", no_argument, NULL, 'e' },
300 { "noklips", no_argument, NULL, 'n' },
301 { "nocrsend", no_argument, NULL, 'c' },
302 { "strictcrlpolicy", no_argument, NULL, 'r' },
303 { "crlcheckinterval", required_argument, NULL, 'x'},
304 { "cachecrls", no_argument, NULL, 'C' },
305 { "uniqueids", no_argument, NULL, 'u' },
306 { "interface", required_argument, NULL, 'i' },
307 { "ikeport", required_argument, NULL, 'p' },
308 { "ctlbase", required_argument, NULL, 'b' },
309 { "secretsfile", required_argument, NULL, 's' },
310 { "foodgroupsdir", required_argument, NULL, 'f' },
311 { "perpeerlogbase", required_argument, NULL, 'P' },
312 { "perpeerlog", no_argument, NULL, 'l' },
313 { "policygroupsdir", required_argument, NULL, 'f' },
314 #ifdef USE_LWRES
315 { "lwdnsq", required_argument, NULL, 'a' },
316 #else /* !USE_LWRES */
317 { "adns", required_argument, NULL, 'a' },
318 #endif /* !USE_LWRES */
319 { "pkcs11module", required_argument, NULL, 'm' },
320 { "pkcs11keepstate", no_argument, NULL, 'k' },
321 { "pkcs11initargs", required_argument, NULL, 'z' },
322 { "pkcs11proxy", no_argument, NULL, 'y' },
323 { "nat_traversal", no_argument, NULL, '1' },
324 { "keep_alive", required_argument, NULL, '2' },
325 { "force_keepalive", no_argument, NULL, '3' },
326 { "disable_port_floating", no_argument, NULL, '4' },
327 { "debug-natt", no_argument, NULL, '5' },
328 { "virtual_private", required_argument, NULL, '6' },
329 #ifdef DEBUG
330 { "debug-none", no_argument, NULL, 'N' },
331 { "debug-all", no_argument, NULL, 'A' },
332 { "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },
333 { "debug-crypt", no_argument, NULL, DBG_CRYPT + DBG_OFFSET },
334 { "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
335 { "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET },
336 { "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET },
337 { "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET },
338 { "debug-klips", no_argument, NULL, DBG_KLIPS + DBG_OFFSET },
339 { "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET },
340 { "debug-oppo", no_argument, NULL, DBG_OPPO + DBG_OFFSET },
341 { "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET },
342 { "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },
343
344 { "impair-delay-adns-key-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_KEY_ANSWER + DBG_OFFSET },
345 { "impair-delay-adns-txt-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_TXT_ANSWER + DBG_OFFSET },
346 { "impair-bust-mi2", no_argument, NULL, IMPAIR_BUST_MI2 + DBG_OFFSET },
347 { "impair-bust-mr2", no_argument, NULL, IMPAIR_BUST_MR2 + DBG_OFFSET },
348 #endif
349 { 0,0,0,0 }
350 };
351 /* Note: we don't like the way short options get parsed
352 * by getopt_long, so we simply pass an empty string as
353 * the list. It could be "hvdenp:l:s:" "NARXPECK".
354 */
355 int c = getopt_long(argc, argv, "", long_opts, NULL);
356
357 /* Note: "breaking" from case terminates loop */
358 switch (c)
359 {
360 case EOF: /* end of flags */
361 break;
362
363 case 0: /* long option already handled */
364 continue;
365
366 case ':': /* diagnostic already printed by getopt_long */
367 case '?': /* diagnostic already printed by getopt_long */
368 usage("");
369 break; /* not actually reached */
370
371 case 'h': /* --help */
372 usage(NULL);
373 break; /* not actually reached */
374
375 case 'v': /* --version */
376 {
377 const char **sp = ipsec_copyright_notice();
378
379 printf("%s%s\n", ipsec_version_string(),
380 compile_time_interop_options);
381 for (; *sp != NULL; sp++)
382 puts(*sp);
383 }
384 exit_pluto(0);
385 break; /* not actually reached */
386
387 case '+': /* --optionsfrom <filename> */
388 optionsfrom(optarg, &argc, &argv, optind, stderr);
389 /* does not return on error */
390 continue;
391
392 case 'd': /* --nofork*/
393 fork_desired = FALSE;
394 continue;
395
396 case 'e': /* --stderrlog */
397 log_to_stderr_desired = TRUE;
398 continue;
399
400 case 'n': /* --noklips */
401 no_klips = TRUE;
402 continue;
403
404 case 'c': /* --nocrsend */
405 no_cr_send = TRUE;
406 continue;
407
408 case 'r': /* --strictcrlpolicy */
409 strict_crl_policy = TRUE;
410 continue;
411
412 case 'x': /* --crlcheckinterval <time>*/
413 if (optarg == NULL || !isdigit(optarg[0]))
414 usage("missing interval time");
415
416 {
417 char *endptr;
418 long interval = strtol(optarg, &endptr, 0);
419
420 if (*endptr != '\0' || endptr == optarg
421 || interval <= 0)
422 usage("<interval-time> must be a positive number");
423 crl_check_interval = interval;
424 }
425 continue;
426
427 case 'C': /* --cachecrls */
428 cache_crls = TRUE;
429 continue;
430
431 case 'u': /* --uniqueids */
432 uniqueIDs = TRUE;
433 continue;
434
435 case 'i': /* --interface <ifname> */
436 if (!use_interface(optarg))
437 usage("too many --interface specifications");
438 continue;
439
440 case 'p': /* --port <portnumber> */
441 if (optarg == NULL || !isdigit(optarg[0]))
442 usage("missing port number");
443
444 {
445 char *endptr;
446 long port = strtol(optarg, &endptr, 0);
447
448 if (*endptr != '\0' || endptr == optarg
449 || port <= 0 || port > 0x10000)
450 usage("<port-number> must be a number between 1 and 65535");
451 pluto_port = port;
452 }
453 continue;
454
455 case 'b': /* --ctlbase <path> */
456 if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
457 , "%s%s", optarg, CTL_SUFFIX) == -1)
458 usage("<path>" CTL_SUFFIX " too long for sun_path");
459 if (snprintf(info_addr.sun_path, sizeof(info_addr.sun_path)
460 , "%s%s", optarg, INFO_SUFFIX) == -1)
461 usage("<path>" INFO_SUFFIX " too long for sun_path");
462 if (snprintf(pluto_lock, sizeof(pluto_lock)
463 , "%s%s", optarg, LOCK_SUFFIX) == -1)
464 usage("<path>" LOCK_SUFFIX " must fit");
465 continue;
466
467 case 's': /* --secretsfile <secrets-file> */
468 shared_secrets_file = optarg;
469 continue;
470
471 case 'f': /* --policygroupsdir <policygroups-dir> */
472 policygroups_dir = optarg;
473 continue;
474
475 case 'a': /* --adns <pathname> */
476 pluto_adns_option = optarg;
477 continue;
478
479 case 'm': /* --pkcs11module <pathname> */
480 pkcs11_module_path = optarg;
481 continue;
482
483 case 'k': /* --pkcs11keepstate */
484 pkcs11_keep_state = TRUE;
485 continue;
486
487 case 'y': /* --pkcs11proxy */
488 pkcs11_proxy = TRUE;
489 continue;
490
491 case 'z': /* --pkcs11initargs */
492 pkcs11_init_args = optarg;
493 continue;
494
495 #ifdef DEBUG
496 case 'N': /* --debug-none */
497 base_debugging = DBG_NONE;
498 continue;
499
500 case 'A': /* --debug-all */
501 base_debugging = DBG_ALL;
502 continue;
503 #endif
504
505 case 'P': /* --perpeerlogbase */
506 base_perpeer_logdir = optarg;
507 continue;
508
509 case 'l':
510 log_to_perpeer = TRUE;
511 continue;
512
513 case '1': /* --nat_traversal */
514 nat_traversal = TRUE;
515 continue;
516 case '2': /* --keep_alive */
517 keep_alive = atoi(optarg);
518 continue;
519 case '3': /* --force_keepalive */
520 force_keepalive = TRUE;
521 continue;
522 case '4': /* --disable_port_floating */
523 nat_t_spf = FALSE;
524 continue;
525 case '5': /* --debug-nat_t */
526 base_debugging |= DBG_NATT;
527 continue;
528 case '6': /* --virtual_private */
529 virtual_private = optarg;
530 continue;
531
532 default:
533 #ifdef DEBUG
534 if (c >= DBG_OFFSET)
535 {
536 base_debugging |= c - DBG_OFFSET;
537 continue;
538 }
539 # undef DBG_OFFSET
540 #endif
541 bad_case(c);
542 }
543 break;
544 }
545 if (optind != argc)
546 usage("unexpected argument");
547 reset_debugging();
548 lockfd = create_lock();
549
550 /* select between logging methods */
551
552 if (log_to_stderr_desired)
553 {
554 log_to_syslog = FALSE;
555 }
556 else
557 {
558 log_to_stderr = FALSE;
559 }
560
561 /* set the logging function of pfkey debugging */
562 #ifdef DEBUG
563 pfkey_debug_func = DBG_log;
564 #else
565 pfkey_debug_func = NULL;
566 #endif
567
568 /* create control socket.
569 * We must create it before the parent process returns so that
570 * there will be no race condition in using it. The easiest
571 * place to do this is before the daemon fork.
572 */
573 {
574 err_t ugh = init_ctl_socket();
575
576 if (ugh != NULL)
577 {
578 fprintf(stderr, "pluto: %s", ugh);
579 exit_pluto(1);
580 }
581 }
582
583 /* If not suppressed, do daemon fork */
584
585 if (fork_desired)
586 {
587 {
588 pid_t pid = fork();
589
590 if (pid < 0)
591 {
592 int e = errno;
593
594 fprintf(stderr, "pluto: fork failed (%d %s)\n",
595 errno, strerror(e));
596 exit_pluto(1);
597 }
598
599 if (pid != 0)
600 {
601 /* parent: die, after filling PID into lock file.
602 * must not use exit_pluto: lock would be removed!
603 */
604 exit(fill_lock(lockfd, pid)? 0 : 1);
605 }
606 }
607
608 if (setsid() < 0)
609 {
610 int e = errno;
611
612 fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",
613 errno, strerror(e));
614 exit_pluto(1);
615 }
616 }
617 else
618 {
619 /* no daemon fork: we have to fill in lock file */
620 (void) fill_lock(lockfd, getpid());
621 fprintf(stdout, "Pluto initialized\n");
622 fflush(stdout);
623 }
624
625 /* Close everything but ctl_fd and (if needed) stderr.
626 * There is some danger that a library that we don't know
627 * about is using some fd that we don't know about.
628 * I guess we'll soon find out.
629 */
630 {
631 int i;
632
633 for (i = getdtablesize() - 1; i >= 0; i--) /* Bad hack */
634 {
635 if ((!log_to_stderr || i != 2) && i != ctl_fd)
636 close(i);
637 }
638
639 /* make sure that stdin, stdout, stderr are reserved */
640 if (open("/dev/null", O_RDONLY) != 0)
641 abort();
642 if (dup2(0, 1) != 1)
643 abort();
644 if (!log_to_stderr && dup2(0, 2) != 2)
645 abort();
646 }
647
648 /* enable pluto debugging hook */
649 dbg = pluto_dbg;
650
651 init_constants();
652 init_log("pluto");
653
654 /* Note: some scripts may look for this exact message -- don't change
655 * ipsec barf was one, but it no longer does.
656 */
657 plog("Starting Pluto (strongSwan Version %s%s)"
658 , ipsec_version_code()
659 , compile_time_interop_options);
660
661 init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
662 init_virtual_ip(virtual_private);
663 scx_init(pkcs11_module_path, pkcs11_init_args); /* load and initialize PKCS #11 module */
664 xauth_init(); /* load and initialize XAUTH module */
665 init_rnd_pool();
666 init_secret();
667 init_states();
668 init_crypto();
669 init_demux();
670 init_kernel();
671 init_adns();
672 init_id();
673 init_fetch();
674
675 /* drop unneeded capabilities and change UID/GID */
676 prctl(PR_SET_KEEPCAPS, 1);
677
678 #ifdef IPSEC_GROUP
679 {
680 struct group group, *grp;
681 char buf[1024];
682
683 if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) != 0 ||
684 grp == NULL || setgid(grp->gr_gid) != 0)
685 {
686 plog("unable to change daemon group");
687 abort();
688 }
689 }
690 #endif
691 #ifdef IPSEC_USER
692 {
693 struct passwd passwd, *pwp;
694 char buf[1024];
695
696 if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) != 0 ||
697 pwp == NULL || setuid(pwp->pw_uid) != 0)
698 {
699 plog("unable to change daemon user");
700 abort();
701 }
702 }
703 #endif
704
705 #ifdef CAPABILITIES
706 caps = cap_init();
707 cap_set_flag(caps, CAP_EFFECTIVE, 2, keep, CAP_SET);
708 cap_set_flag(caps, CAP_INHERITABLE, 2, keep, CAP_SET);
709 cap_set_flag(caps, CAP_PERMITTED, 2, keep, CAP_SET);
710 if (cap_set_proc(caps) != 0)
711 {
712 plog("unable to drop daemon capabilities");
713 abort();
714 }
715 cap_free(caps);
716 #endif /* CAPABILITIES */
717
718 /* loading X.509 CA certificates */
719 load_authcerts("CA cert", CA_CERT_PATH, AUTH_CA);
720 /* loading X.509 AA certificates */
721 load_authcerts("AA cert", AA_CERT_PATH, AUTH_AA);
722 /* loading X.509 OCSP certificates */
723 load_authcerts("OCSP cert", OCSP_CERT_PATH, AUTH_OCSP);
724 /* loading X.509 CRLs */
725 load_crls();
726 /* loading attribute certificates (experimental) */
727 load_acerts();
728
729 daily_log_event();
730 call_server();
731 return -1; /* Shouldn't ever reach this */
732 }
733
734 /* leave pluto, with status.
735 * Once child is launched, parent must not exit this way because
736 * the lock would be released.
737 *
738 * 0 OK
739 * 1 general discomfort
740 * 10 lock file exists
741 */
742 void
743 exit_pluto(int status)
744 {
745 reset_globals(); /* needed because we may be called in odd state */
746 free_preshared_secrets();
747 free_remembered_public_keys();
748 delete_every_connection();
749 free_crl_fetch(); /* free chain of crl fetch requests */
750 free_ocsp_fetch(); /* free chain of ocsp fetch requests */
751 free_authcerts(); /* free chain of X.509 authority certificates */
752 free_crls(); /* free chain of X.509 CRLs */
753 free_acerts(); /* free chain of X.509 attribute certificates */
754 free_ca_infos(); /* free chain of X.509 CA information records */
755 free_ocsp(); /* free ocsp cache */
756 free_ifaces();
757 scx_finalize(); /* finalize and unload PKCS #11 module */
758 xauth_finalize(); /* finalize and unload XAUTH module */
759 stop_adns();
760 free_md_pool();
761 free_crypto();
762 free_id(); /* free myids */
763 free_events(); /* free remaining events */
764 delete_lock();
765 library_deinit();
766 close_log();
767 exit(status);
768 }
769
770 /*
771 * Local Variables:
772 * c-basic-offset:4
773 * c-style: pluto
774 * End:
775 */