2 * Copyright (C) 2006-2010 Tobias Brunner
3 * Copyright (C) 2005-2009 Martin Willi
4 * Copyright (C) 2006 Daniel Roethlisberger
5 * Copyright (C) 2005 Jan Hutter
6 * Hochschule fuer Technik Rapperswil
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>.
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
20 #include <sys/types.h>
25 #include <sys/capability.h>
26 #endif /* CAPABILITIES */
31 #include <selectors/traffic_selector.h>
32 #include <config/proposal.h>
34 #ifndef LOG_AUTHPRIV /* not defined on OpenSolaris */
35 #define LOG_AUTHPRIV LOG_AUTH
38 typedef struct private_daemon_t private_daemon_t
;
41 * Private additions to daemon_t, contains threads and internal functions.
43 struct private_daemon_t
{
45 * Public members of daemon_t.
51 * capabilities to keep
54 #endif /* CAPABILITIES */
58 * One and only instance of the daemon.
63 * hook in library for debugging messages
65 extern void (*dbg
) (int level
, char *fmt
, ...);
68 * we store the previous debug function so we can reset it
70 static void (*dbg_old
) (int level
, char *fmt
, ...);
73 * Logging hook for library logs, spreads debug message over bus
75 static void dbg_bus(int level
, char *fmt
, ...)
80 charon
->bus
->vlog(charon
->bus
, DBG_LIB
, level
, fmt
, args
);
85 * Clean up all daemon resources
87 static void destroy(private_daemon_t
*this)
89 /* terminate all idle threads */
90 if (this->public.processor
)
92 this->public.processor
->set_threads(this->public.processor
, 0);
94 /* close all IKE_SAs */
95 if (this->public.ike_sa_manager
)
97 this->public.ike_sa_manager
->flush(this->public.ike_sa_manager
);
99 DESTROY_IF(this->public.receiver
);
100 /* unload plugins to release threads */
101 lib
->plugins
->unload(lib
->plugins
);
103 cap_free(this->caps
);
104 #endif /* CAPABILITIES */
105 DESTROY_IF(this->public.traps
);
106 DESTROY_IF(this->public.ike_sa_manager
);
107 DESTROY_IF(this->public.kernel_interface
);
108 DESTROY_IF(this->public.scheduler
);
109 DESTROY_IF(this->public.controller
);
110 DESTROY_IF(this->public.eap
);
111 DESTROY_IF(this->public.sim
);
113 DESTROY_IF(this->public.connect_manager
);
114 DESTROY_IF(this->public.mediation_manager
);
116 DESTROY_IF(this->public.backends
);
117 DESTROY_IF(this->public.credentials
);
118 DESTROY_IF(this->public.sender
);
119 DESTROY_IF(this->public.socket
);
120 /* wait until all threads are gone */
121 DESTROY_IF(this->public.processor
);
123 /* rehook library logging, shutdown logging */
125 DESTROY_IF(this->public.bus
);
126 this->public.file_loggers
->destroy_offset(this->public.file_loggers
,
127 offsetof(file_logger_t
, destroy
));
128 this->public.sys_loggers
->destroy_offset(this->public.sys_loggers
,
129 offsetof(sys_logger_t
, destroy
));
133 METHOD(daemon_t
, keep_cap
, void,
134 private_daemon_t
*this, u_int cap
)
137 cap_set_flag(this->caps
, CAP_EFFECTIVE
, 1, &cap
, CAP_SET
);
138 cap_set_flag(this->caps
, CAP_INHERITABLE
, 1, &cap
, CAP_SET
);
139 cap_set_flag(this->caps
, CAP_PERMITTED
, 1, &cap
, CAP_SET
);
140 #endif /* CAPABILITIES */
143 METHOD(daemon_t
, drop_capabilities
, bool,
144 private_daemon_t
*this)
147 if (cap_set_proc(this->caps
) != 0)
151 #endif /* CAPABILITIES */
155 METHOD(daemon_t
, start
, void,
156 private_daemon_t
*this)
158 /* start the engine, go multithreaded */
159 charon
->processor
->set_threads(charon
->processor
,
160 lib
->settings
->get_int(lib
->settings
, "charon.threads",
167 static void print_plugins()
169 char buf
[512], *plugin
;
171 enumerator_t
*enumerator
;
174 enumerator
= lib
->plugins
->create_plugin_enumerator(lib
->plugins
);
175 while (len
< sizeof(buf
) && enumerator
->enumerate(enumerator
, &plugin
))
177 len
+= snprintf(&buf
[len
], sizeof(buf
)-len
, "%s ", plugin
);
179 enumerator
->destroy(enumerator
);
180 DBG1(DBG_DMN
, "loaded plugins: %s", buf
);
186 static void initialize_loggers(private_daemon_t
*this, bool use_stderr
,
189 sys_logger_t
*sys_logger
;
190 file_logger_t
*file_logger
;
191 enumerator_t
*enumerator
;
192 char *facility
, *filename
;
193 int loggers_defined
= 0;
199 /* setup sysloggers */
200 enumerator
= lib
->settings
->create_section_enumerator(lib
->settings
,
202 while (enumerator
->enumerate(enumerator
, &facility
))
205 if (streq(facility
, "daemon"))
207 sys_logger
= sys_logger_create(LOG_DAEMON
);
209 else if (streq(facility
, "auth"))
211 sys_logger
= sys_logger_create(LOG_AUTHPRIV
);
217 def
= lib
->settings
->get_int(lib
->settings
,
218 "charon.syslog.%s.default", 1, facility
);
219 for (group
= 0; group
< DBG_MAX
; group
++)
221 sys_logger
->set_level(sys_logger
, group
,
222 lib
->settings
->get_int(lib
->settings
,
223 "charon.syslog.%s.%N", def
,
224 facility
, debug_lower_names
, group
));
226 this->public.sys_loggers
->insert_last(this->public.sys_loggers
,
228 this->public.bus
->add_listener(this->public.bus
, &sys_logger
->listener
);
230 enumerator
->destroy(enumerator
);
232 /* and file loggers */
233 enumerator
= lib
->settings
->create_section_enumerator(lib
->settings
,
235 while (enumerator
->enumerate(enumerator
, &filename
))
238 if (streq(filename
, "stderr"))
242 else if (streq(filename
, "stdout"))
248 append
= lib
->settings
->get_bool(lib
->settings
,
249 "charon.filelog.%s.append", TRUE
, filename
);
250 file
= fopen(filename
, append ?
"a" : "w");
253 DBG1(DBG_DMN
, "opening file %s for logging failed: %s",
254 filename
, strerror(errno
));
258 file_logger
= file_logger_create(file
);
259 def
= lib
->settings
->get_int(lib
->settings
,
260 "charon.filelog.%s.default", 1, filename
);
261 for (group
= 0; group
< DBG_MAX
; group
++)
263 file_logger
->set_level(file_logger
, group
,
264 lib
->settings
->get_int(lib
->settings
,
265 "charon.filelog.%s.%N", def
,
266 filename
, debug_lower_names
, group
));
268 this->public.file_loggers
->insert_last(this->public.file_loggers
,
270 this->public.bus
->add_listener(this->public.bus
, &file_logger
->listener
);
273 enumerator
->destroy(enumerator
);
275 /* set up legacy style default loggers provided via command-line */
276 if (!loggers_defined
)
278 /* set up default stdout file_logger */
279 file_logger
= file_logger_create(stdout
);
280 this->public.bus
->add_listener(this->public.bus
, &file_logger
->listener
);
281 this->public.file_loggers
->insert_last(this->public.file_loggers
,
283 /* set up default daemon sys_logger */
284 sys_logger
= sys_logger_create(LOG_DAEMON
);
285 this->public.bus
->add_listener(this->public.bus
, &sys_logger
->listener
);
286 this->public.sys_loggers
->insert_last(this->public.sys_loggers
,
288 for (group
= 0; group
< DBG_MAX
; group
++)
290 sys_logger
->set_level(sys_logger
, group
, levels
[group
]);
293 file_logger
->set_level(file_logger
, group
, levels
[group
]);
297 /* set up default auth sys_logger */
298 sys_logger
= sys_logger_create(LOG_AUTHPRIV
);
299 this->public.bus
->add_listener(this->public.bus
, &sys_logger
->listener
);
300 this->public.sys_loggers
->insert_last(this->public.sys_loggers
,
302 sys_logger
->set_level(sys_logger
, DBG_ANY
, LEVEL_AUDIT
);
306 METHOD(daemon_t
, initialize
, bool,
307 private_daemon_t
*this, bool syslog
, level_t levels
[])
309 /* for uncritical pseudo random numbers */
310 srandom(time(NULL
) + getpid());
312 /* setup bus and it's listeners first to enable log output */
313 this->public.bus
= bus_create();
314 /* set up hook to log dbg message in library via charons message bus */
318 initialize_loggers(this, !syslog
, levels
);
320 DBG1(DBG_DMN
, "Starting IKEv2 charon daemon (strongSwan "VERSION
")");
324 DBG1(DBG_DMN
, "integrity tests enabled:");
325 DBG1(DBG_DMN
, "lib 'libstrongswan': passed file and segment integrity tests");
326 DBG1(DBG_DMN
, "lib 'libcharon': passed file and segment integrity tests");
327 DBG1(DBG_DMN
, "daemon 'charon': passed file integrity test");
330 /* load secrets, ca certificates and crls */
331 this->public.processor
= processor_create();
332 this->public.scheduler
= scheduler_create();
333 this->public.credentials
= credential_manager_create();
334 this->public.controller
= controller_create();
335 this->public.eap
= eap_manager_create();
336 this->public.sim
= sim_manager_create();
337 this->public.backends
= backend_manager_create();
338 this->public.kernel_interface
= kernel_interface_create();
339 this->public.socket
= socket_manager_create();
340 this->public.traps
= trap_manager_create();
342 /* load plugins, further infrastructure may need it */
343 if (!lib
->plugins
->load(lib
->plugins
, NULL
,
344 lib
->settings
->get_str(lib
->settings
, "charon.load", PLUGINS
)))
351 this->public.ike_sa_manager
= ike_sa_manager_create();
352 if (this->public.ike_sa_manager
== NULL
)
356 this->public.sender
= sender_create();
357 this->public.receiver
= receiver_create();
358 if (this->public.receiver
== NULL
)
364 this->public.connect_manager
= connect_manager_create();
365 if (this->public.connect_manager
== NULL
)
369 this->public.mediation_manager
= mediation_manager_create();
378 private_daemon_t
*daemon_create()
380 private_daemon_t
*this;
384 .keep_cap
= _keep_cap
,
385 .drop_capabilities
= _drop_capabilities
,
386 .initialize
= _initialize
,
388 .file_loggers
= linked_list_create(),
389 .sys_loggers
= linked_list_create(),
394 this->caps
= cap_init();
395 keep_cap(this, CAP_NET_ADMIN
);
396 if (lib
->leak_detective
)
398 keep_cap(this, CAP_SYS_NICE
);
400 #endif /* CAPABILITIES */
406 * Described in header.
408 void libcharon_deinit()
411 destroy((private_daemon_t
*)charon
);
416 * Described in header.
418 bool libcharon_init()
420 private_daemon_t
*this;
422 this = daemon_create();
423 charon
= &this->public;
425 lib
->printf_hook
->add_handler(lib
->printf_hook
, 'R',
426 traffic_selector_printf_hook
,
427 PRINTF_HOOK_ARGTYPE_POINTER
,
428 PRINTF_HOOK_ARGTYPE_END
);
429 lib
->printf_hook
->add_handler(lib
->printf_hook
, 'P',
430 proposal_printf_hook
,
431 PRINTF_HOOK_ARGTYPE_POINTER
,
432 PRINTF_HOOK_ARGTYPE_END
);
434 if (lib
->integrity
&&
435 !lib
->integrity
->check(lib
->integrity
, "libcharon", libcharon_init
))
437 dbg(1, "integrity check of libcharon failed");