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
);
124 DESTROY_IF(this->public.connect_manager
);
125 DESTROY_IF(this->public.mediation_manager
);
127 DESTROY_IF(this->public.backends
);
128 DESTROY_IF(this->public.socket
);
130 /* rehook library logging, shutdown logging */
132 DESTROY_IF(this->public.bus
);
133 this->public.file_loggers
->destroy_offset(this->public.file_loggers
,
134 offsetof(file_logger_t
, destroy
));
135 this->public.sys_loggers
->destroy_offset(this->public.sys_loggers
,
136 offsetof(sys_logger_t
, destroy
));
140 METHOD(daemon_t
, keep_cap
, void,
141 private_daemon_t
*this, u_int cap
)
143 #ifdef CAPABILITIES_LIBCAP
144 cap_set_flag(this->caps
, CAP_EFFECTIVE
, 1, &cap
, CAP_SET
);
145 cap_set_flag(this->caps
, CAP_INHERITABLE
, 1, &cap
, CAP_SET
);
146 cap_set_flag(this->caps
, CAP_PERMITTED
, 1, &cap
, CAP_SET
);
147 #endif /* CAPABILITIES_LIBCAP */
148 #ifdef CAPABILITIES_NATIVE
149 this->caps
.effective
|= 1 << cap
;
150 this->caps
.permitted
|= 1 << cap
;
151 this->caps
.inheritable
|= 1 << cap
;
152 #endif /* CAPABILITIES_NATIVE */
155 METHOD(daemon_t
, drop_capabilities
, bool,
156 private_daemon_t
*this)
158 #ifdef CAPABILITIES_LIBCAP
159 if (cap_set_proc(this->caps
) != 0)
163 #endif /* CAPABILITIES_LIBCAP */
164 #ifdef CAPABILITIES_NATIVE
165 struct __user_cap_header_struct header
= {
166 .version
= _LINUX_CAPABILITY_VERSION
,
168 if (capset(&header
, &this->caps
) != 0)
172 #endif /* CAPABILITIES_NATIVE */
176 METHOD(daemon_t
, start
, void,
177 private_daemon_t
*this)
179 /* start the engine, go multithreaded */
180 lib
->processor
->set_threads(lib
->processor
,
181 lib
->settings
->get_int(lib
->settings
, "charon.threads",
188 static void print_plugins()
190 char buf
[512], *plugin
;
192 enumerator_t
*enumerator
;
195 enumerator
= lib
->plugins
->create_plugin_enumerator(lib
->plugins
);
196 while (len
< sizeof(buf
) && enumerator
->enumerate(enumerator
, &plugin
))
198 len
+= snprintf(&buf
[len
], sizeof(buf
)-len
, "%s ", plugin
);
200 enumerator
->destroy(enumerator
);
201 DBG1(DBG_DMN
, "loaded plugins: %s", buf
);
207 static void initialize_loggers(private_daemon_t
*this, bool use_stderr
,
210 sys_logger_t
*sys_logger
;
211 file_logger_t
*file_logger
;
212 enumerator_t
*enumerator
;
213 char *facility
, *filename
;
214 int loggers_defined
= 0;
217 bool append
, ike_name
;
220 /* setup sysloggers */
221 enumerator
= lib
->settings
->create_section_enumerator(lib
->settings
,
223 while (enumerator
->enumerate(enumerator
, &facility
))
227 ike_name
= lib
->settings
->get_bool(lib
->settings
,
228 "charon.syslog.%s.ike_name", FALSE
, facility
);
229 if (streq(facility
, "daemon"))
231 sys_logger
= sys_logger_create(LOG_DAEMON
, ike_name
);
233 else if (streq(facility
, "auth"))
235 sys_logger
= sys_logger_create(LOG_AUTHPRIV
, ike_name
);
241 def
= lib
->settings
->get_int(lib
->settings
,
242 "charon.syslog.%s.default", 1, facility
);
243 for (group
= 0; group
< DBG_MAX
; group
++)
245 sys_logger
->set_level(sys_logger
, group
,
246 lib
->settings
->get_int(lib
->settings
,
247 "charon.syslog.%s.%N", def
,
248 facility
, debug_lower_names
, group
));
250 this->public.sys_loggers
->insert_last(this->public.sys_loggers
,
252 this->public.bus
->add_listener(this->public.bus
, &sys_logger
->listener
);
254 enumerator
->destroy(enumerator
);
256 /* and file loggers */
257 enumerator
= lib
->settings
->create_section_enumerator(lib
->settings
,
259 while (enumerator
->enumerate(enumerator
, &filename
))
262 if (streq(filename
, "stderr"))
266 else if (streq(filename
, "stdout"))
272 append
= lib
->settings
->get_bool(lib
->settings
,
273 "charon.filelog.%s.append", TRUE
, filename
);
274 file
= fopen(filename
, append ?
"a" : "w");
277 DBG1(DBG_DMN
, "opening file %s for logging failed: %s",
278 filename
, strerror(errno
));
281 if (lib
->settings
->get_bool(lib
->settings
,
282 "charon.filelog.%s.flush_line", FALSE
, filename
))
287 file_logger
= file_logger_create(file
,
288 lib
->settings
->get_str(lib
->settings
,
289 "charon.filelog.%s.time_format", NULL
, filename
),
290 lib
->settings
->get_bool(lib
->settings
,
291 "charon.filelog.%s.ike_name", FALSE
, filename
));
292 def
= lib
->settings
->get_int(lib
->settings
,
293 "charon.filelog.%s.default", 1, filename
);
294 for (group
= 0; group
< DBG_MAX
; group
++)
296 file_logger
->set_level(file_logger
, group
,
297 lib
->settings
->get_int(lib
->settings
,
298 "charon.filelog.%s.%N", def
,
299 filename
, debug_lower_names
, group
));
301 this->public.file_loggers
->insert_last(this->public.file_loggers
,
303 this->public.bus
->add_listener(this->public.bus
, &file_logger
->listener
);
306 enumerator
->destroy(enumerator
);
308 /* set up legacy style default loggers provided via command-line */
309 if (!loggers_defined
)
311 /* set up default stdout file_logger */
312 file_logger
= file_logger_create(stdout
, NULL
, FALSE
);
313 this->public.bus
->add_listener(this->public.bus
, &file_logger
->listener
);
314 this->public.file_loggers
->insert_last(this->public.file_loggers
,
316 /* set up default daemon sys_logger */
317 sys_logger
= sys_logger_create(LOG_DAEMON
, FALSE
);
318 this->public.bus
->add_listener(this->public.bus
, &sys_logger
->listener
);
319 this->public.sys_loggers
->insert_last(this->public.sys_loggers
,
321 for (group
= 0; group
< DBG_MAX
; group
++)
323 sys_logger
->set_level(sys_logger
, group
, levels
[group
]);
326 file_logger
->set_level(file_logger
, group
, levels
[group
]);
330 /* set up default auth sys_logger */
331 sys_logger
= sys_logger_create(LOG_AUTHPRIV
, FALSE
);
332 this->public.bus
->add_listener(this->public.bus
, &sys_logger
->listener
);
333 this->public.sys_loggers
->insert_last(this->public.sys_loggers
,
335 sys_logger
->set_level(sys_logger
, DBG_ANY
, LEVEL_AUDIT
);
339 METHOD(daemon_t
, initialize
, bool,
340 private_daemon_t
*this, bool syslog
, level_t levels
[])
342 /* for uncritical pseudo random numbers */
343 srandom(time(NULL
) + getpid());
345 /* setup bus and it's listeners first to enable log output */
346 this->public.bus
= bus_create();
347 /* set up hook to log dbg message in library via charons message bus */
351 initialize_loggers(this, !syslog
, levels
);
353 DBG1(DBG_DMN
, "Starting IKEv2 charon daemon (strongSwan "VERSION
")");
357 DBG1(DBG_DMN
, "integrity tests enabled:");
358 DBG1(DBG_DMN
, "lib 'libstrongswan': passed file and segment integrity tests");
359 DBG1(DBG_DMN
, "lib 'libhydra': passed file and segment integrity tests");
360 DBG1(DBG_DMN
, "lib 'libcharon': passed file and segment integrity tests");
361 DBG1(DBG_DMN
, "daemon 'charon': passed file integrity test");
364 /* load secrets, ca certificates and crls */
365 this->public.controller
= controller_create();
366 this->public.eap
= eap_manager_create();
367 this->public.sim
= sim_manager_create();
368 this->public.backends
= backend_manager_create();
369 this->public.socket
= socket_manager_create();
370 this->public.traps
= trap_manager_create();
371 this->kernel_handler
= kernel_handler_create();
373 /* load plugins, further infrastructure may need it */
374 if (!lib
->plugins
->load(lib
->plugins
, NULL
,
375 lib
->settings
->get_str(lib
->settings
, "charon.load", PLUGINS
)))
382 this->public.ike_sa_manager
= ike_sa_manager_create();
383 if (this->public.ike_sa_manager
== NULL
)
387 this->public.sender
= sender_create();
388 this->public.receiver
= receiver_create();
389 if (this->public.receiver
== NULL
)
395 this->public.connect_manager
= connect_manager_create();
396 if (this->public.connect_manager
== NULL
)
400 this->public.mediation_manager
= mediation_manager_create();
409 private_daemon_t
*daemon_create()
411 private_daemon_t
*this;
415 .keep_cap
= _keep_cap
,
416 .drop_capabilities
= _drop_capabilities
,
417 .initialize
= _initialize
,
419 .file_loggers
= linked_list_create(),
420 .sys_loggers
= linked_list_create(),
425 #ifdef CAPABILITIES_LIBCAP
426 this->caps
= cap_init();
427 #endif /* CAPABILITIES_LIBCAP */
428 keep_cap(this, CAP_NET_ADMIN
);
429 if (lib
->leak_detective
)
431 keep_cap(this, CAP_SYS_NICE
);
433 #endif /* CAPABILITIES */
439 * Described in header.
441 void libcharon_deinit()
444 destroy((private_daemon_t
*)charon
);
449 * Described in header.
451 bool libcharon_init()
453 private_daemon_t
*this;
455 this = daemon_create();
456 charon
= &this->public;
458 lib
->printf_hook
->add_handler(lib
->printf_hook
, 'P',
459 proposal_printf_hook
,
460 PRINTF_HOOK_ARGTYPE_POINTER
,
461 PRINTF_HOOK_ARGTYPE_END
);
463 if (lib
->integrity
&&
464 !lib
->integrity
->check(lib
->integrity
, "libcharon", libcharon_init
))
466 dbg(DBG_DMN
, 1, "integrity check of libcharon failed");