Annotation of embedaddon/strongswan/src/libcharon/daemon.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2006-2017 Tobias Brunner
3: * Copyright (C) 2005-2009 Martin Willi
4: * Copyright (C) 2006 Daniel Roethlisberger
5: * Copyright (C) 2005 Jan Hutter
6: * HSR Hochschule fuer Technik Rapperswil
7: *
8: * This program is free software; you can redistribute it and/or modify it
9: * under the terms of the GNU General Public License as published by the
10: * Free Software Foundation; either version 2 of the License, or (at your
11: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12: *
13: * This program is distributed in the hope that it will be useful, but
14: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16: * for more details.
17: */
18:
19: /*
20: * Copyright (C) 2016 secunet Security Networks AG
21: * Copyright (C) 2016 Thomas Egerer
22: *
23: * Permission is hereby granted, free of charge, to any person obtaining a copy
24: * of this software and associated documentation files (the "Software"), to deal
25: * in the Software without restriction, including without limitation the rights
26: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27: * copies of the Software, and to permit persons to whom the Software is
28: * furnished to do so, subject to the following conditions:
29: *
30: * The above copyright notice and this permission notice shall be included in
31: * all copies or substantial portions of the Software.
32: *
33: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
39: * THE SOFTWARE.
40: */
41:
42: #include <stdio.h>
43: #include <sys/types.h>
44: #include <unistd.h>
45: #include <time.h>
46: #include <errno.h>
47:
48: #ifdef HAVE_SYSLOG
49: #include <syslog.h>
50: #endif
51:
52: #include "daemon.h"
53:
54: #include <library.h>
55: #include <bus/listeners/sys_logger.h>
56: #include <bus/listeners/file_logger.h>
57: #include <collections/array.h>
58: #include <plugins/plugin_feature.h>
59: #include <kernel/kernel_handler.h>
60: #include <processing/jobs/start_action_job.h>
61: #include <threading/mutex.h>
62:
63: #ifndef LOG_AUTHPRIV /* not defined on OpenSolaris */
64: #define LOG_AUTHPRIV LOG_AUTH
65: #endif
66:
67: typedef struct private_daemon_t private_daemon_t;
68:
69: /**
70: * Private additions to daemon_t, contains threads and internal functions.
71: */
72: struct private_daemon_t {
73: /**
74: * Public members of daemon_t.
75: */
76: daemon_t public;
77:
78: /**
79: * Handler for kernel events
80: */
81: kernel_handler_t *kernel_handler;
82:
83: /**
84: * A list of installed loggers (as logger_entry_t*)
85: */
86: linked_list_t *loggers;
87:
88: /**
89: * Cached log levels for default loggers
90: */
91: level_t *levels;
92:
93: /**
94: * Whether to log to stdout/err by default
95: */
96: bool to_stderr;
97:
98: /**
99: * Identifier used for syslog (in the openlog call)
100: */
101: char *syslog_identifier;
102:
103: /**
104: * Mutex for configured loggers
105: */
106: mutex_t *mutex;
107:
108: /**
109: * Integrity check failed?
110: */
111: bool integrity_failed;
112:
113: /**
114: * Number of times we have been initialized
115: */
116: refcount_t ref;
117: };
118:
119: /**
120: * Register plugins if built statically
121: */
122: #ifdef STATIC_PLUGIN_CONSTRUCTORS
123: #include "plugin_constructors.c"
124: #endif
125:
126: /**
127: * One and only instance of the daemon.
128: */
129: daemon_t *charon;
130:
131: /**
132: * hook in library for debugging messages
133: */
134: extern void (*dbg) (debug_t group, level_t level, char *fmt, ...);
135:
136: /**
137: * we store the previous debug function so we can reset it
138: */
139: static void (*dbg_old) (debug_t group, level_t level, char *fmt, ...);
140:
141: /**
142: * Logging hook for library logs, spreads debug message over bus
143: */
144: static void dbg_bus(debug_t group, level_t level, char *fmt, ...)
145: {
146: va_list args;
147:
148: va_start(args, fmt);
149: charon->bus->vlog(charon->bus, group, level, fmt, args);
150: va_end(args);
151: }
152:
153: /**
154: * Data for registered custom loggers
155: */
156: typedef struct {
157: /**
158: * Name of the custom logger (also used for loglevel configuration)
159: */
160: char *name;
161:
162: /**
163: * Constructor to be called for custom logger creation
164: */
165: custom_logger_constructor_t constructor;
166:
167: } custom_logger_entry_t;
168:
169: #define MAX_CUSTOM_LOGGERS 10
170:
171: /**
172: * Static array for logger registration using __attribute__((constructor))
173: */
174: static custom_logger_entry_t custom_loggers[MAX_CUSTOM_LOGGERS];
175: static int custom_logger_count;
176:
177: /**
178: * Described in header
179: */
180: void register_custom_logger(char *name,
181: custom_logger_constructor_t constructor)
182: {
183: if (custom_logger_count < MAX_CUSTOM_LOGGERS - 1)
184: {
185: custom_loggers[custom_logger_count].name = name;
186: custom_loggers[custom_logger_count].constructor = constructor;
187: custom_logger_count++;
188: }
189: else
190: {
191: fprintf(stderr, "failed to register custom logger, please increase "
192: "MAX_CUSTOM_LOGGERS");
193: }
194: }
195:
196: /**
197: * Types of supported loggers
198: */
199: typedef enum {
200: /**
201: * Syslog logger instance
202: */
203: SYS_LOGGER,
204:
205: /**
206: * File logger instance
207: */
208: FILE_LOGGER,
209:
210: /**
211: * Custom logger instance
212: */
213: CUSTOM_LOGGER,
214:
215: } logger_type_t;
216:
217: /**
218: * Some metadata about configured loggers
219: */
220: typedef struct {
221: /**
222: * Target of the logger (syslog facility or filename)
223: */
224: char *target;
225:
226: /**
227: * Type of logger
228: */
229: logger_type_t type;
230:
231: /**
232: * The actual logger
233: */
234: union {
235: sys_logger_t *sys;
236: file_logger_t *file;
237: custom_logger_t *custom;
238: } logger;
239:
240: } logger_entry_t;
241:
242: /**
243: * Destroy a logger entry
244: */
245: static void logger_entry_destroy(logger_entry_t *this)
246: {
247: switch (this->type)
248: {
249: case FILE_LOGGER:
250: DESTROY_IF(this->logger.file);
251: break;
252: case SYS_LOGGER:
253: DESTROY_IF(this->logger.sys);
254: break;
255: case CUSTOM_LOGGER:
256: DESTROY_IF(this->logger.custom);
257: break;
258: }
259: free(this->target);
260: free(this);
261: }
262:
263: /**
264: * Unregister and destroy a logger entry
265: */
266: static void logger_entry_unregister_destroy(logger_entry_t *this)
267: {
268: switch (this->type)
269: {
270: case FILE_LOGGER:
271: charon->bus->remove_logger(charon->bus, &this->logger.file->logger);
272: break;
273: case SYS_LOGGER:
274: charon->bus->remove_logger(charon->bus, &this->logger.sys->logger);
275: break;
276: case CUSTOM_LOGGER:
277: charon->bus->remove_logger(charon->bus,
278: &this->logger.custom->logger);
279: break;
280: }
281: logger_entry_destroy(this);
282: }
283:
284: CALLBACK(logger_entry_match, bool,
285: logger_entry_t *this, va_list args)
286: {
287: logger_type_t type;
288: char *target;
289:
290: VA_ARGS_VGET(args, target, type);
291: return this->type == type && streq(this->target, target);
292: }
293:
294: /**
295: * Handle configured syslog identifier
296: *
297: * mutex must be locked when calling this function
298: */
299: static void handle_syslog_identifier(private_daemon_t *this)
300: {
301: #ifdef HAVE_SYSLOG
302: char *identifier;
303:
304: identifier = lib->settings->get_str(lib->settings, "%s.syslog.identifier",
305: NULL, lib->ns);
306: if (identifier)
307: { /* set identifier, which is prepended to each log line */
308: if (!this->syslog_identifier ||
309: !streq(identifier, this->syslog_identifier))
310: {
311: closelog();
312: this->syslog_identifier = identifier;
313: openlog(this->syslog_identifier, 0, 0);
314: }
315: }
316: else if (this->syslog_identifier)
317: {
318: closelog();
319: this->syslog_identifier = NULL;
320: }
321: #endif /* HAVE_SYSLOG */
322: }
323:
324: /**
325: * Convert the given string into a syslog facility, returns -1 if the facility
326: * is not supported
327: */
328: static int get_syslog_facility(char *facility)
329: {
330: #ifdef HAVE_SYSLOG
331: if (streq(facility, "daemon"))
332: {
333: return LOG_DAEMON;
334: }
335: else if (streq(facility, "auth"))
336: {
337: return LOG_AUTHPRIV;
338: }
339: #endif /* HAVE_SYSLOG */
340: return -1;
341: }
342:
343: /**
344: * Returns an existing or newly created logger entry (if found, it is removed
345: * from the given linked list of existing loggers)
346: */
347: static logger_entry_t *get_logger_entry(char *target, logger_type_t type,
348: linked_list_t *existing,
349: custom_logger_constructor_t constructor)
350: {
351: logger_entry_t *entry;
352:
353: if (!existing->find_first(existing, logger_entry_match, (void**)&entry,
354: target, type))
355: {
356: INIT(entry,
357: .target = strdup(target),
358: .type = type,
359: );
360: switch (type)
361: {
362: case FILE_LOGGER:
363: entry->logger.file = file_logger_create(target);
364: break;
365: case SYS_LOGGER:
366: #ifdef HAVE_SYSLOG
367: entry->logger.sys = sys_logger_create(
368: get_syslog_facility(target));
369: break;
370: #else
371: free(entry);
372: return NULL;
373: #endif /* HAVE_SYSLOG */
374: case CUSTOM_LOGGER:
375: if (constructor)
376: {
377: entry->logger.custom = constructor(target);
378: }
379: if (!entry->logger.custom)
380: {
381: free(entry);
382: return NULL;
383: }
384: break;
385: }
386: }
387: else
388: {
389: existing->remove(existing, entry, NULL);
390: }
391: return entry;
392: }
393:
394: /**
395: * Create or reuse a syslog logger
396: */
397: static sys_logger_t *add_sys_logger(private_daemon_t *this, char *facility,
398: linked_list_t *current_loggers)
399: {
400: logger_entry_t *entry;
401:
402: entry = get_logger_entry(facility, SYS_LOGGER, current_loggers, NULL);
403: if (entry)
404: {
405: this->loggers->insert_last(this->loggers, entry);
406: }
407: return entry ? entry->logger.sys : NULL;
408: }
409:
410: /**
411: * Create or reuse a file logger
412: */
413: static file_logger_t *add_file_logger(private_daemon_t *this, char *filename,
414: linked_list_t *current_loggers)
415: {
416: logger_entry_t *entry;
417:
418: entry = get_logger_entry(filename, FILE_LOGGER, current_loggers, NULL);
419: if (entry)
420: {
421: this->loggers->insert_last(this->loggers, entry);
422: }
423: return entry ? entry->logger.file : NULL;
424: }
425:
426: /**
427: * Create or reuse a custom logger
428: */
429: static custom_logger_t *add_custom_logger(private_daemon_t *this,
430: custom_logger_entry_t *custom,
431: linked_list_t *current_loggers)
432: {
433: logger_entry_t *entry;
434:
435: entry = get_logger_entry(custom->name, CUSTOM_LOGGER, current_loggers,
436: custom->constructor);
437: if (entry)
438: {
439: this->loggers->insert_last(this->loggers, entry);
440: }
441: return entry ? entry->logger.custom : NULL;
442: }
443:
444: /**
445: * Load the given syslog logger configured in strongswan.conf
446: */
447: static void load_sys_logger(private_daemon_t *this, char *facility,
448: linked_list_t *current_loggers)
449: {
450: sys_logger_t *sys_logger;
451: debug_t group;
452: level_t def;
453:
454: if (get_syslog_facility(facility) == -1)
455: {
456: return;
457: }
458:
459: sys_logger = add_sys_logger(this, facility, current_loggers);
460: if (!sys_logger)
461: {
462: return;
463: }
464:
465: sys_logger->set_options(sys_logger,
466: lib->settings->get_bool(lib->settings, "%s.syslog.%s.ike_name",
467: FALSE, lib->ns, facility));
468:
469: def = lib->settings->get_int(lib->settings, "%s.syslog.%s.default", 1,
470: lib->ns, facility);
471: for (group = 0; group < DBG_MAX; group++)
472: {
473: sys_logger->set_level(sys_logger, group,
474: lib->settings->get_int(lib->settings, "%s.syslog.%s.%N", def,
475: lib->ns, facility, debug_lower_names, group));
476: }
477: charon->bus->add_logger(charon->bus, &sys_logger->logger);
478: }
479:
480: /**
481: * Load the given file logger configured in strongswan.conf
482: */
483: static void load_file_logger(private_daemon_t *this, char *section,
484: linked_list_t *current_loggers)
485: {
486: file_logger_t *file_logger;
487: debug_t group;
488: level_t def;
489: bool add_ms, ike_name, flush_line, append;
490: char *time_format, *filename;
491:
492: time_format = lib->settings->get_str(lib->settings,
493: "%s.filelog.%s.time_format", NULL, lib->ns, section);
494: add_ms = lib->settings->get_bool(lib->settings,
495: "%s.filelog.%s.time_add_ms", FALSE, lib->ns, section);
496: ike_name = lib->settings->get_bool(lib->settings,
497: "%s.filelog.%s.ike_name", FALSE, lib->ns, section);
498: flush_line = lib->settings->get_bool(lib->settings,
499: "%s.filelog.%s.flush_line", FALSE, lib->ns, section);
500: append = lib->settings->get_bool(lib->settings,
501: "%s.filelog.%s.append", TRUE, lib->ns, section);
502: filename = lib->settings->get_str(lib->settings,
503: "%s.filelog.%s.path", section, lib->ns, section);
504:
505: file_logger = add_file_logger(this, filename, current_loggers);
506: if (!file_logger)
507: {
508: return;
509: }
510:
511: file_logger->set_options(file_logger, time_format, add_ms, ike_name);
512: file_logger->open(file_logger, flush_line, append);
513:
514: def = lib->settings->get_int(lib->settings, "%s.filelog.%s.default", 1,
515: lib->ns, section);
516: for (group = 0; group < DBG_MAX; group++)
517: {
518: file_logger->set_level(file_logger, group,
519: lib->settings->get_int(lib->settings, "%s.filelog.%s.%N", def,
520: lib->ns, section, debug_lower_names, group));
521: }
522: charon->bus->add_logger(charon->bus, &file_logger->logger);
523: }
524:
525: /**
526: * Load the given custom logger configured in strongswan.conf
527: */
528: static void load_custom_logger(private_daemon_t *this,
529: custom_logger_entry_t *entry,
530: linked_list_t *current_loggers)
531: {
532: custom_logger_t *custom_logger;
533: debug_t group;
534: level_t def;
535:
536: custom_logger = add_custom_logger(this, entry, current_loggers);
537: if (!custom_logger)
538: {
539: return;
540: }
541:
542: def = lib->settings->get_int(lib->settings, "%s.customlog.%s.default", 1,
543: lib->ns, entry->name);
544: for (group = 0; group < DBG_MAX; group++)
545: {
546: custom_logger->set_level(custom_logger, group,
547: lib->settings->get_int(lib->settings, "%s.customlog.%s.%N", def,
548: lib->ns, entry->name, debug_lower_names, group));
549: }
550: if (custom_logger->reload)
551: {
552: custom_logger->reload(custom_logger);
553: }
554: charon->bus->add_logger(charon->bus, &custom_logger->logger);
555: }
556:
557: METHOD(daemon_t, load_loggers, void,
558: private_daemon_t *this)
559: {
560: enumerator_t *enumerator;
561: linked_list_t *current_loggers;
562: char *target;
563: int i;
564:
565: this->mutex->lock(this->mutex);
566: handle_syslog_identifier(this);
567: current_loggers = this->loggers;
568: this->loggers = linked_list_create();
569: enumerator = lib->settings->create_section_enumerator(lib->settings,
570: "%s.syslog", lib->ns);
571: while (enumerator->enumerate(enumerator, &target))
572: {
573: load_sys_logger(this, target, current_loggers);
574: }
575: enumerator->destroy(enumerator);
576:
577: enumerator = lib->settings->create_section_enumerator(lib->settings,
578: "%s.filelog", lib->ns);
579: while (enumerator->enumerate(enumerator, &target))
580: {
581: load_file_logger(this, target, current_loggers);
582: }
583: enumerator->destroy(enumerator);
584:
585: for (i = 0; i < custom_logger_count; ++i)
586: {
587: load_custom_logger(this, &custom_loggers[i], current_loggers);
588: }
589:
590: if (!this->loggers->get_count(this->loggers) && this->levels)
591: { /* setup legacy style default loggers configured via command-line */
592: file_logger_t *file_logger;
593: sys_logger_t *sys_logger;
594: debug_t group;
595:
596: sys_logger = add_sys_logger(this, "daemon", current_loggers);
597: file_logger = add_file_logger(this, "stdout", current_loggers);
598: file_logger->open(file_logger, FALSE, FALSE);
599:
600: for (group = 0; group < DBG_MAX; group++)
601: {
602: if (sys_logger)
603: {
604: sys_logger->set_level(sys_logger, group, this->levels[group]);
605: }
606: if (this->to_stderr)
607: {
608: file_logger->set_level(file_logger, group, this->levels[group]);
609: }
610: }
611: if (sys_logger)
612: {
613: charon->bus->add_logger(charon->bus, &sys_logger->logger);
614: }
615: charon->bus->add_logger(charon->bus, &file_logger->logger);
616:
617: sys_logger = add_sys_logger(this, "auth", current_loggers);
618: if (sys_logger)
619: {
620: sys_logger->set_level(sys_logger, DBG_ANY, LEVEL_AUDIT);
621: charon->bus->add_logger(charon->bus, &sys_logger->logger);
622: }
623: }
624: /* unregister and destroy any unused remaining loggers */
625: current_loggers->destroy_function(current_loggers,
626: (void*)logger_entry_unregister_destroy);
627: this->mutex->unlock(this->mutex);
628: }
629:
630: METHOD(daemon_t, set_default_loggers, void,
631: private_daemon_t *this, level_t levels[DBG_MAX], bool to_stderr)
632: {
633: debug_t group;
634:
635: this->mutex->lock(this->mutex);
636: if (!levels)
637: {
638: free(this->levels);
639: this->levels = NULL;
640: }
641: else
642: {
643: if (!this->levels)
644: {
645: this->levels = calloc(sizeof(level_t), DBG_MAX);
646: }
647: for (group = 0; group < DBG_MAX; group++)
648: {
649: this->levels[group] = levels[group];
650: }
651: this->to_stderr = to_stderr;
652: }
653: this->mutex->unlock(this->mutex);
654: }
655:
656: METHOD(daemon_t, set_level, void,
657: private_daemon_t *this, debug_t group, level_t level)
658: {
659: enumerator_t *enumerator;
660: logger_entry_t *entry;
661:
662: /* we set the loglevel on ALL loggers */
663: this->mutex->lock(this->mutex);
664: enumerator = this->loggers->create_enumerator(this->loggers);
665: while (enumerator->enumerate(enumerator, &entry))
666: {
667: switch (entry->type)
668: {
669: case FILE_LOGGER:
670: entry->logger.file->set_level(entry->logger.file, group, level);
671: charon->bus->add_logger(charon->bus,
672: &entry->logger.file->logger);
673: break;
674: case SYS_LOGGER:
675: entry->logger.sys->set_level(entry->logger.sys, group, level);
676: charon->bus->add_logger(charon->bus,
677: &entry->logger.sys->logger);
678: break;
679: case CUSTOM_LOGGER:
680: entry->logger.custom->set_level(entry->logger.custom, group,
681: level);
682: charon->bus->add_logger(charon->bus,
683: &entry->logger.custom->logger);
684: break;
685: }
686: }
687: enumerator->destroy(enumerator);
688: this->mutex->unlock(this->mutex);
689: }
690:
691: /**
692: * Clean up all daemon resources
693: */
694: static void destroy(private_daemon_t *this)
695: {
696: /* terminate all idle threads */
697: lib->processor->set_threads(lib->processor, 0);
698: /* make sure nobody waits for a DNS query */
699: lib->hosts->flush(lib->hosts);
700: /* close all IKE_SAs */
701: if (this->public.ike_sa_manager)
702: {
703: this->public.ike_sa_manager->flush(this->public.ike_sa_manager);
704: }
705: if (this->public.traps)
706: {
707: this->public.traps->flush(this->public.traps);
708: }
709: if (this->public.shunts)
710: {
711: this->public.shunts->flush(this->public.shunts);
712: }
713: if (this->public.sender)
714: {
715: this->public.sender->flush(this->public.sender);
716: }
717:
718: /* cancel all threads and wait for their termination */
719: lib->processor->cancel(lib->processor);
720:
721: #ifdef ME
722: DESTROY_IF(this->public.connect_manager);
723: DESTROY_IF(this->public.mediation_manager);
724: #endif /* ME */
725: /* make sure the cache and scheduler are clear before unloading plugins */
726: lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
727: lib->scheduler->flush(lib->scheduler);
728: lib->plugins->unload(lib->plugins);
729: DESTROY_IF(this->public.attributes);
730: DESTROY_IF(this->kernel_handler);
731: DESTROY_IF(this->public.traps);
732: DESTROY_IF(this->public.shunts);
733: DESTROY_IF(this->public.redirect);
734: DESTROY_IF(this->public.controller);
735: DESTROY_IF(this->public.eap);
736: DESTROY_IF(this->public.xauth);
737: DESTROY_IF(this->public.backends);
738: DESTROY_IF(this->public.socket);
739: DESTROY_IF(this->public.kernel);
740:
741: /* rehook library logging, shutdown logging */
742: dbg = dbg_old;
743: DESTROY_IF(this->public.bus);
744: this->loggers->destroy_function(this->loggers, (void*)logger_entry_destroy);
745: this->mutex->destroy(this->mutex);
746: free(this->levels);
747: free(this);
748: }
749:
750: /**
751: * Run a set of configured scripts
752: */
753: static void run_scripts(private_daemon_t *this, char *verb)
754: {
755: struct {
756: char *name;
757: char *path;
758: } *script;
759: array_t *scripts = NULL;
760: enumerator_t *enumerator;
761: char *key, *value, *pos, buf[1024];
762: FILE *cmd;
763:
764: /* copy the scripts so we don't hold any locks while executing them */
765: enumerator = lib->settings->create_key_value_enumerator(lib->settings,
766: "%s.%s-scripts", lib->ns, verb);
767: while (enumerator->enumerate(enumerator, &key, &value))
768: {
769: INIT(script,
770: .name = key,
771: .path = value,
772: );
773: array_insert_create(&scripts, ARRAY_TAIL, script);
774: }
775: enumerator->destroy(enumerator);
776:
777: enumerator = array_create_enumerator(scripts);
778: while (enumerator->enumerate(enumerator, &script))
779: {
780: DBG1(DBG_DMN, "executing %s script '%s' (%s)", verb, script->name,
781: script->path);
782: cmd = popen(script->path, "r");
783: if (!cmd)
784: {
785: DBG1(DBG_DMN, "executing %s script '%s' (%s) failed: %s",
786: verb, script->name, script->path, strerror(errno));
787: }
788: else
789: {
790: while (TRUE)
791: {
792: if (!fgets(buf, sizeof(buf), cmd))
793: {
794: if (ferror(cmd))
795: {
796: DBG1(DBG_DMN, "reading from %s script '%s' (%s) failed",
797: verb, script->name, script->path);
798: }
799: break;
800: }
801: else
802: {
803: pos = buf + strlen(buf);
804: if (pos > buf && pos[-1] == '\n')
805: {
806: pos[-1] = '\0';
807: }
808: DBG1(DBG_DMN, "%s: %s", script->name, buf);
809: }
810: }
811: pclose(cmd);
812: }
813: free(script);
814: }
815: enumerator->destroy(enumerator);
816: array_destroy(scripts);
817: }
818:
819: METHOD(daemon_t, start, void,
820: private_daemon_t *this)
821: {
822: /* start the engine, go multithreaded */
823: lib->processor->set_threads(lib->processor,
824: lib->settings->get_int(lib->settings, "%s.threads",
825: DEFAULT_THREADS, lib->ns));
826:
827: run_scripts(this, "start");
828: }
829:
830: /**
831: * Initialize/deinitialize sender and receiver
832: */
833: static bool sender_receiver_cb(void *plugin, plugin_feature_t *feature,
834: bool reg, private_daemon_t *this)
835: {
836: if (reg)
837: {
838: this->public.receiver = receiver_create();
839: if (!this->public.receiver)
840: {
841: return FALSE;
842: }
843: this->public.sender = sender_create();
844: }
845: else
846: {
847: DESTROY_IF(this->public.receiver);
848: DESTROY_IF(this->public.sender);
849: }
850: return TRUE;
851: }
852:
853: /**
854: * Initialize/deinitialize IKE_SA/CHILD_SA managers
855: */
856: static bool sa_managers_cb(void *plugin, plugin_feature_t *feature,
857: bool reg, private_daemon_t *this)
858: {
859: if (reg)
860: {
861: this->public.ike_sa_manager = ike_sa_manager_create();
862: if (!this->public.ike_sa_manager)
863: {
864: return FALSE;
865: }
866: this->public.child_sa_manager = child_sa_manager_create();
867: }
868: else
869: {
870: DESTROY_IF(this->public.ike_sa_manager);
871: DESTROY_IF(this->public.child_sa_manager);
872: }
873: return TRUE;
874: }
875:
876: METHOD(daemon_t, initialize, bool,
877: private_daemon_t *this, char *plugins)
878: {
879: plugin_feature_t features[] = {
880: PLUGIN_PROVIDE(CUSTOM, "libcharon"),
881: PLUGIN_DEPENDS(NONCE_GEN),
882: PLUGIN_DEPENDS(CUSTOM, "libcharon-sa-managers"),
883: PLUGIN_DEPENDS(CUSTOM, "libcharon-receiver"),
884: PLUGIN_DEPENDS(CUSTOM, "kernel-ipsec"),
885: PLUGIN_DEPENDS(CUSTOM, "kernel-net"),
886: PLUGIN_CALLBACK((plugin_feature_callback_t)sender_receiver_cb, this),
887: PLUGIN_PROVIDE(CUSTOM, "libcharon-receiver"),
888: PLUGIN_DEPENDS(HASHER, HASH_SHA1),
889: PLUGIN_DEPENDS(RNG, RNG_STRONG),
890: PLUGIN_DEPENDS(CUSTOM, "socket"),
891: PLUGIN_CALLBACK((plugin_feature_callback_t)sa_managers_cb, this),
892: PLUGIN_PROVIDE(CUSTOM, "libcharon-sa-managers"),
893: PLUGIN_DEPENDS(HASHER, HASH_SHA1),
894: PLUGIN_DEPENDS(RNG, RNG_WEAK),
895: };
896: lib->plugins->add_static_features(lib->plugins, lib->ns, features,
897: countof(features), TRUE, NULL, NULL);
898:
899: /* load plugins, further infrastructure may need it */
900: if (!lib->plugins->load(lib->plugins, plugins))
901: {
902: return FALSE;
903: }
904:
905: /* Queue start_action job */
906: lib->processor->queue_job(lib->processor, (job_t*)start_action_job_create());
907:
908: #ifdef ME
909: this->public.connect_manager = connect_manager_create();
910: if (this->public.connect_manager == NULL)
911: {
912: return FALSE;
913: }
914: this->public.mediation_manager = mediation_manager_create();
915: #endif /* ME */
916:
917: return TRUE;
918: }
919:
920: /**
921: * Create the daemon.
922: */
923: private_daemon_t *daemon_create()
924: {
925: private_daemon_t *this;
926:
927: INIT(this,
928: .public = {
929: .initialize = _initialize,
930: .start = _start,
931: .load_loggers = _load_loggers,
932: .set_default_loggers = _set_default_loggers,
933: .set_level = _set_level,
934: .bus = bus_create(),
935: },
936: .loggers = linked_list_create(),
937: .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
938: .ref = 1,
939: );
940: charon = &this->public;
941: this->public.kernel = kernel_interface_create();
942: this->public.attributes = attribute_manager_create();
943: this->public.controller = controller_create();
944: this->public.eap = eap_manager_create();
945: this->public.xauth = xauth_manager_create();
946: this->public.backends = backend_manager_create();
947: this->public.socket = socket_manager_create();
948: this->public.traps = trap_manager_create();
949: this->public.shunts = shunt_manager_create();
950: this->public.redirect = redirect_manager_create();
951: this->kernel_handler = kernel_handler_create();
952:
953: return this;
954: }
955:
956: /**
957: * Described in header.
958: */
959: void libcharon_deinit()
960: {
961: private_daemon_t *this = (private_daemon_t*)charon;
962:
963: if (!this || !ref_put(&this->ref))
964: { /* have more users */
965: return;
966: }
967:
968: run_scripts(this, "stop");
969:
970: destroy(this);
971: charon = NULL;
972: }
973:
974: /**
975: * Described in header.
976: */
977: bool libcharon_init()
978: {
979: private_daemon_t *this;
980:
981: if (charon)
982: { /* already initialized, increase refcount */
983: this = (private_daemon_t*)charon;
984: ref_get(&this->ref);
985: return !this->integrity_failed;
986: }
987:
988: this = daemon_create();
989:
990: /* for uncritical pseudo random numbers */
991: srandom(time(NULL) + getpid());
992:
993: /* set up hook to log dbg message in library via charons message bus */
994: dbg_old = dbg;
995: dbg = dbg_bus;
996:
997: if (lib->integrity &&
998: !lib->integrity->check(lib->integrity, "libcharon", libcharon_init))
999: {
1000: dbg(DBG_DMN, 1, "integrity check of libcharon failed");
1001: this->integrity_failed = TRUE;
1002: }
1003: return !this->integrity_failed;
1004: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>