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>
27 #ifdef HAVE_SYS_CAPABILITY_H
28 #include <sys/capability.h>
29 #endif /* HAVE_SYS_CAPABILITY_H */
30 #endif /* CAPABILITIES */
35 #include <config/proposal.h>
36 #include <kernel/kernel_handler.h>
38 #ifndef LOG_AUTHPRIV /* not defined on OpenSolaris */
39 #define LOG_AUTHPRIV LOG_AUTH
42 typedef struct private_daemon_t private_daemon_t
;
45 * Private additions to daemon_t, contains threads and internal functions.
47 struct private_daemon_t
{
49 * Public members of daemon_t.
54 * Handler for kernel events
56 kernel_handler_t
*kernel_handler
;
59 * capabilities to keep
61 #ifdef CAPABILITIES_LIBCAP
63 #endif /* CAPABILITIES_LIBCAP */
64 #ifdef CAPABILITIES_NATIVE
65 struct __user_cap_data_struct caps
;
66 #endif /* CAPABILITIES_NATIVE */
71 * One and only instance of the daemon.
76 * hook in library for debugging messages
78 extern void (*dbg
) (debug_t group
, level_t level
, char *fmt
, ...);
81 * we store the previous debug function so we can reset it
83 static void (*dbg_old
) (debug_t group
, level_t level
, char *fmt
, ...);
86 * Logging hook for library logs, spreads debug message over bus
88 static void dbg_bus(debug_t group
, level_t level
, char *fmt
, ...)
93 charon
->bus
->vlog(charon
->bus
, group
, level
, fmt
, args
);
98 * Clean up all daemon resources
100 static void destroy(private_daemon_t
*this)
102 /* terminate all idle threads */
103 lib
->processor
->set_threads(lib
->processor
, 0);
105 /* close all IKE_SAs */
106 if (this->public.ike_sa_manager
)
108 this->public.ike_sa_manager
->flush(this->public.ike_sa_manager
);
110 DESTROY_IF(this->public.receiver
);
111 DESTROY_IF(this->public.sender
);
112 /* unload plugins to release threads */
113 lib
->plugins
->unload(lib
->plugins
);
114 #ifdef CAPABILITIES_LIBCAP
115 cap_free(this->caps
);
116 #endif /* CAPABILITIES_LIBCAP */
117 DESTROY_IF(this->kernel_handler
);
118 DESTROY_IF(this->public.traps
);
119 DESTROY_IF(this->public.ike_sa_manager
);
120 DESTROY_IF(this->public.controller
);
121 DESTROY_IF(this->public.eap
);
122 DESTROY_IF(this->public.sim
);
123 DESTROY_IF(this->public.tnccs
);
125 DESTROY_IF(this->public.connect_manager
);
126 DESTROY_IF(this->public.mediation_manager
);
128 DESTROY_IF(this->public.backends
);
129 DESTROY_IF(this->public.socket
);
131 /* rehook library logging, shutdown logging */
133 DESTROY_IF(this->public.bus
);
134 this->public.file_loggers
->destroy_offset(this->public.file_loggers
,
135 offsetof(file_logger_t
, destroy
));
136 this->public.sys_loggers
->destroy_offset(this->public.sys_loggers
,
137 offsetof(sys_logger_t
, destroy
));
141 METHOD(daemon_t
, keep_cap
, void,
142 private_daemon_t
*this, u_int cap
)
144 #ifdef CAPABILITIES_LIBCAP
145 cap_set_flag(this->caps
, CAP_EFFECTIVE
, 1, &cap
, CAP_SET
);
146 cap_set_flag(this->caps
, CAP_INHERITABLE
, 1, &cap
, CAP_SET
);
147 cap_set_flag(this->caps
, CAP_PERMITTED
, 1, &cap
, CAP_SET
);
148 #endif /* CAPABILITIES_LIBCAP */
149 #ifdef CAPABILITIES_NATIVE
150 this->caps
.effective
|= 1 << cap
;
151 this->caps
.permitted
|= 1 << cap
;
152 this->caps
.inheritable
|= 1 << cap
;
153 #endif /* CAPABILITIES_NATIVE */
156 METHOD(daemon_t
, drop_capabilities
, bool,
157 private_daemon_t
*this)
159 #ifdef CAPABILITIES_LIBCAP
160 if (cap_set_proc(this->caps
) != 0)
164 #endif /* CAPABILITIES_LIBCAP */
165 #ifdef CAPABILITIES_NATIVE
166 struct __user_cap_header_struct header
= {
167 .version
= _LINUX_CAPABILITY_VERSION
,
169 if (capset(&header
, &this->caps
) != 0)
173 #endif /* CAPABILITIES_NATIVE */
177 METHOD(daemon_t
, start
, void,
178 private_daemon_t
*this)
180 /* start the engine, go multithreaded */
181 lib
->processor
->set_threads(lib
->processor
,
182 lib
->settings
->get_int(lib
->settings
, "charon.threads",
189 static void print_plugins()
191 char buf
[512], *plugin
;
193 enumerator_t
*enumerator
;
196 enumerator
= lib
->plugins
->create_plugin_enumerator(lib
->plugins
);
197 while (len
< sizeof(buf
) && enumerator
->enumerate(enumerator
, &plugin
))
199 len
+= snprintf(&buf
[len
], sizeof(buf
)-len
, "%s ", plugin
);
201 enumerator
->destroy(enumerator
);
202 DBG1(DBG_DMN
, "loaded plugins: %s", buf
);
208 static void initialize_loggers(private_daemon_t
*this, bool use_stderr
,
211 sys_logger_t
*sys_logger
;
212 file_logger_t
*file_logger
;
213 enumerator_t
*enumerator
;
214 char *facility
, *filename
;
215 int loggers_defined
= 0;
218 bool append
, ike_name
;
221 /* setup sysloggers */
222 enumerator
= lib
->settings
->create_section_enumerator(lib
->settings
,
224 while (enumerator
->enumerate(enumerator
, &facility
))
228 ike_name
= lib
->settings
->get_bool(lib
->settings
,
229 "charon.syslog.%s.ike_name", FALSE
, facility
);
230 if (streq(facility
, "daemon"))
232 sys_logger
= sys_logger_create(LOG_DAEMON
, ike_name
);
234 else if (streq(facility
, "auth"))
236 sys_logger
= sys_logger_create(LOG_AUTHPRIV
, ike_name
);
242 def
= lib
->settings
->get_int(lib
->settings
,
243 "charon.syslog.%s.default", 1, facility
);
244 for (group
= 0; group
< DBG_MAX
; group
++)
246 sys_logger
->set_level(sys_logger
, group
,
247 lib
->settings
->get_int(lib
->settings
,
248 "charon.syslog.%s.%N", def
,
249 facility
, debug_lower_names
, group
));
251 this->public.sys_loggers
->insert_last(this->public.sys_loggers
,
253 this->public.bus
->add_listener(this->public.bus
, &sys_logger
->listener
);
255 enumerator
->destroy(enumerator
);
257 /* and file loggers */
258 enumerator
= lib
->settings
->create_section_enumerator(lib
->settings
,
260 while (enumerator
->enumerate(enumerator
, &filename
))
263 if (streq(filename
, "stderr"))
267 else if (streq(filename
, "stdout"))
273 append
= lib
->settings
->get_bool(lib
->settings
,
274 "charon.filelog.%s.append", TRUE
, filename
);
275 file
= fopen(filename
, append ?
"a" : "w");
278 DBG1(DBG_DMN
, "opening file %s for logging failed: %s",
279 filename
, strerror(errno
));
282 if (lib
->settings
->get_bool(lib
->settings
,
283 "charon.filelog.%s.flush_line", FALSE
, filename
))
288 file_logger
= file_logger_create(file
,
289 lib
->settings
->get_str(lib
->settings
,
290 "charon.filelog.%s.time_format", NULL
, filename
),
291 lib
->settings
->get_bool(lib
->settings
,
292 "charon.filelog.%s.ike_name", FALSE
, filename
));
293 def
= lib
->settings
->get_int(lib
->settings
,
294 "charon.filelog.%s.default", 1, filename
);
295 for (group
= 0; group
< DBG_MAX
; group
++)
297 file_logger
->set_level(file_logger
, group
,
298 lib
->settings
->get_int(lib
->settings
,
299 "charon.filelog.%s.%N", def
,
300 filename
, debug_lower_names
, group
));
302 this->public.file_loggers
->insert_last(this->public.file_loggers
,
304 this->public.bus
->add_listener(this->public.bus
, &file_logger
->listener
);
307 enumerator
->destroy(enumerator
);
309 /* set up legacy style default loggers provided via command-line */
310 if (!loggers_defined
)
312 /* set up default stdout file_logger */
313 file_logger
= file_logger_create(stdout
, NULL
, FALSE
);
314 this->public.bus
->add_listener(this->public.bus
, &file_logger
->listener
);
315 this->public.file_loggers
->insert_last(this->public.file_loggers
,
317 /* set up default daemon sys_logger */
318 sys_logger
= sys_logger_create(LOG_DAEMON
, FALSE
);
319 this->public.bus
->add_listener(this->public.bus
, &sys_logger
->listener
);
320 this->public.sys_loggers
->insert_last(this->public.sys_loggers
,
322 for (group
= 0; group
< DBG_MAX
; group
++)
324 sys_logger
->set_level(sys_logger
, group
, levels
[group
]);
327 file_logger
->set_level(file_logger
, group
, levels
[group
]);
331 /* set up default auth sys_logger */
332 sys_logger
= sys_logger_create(LOG_AUTHPRIV
, FALSE
);
333 this->public.bus
->add_listener(this->public.bus
, &sys_logger
->listener
);
334 this->public.sys_loggers
->insert_last(this->public.sys_loggers
,
336 sys_logger
->set_level(sys_logger
, DBG_ANY
, LEVEL_AUDIT
);
340 METHOD(daemon_t
, initialize
, bool,
341 private_daemon_t
*this, bool syslog
, level_t levels
[])
343 /* for uncritical pseudo random numbers */
344 srandom(time(NULL
) + getpid());
346 /* setup bus and it's listeners first to enable log output */
347 this->public.bus
= bus_create();
348 /* set up hook to log dbg message in library via charons message bus */
352 initialize_loggers(this, !syslog
, levels
);
354 DBG1(DBG_DMN
, "Starting IKEv2 charon daemon (strongSwan "VERSION
")");
358 DBG1(DBG_DMN
, "integrity tests enabled:");
359 DBG1(DBG_DMN
, "lib 'libstrongswan': passed file and segment integrity tests");
360 DBG1(DBG_DMN
, "lib 'libhydra': passed file and segment integrity tests");
361 DBG1(DBG_DMN
, "lib 'libcharon': passed file and segment integrity tests");
362 DBG1(DBG_DMN
, "daemon 'charon': passed file integrity test");
365 /* load secrets, ca certificates and crls */
366 this->public.controller
= controller_create();
367 this->public.eap
= eap_manager_create();
368 this->public.sim
= sim_manager_create();
369 this->public.tnccs
= tnccs_manager_create();
370 this->public.backends
= backend_manager_create();
371 this->public.socket
= socket_manager_create();
372 this->public.traps
= trap_manager_create();
373 this->kernel_handler
= kernel_handler_create();
375 /* load plugins, further infrastructure may need it */
376 if (!lib
->plugins
->load(lib
->plugins
, NULL
,
377 lib
->settings
->get_str(lib
->settings
, "charon.load", PLUGINS
)))
384 this->public.ike_sa_manager
= ike_sa_manager_create();
385 if (this->public.ike_sa_manager
== NULL
)
389 this->public.sender
= sender_create();
390 this->public.receiver
= receiver_create();
391 if (this->public.receiver
== NULL
)
397 this->public.connect_manager
= connect_manager_create();
398 if (this->public.connect_manager
== NULL
)
402 this->public.mediation_manager
= mediation_manager_create();
411 private_daemon_t
*daemon_create()
413 private_daemon_t
*this;
417 .keep_cap
= _keep_cap
,
418 .drop_capabilities
= _drop_capabilities
,
419 .initialize
= _initialize
,
421 .file_loggers
= linked_list_create(),
422 .sys_loggers
= linked_list_create(),
427 #ifdef CAPABILITIES_LIBCAP
428 this->caps
= cap_init();
429 #endif /* CAPABILITIES_LIBCAP */
430 keep_cap(this, CAP_NET_ADMIN
);
431 if (lib
->leak_detective
)
433 keep_cap(this, CAP_SYS_NICE
);
435 #endif /* CAPABILITIES */
441 * Described in header.
443 void libcharon_deinit()
446 destroy((private_daemon_t
*)charon
);
451 * Described in header.
453 bool libcharon_init()
455 private_daemon_t
*this;
457 this = daemon_create();
458 charon
= &this->public;
460 lib
->printf_hook
->add_handler(lib
->printf_hook
, 'P',
461 proposal_printf_hook
,
462 PRINTF_HOOK_ARGTYPE_POINTER
,
463 PRINTF_HOOK_ARGTYPE_END
);
465 if (lib
->integrity
&&
466 !lib
->integrity
->check(lib
->integrity
, "libcharon", libcharon_init
))
468 dbg(DBG_DMN
, 1, "integrity check of libcharon failed");