2
* Copyright (C) 2013 Martin Willi
3
* Copyright (C) 2013 revosec AG
5
* This program is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License as published by the
7
* Free Software Foundation; either version 2 of the License, or (at your
8
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10
* This program is distributed in the hope that it will be useful, but
11
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16
#include <sys/types.h>
17
#include <sys/utsname.h>
26
#include <threading/thread.h>
27
#include <utils/backtrace.h>
29
#include "xpc_dispatch.h"
32
* XPC dispatcher class
34
static xpc_dispatch_t *dispatcher;
37
* atexit() cleanup for dispatcher
39
void dispatcher_cleanup()
41
DESTROY_IF(dispatcher);
45
* Loglevel configuration
47
static level_t levels[DBG_MAX];
50
* hook in library for debugging messages
52
extern void (*dbg) (debug_t group, level_t level, char *fmt, ...);
55
* Logging hook for library logs, using stderr output
57
static void dbg_stderr(debug_t group, level_t level, char *fmt, ...)
64
fprintf(stderr, "00[%N] ", debug_names, group);
65
vfprintf(stderr, fmt, args);
66
fprintf(stderr, "\n");
72
* Run the daemon and handle unix signals
79
sigaddset(&set, SIGINT);
80
sigaddset(&set, SIGTERM);
81
sigprocmask(SIG_BLOCK, &set, NULL);
87
if (sigwait(&set, &sig))
89
DBG1(DBG_DMN, "error while waiting for a signal");
95
DBG1(DBG_DMN, "signal of type SIGINT received. Shutting down");
96
charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
99
DBG1(DBG_DMN, "signal of type SIGTERM received. Shutting down");
100
charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
103
DBG1(DBG_DMN, "unknown signal %d received. Ignored", sig);
110
* Handle SIGSEGV/SIGILL signals raised by threads
112
static void segv_handler(int signal)
114
backtrace_t *backtrace;
116
DBG1(DBG_DMN, "thread %u received %d", thread_current_id(), signal);
117
backtrace = backtrace_create(2);
118
backtrace->log(backtrace, NULL, TRUE);
119
backtrace->destroy(backtrace);
121
DBG1(DBG_DMN, "killing ourself, received critical signal");
126
* Main function, starts the daemon.
128
int main(int argc, char *argv[])
130
struct sigaction action;
131
struct utsname utsname;
135
atexit(library_deinit);
136
if (!library_init(NULL))
138
exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
142
if (!lib->integrity->check_file(lib->integrity, "charon-xpc", argv[0]))
144
exit(SS_RC_DAEMON_INTEGRITY);
147
atexit(libhydra_deinit);
148
if (!libhydra_init("charon-xpc"))
150
exit(SS_RC_INITIALIZATION_FAILED);
152
atexit(libcharon_deinit);
153
if (!libcharon_init("charon-xpc"))
155
exit(SS_RC_INITIALIZATION_FAILED);
157
for (group = 0; group < DBG_MAX; group++)
159
levels[group] = LEVEL_CTRL;
161
charon->load_loggers(charon, levels, TRUE);
163
lib->settings->set_default_str(lib->settings, "charon-xpc.port", "0");
164
lib->settings->set_default_str(lib->settings, "charon-xpc.port_nat_t", "0");
165
lib->settings->set_default_str(lib->settings,
166
"charon-xpc.close_ike_on_child_failure", "yes");
167
if (!charon->initialize(charon,
168
lib->settings->get_str(lib->settings, "charon-xpc.load",
169
"nonce pkcs1 openssl keychain ctr ccm gcm kernel-libipsec "
170
"kernel-pfroute socket-default eap-identity eap-mschapv2 "
171
"eap-md5 xauth-generic osx-attr")))
173
exit(SS_RC_INITIALIZATION_FAILED);
176
if (uname(&utsname) != 0)
178
memset(&utsname, 0, sizeof(utsname));
180
DBG1(DBG_DMN, "Starting charon-xpc IKE daemon (strongSwan %s, %s %s, %s)",
181
VERSION, utsname.sysname, utsname.release, utsname.machine);
183
/* add handler for SEGV and ILL,
184
* INT, TERM and HUP are handled by sigwait() in run() */
185
action.sa_handler = segv_handler;
187
sigemptyset(&action.sa_mask);
188
sigaddset(&action.sa_mask, SIGINT);
189
sigaddset(&action.sa_mask, SIGTERM);
190
sigaddset(&action.sa_mask, SIGHUP);
191
sigaction(SIGSEGV, &action, NULL);
192
sigaction(SIGILL, &action, NULL);
193
sigaction(SIGBUS, &action, NULL);
194
action.sa_handler = SIG_IGN;
195
sigaction(SIGPIPE, &action, NULL);
197
pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL);
199
dispatcher = xpc_dispatch_create();
202
exit(SS_RC_INITIALIZATION_FAILED);
204
atexit(dispatcher_cleanup);
206
charon->start(charon);