2 * Copyright (C) 2006-2012 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
23 #include <sys/types.h>
24 #include <sys/utsname.h>
27 #include <systemd/sd-daemon.h>
33 #include <utils/backtrace.h>
34 #include <threading/thread.h>
37 * hook in library for debugging messages
39 extern void (*dbg
) (debug_t group
, level_t level
, char *fmt
, ...);
42 * Logging hook for library logs, using stderr output
44 static void dbg_stderr(debug_t group
, level_t level
, char *fmt
, ...)
51 fprintf(stderr
, "00[%N] ", debug_names
, group
);
52 vfprintf(stderr
, fmt
, args
);
53 fprintf(stderr
, "\n");
59 * Run the daemon and handle unix signals
66 sigaddset(&set
, SIGTERM
);
67 sigprocmask(SIG_BLOCK
, &set
, NULL
);
69 sd_notify(0, "READY=1\n");
75 error
= sigwait(&set
, &sig
);
78 DBG1(DBG_DMN
, "waiting for signal failed: %s", strerror(error
));
79 return SS_RC_INITIALIZATION_FAILED
;
85 DBG1(DBG_DMN
, "SIGTERM received, shutting down");
86 charon
->bus
->alert(charon
->bus
, ALERT_SHUTDOWN_SIGNAL
, sig
);
91 DBG1(DBG_DMN
, "unknown signal %d received. Ignored", sig
);
101 static bool lookup_uid_gid()
104 if (!lib
->caps
->resolve_uid(lib
->caps
, IPSEC_USER
))
108 #endif /* IPSEC_USER */
110 if (!lib
->caps
->resolve_gid(lib
->caps
, IPSEC_GROUP
))
114 #endif /* IPSEC_GROUP */
119 * Handle SIGSEGV/SIGILL signals raised by threads
121 static void segv_handler(int signal
)
123 backtrace_t
*backtrace
;
125 DBG1(DBG_DMN
, "thread %u received %d", thread_current_id(), signal
);
126 backtrace
= backtrace_create(2);
127 backtrace
->log(backtrace
, NULL
, TRUE
);
128 backtrace
->log(backtrace
, stderr
, TRUE
);
129 backtrace
->destroy(backtrace
);
131 DBG1(DBG_DMN
, "killing ourself, received critical signal");
136 * Main function, starts the daemon.
138 int main(int argc
, char *argv
[])
140 struct sigaction action
;
141 struct utsname utsname
;
145 if (uname(&utsname
) != 0)
147 memset(&utsname
, 0, sizeof(utsname
));
150 sd_notifyf(0, "STATUS=Starting charon-systemd, strongSwan %s, %s %s, %s",
151 VERSION
, utsname
.sysname
, utsname
.release
, utsname
.machine
);
153 atexit(library_deinit
);
154 if (!library_init(NULL
, "charon-systemd"))
156 sd_notifyf(0, "STATUS=libstrongswan initialization failed");
157 return SS_RC_INITIALIZATION_FAILED
;
159 if (lib
->integrity
&&
160 !lib
->integrity
->check_file(lib
->integrity
, "charon-systemd", argv
[0]))
162 sd_notifyf(0, "STATUS=integrity check of charon-systemd failed");
163 return SS_RC_INITIALIZATION_FAILED
;
165 atexit(libhydra_deinit
);
166 if (!libhydra_init())
168 sd_notifyf(0, "STATUS=libhydra initialization failed");
169 return SS_RC_INITIALIZATION_FAILED
;
171 atexit(libcharon_deinit
);
172 if (!libcharon_init())
174 sd_notifyf(0, "STATUS=libcharon initialization failed");
175 return SS_RC_INITIALIZATION_FAILED
;
177 if (!lookup_uid_gid())
179 sd_notifyf(0, "STATUS=unkown uid/gid");
180 return SS_RC_INITIALIZATION_FAILED
;
182 charon
->load_loggers(charon
, NULL
, FALSE
);
184 if (!charon
->initialize(charon
, PLUGINS
))
186 sd_notifyf(0, "STATUS=charon initialization failed");
187 return SS_RC_INITIALIZATION_FAILED
;
189 lib
->plugins
->status(lib
->plugins
, LEVEL_CTRL
);
191 if (!lib
->caps
->drop(lib
->caps
))
193 sd_notifyf(0, "STATUS=dropping capabilities failed");
194 return SS_RC_INITIALIZATION_FAILED
;
197 /* add handler for SEGV and ILL,
198 * INT, TERM and HUP are handled by sigwait() in run() */
199 action
.sa_handler
= segv_handler
;
201 sigemptyset(&action
.sa_mask
);
202 sigaddset(&action
.sa_mask
, SIGINT
);
203 sigaddset(&action
.sa_mask
, SIGTERM
);
204 sigaddset(&action
.sa_mask
, SIGHUP
);
205 sigaction(SIGSEGV
, &action
, NULL
);
206 sigaction(SIGILL
, &action
, NULL
);
207 sigaction(SIGBUS
, &action
, NULL
);
208 action
.sa_handler
= SIG_IGN
;
209 sigaction(SIGPIPE
, &action
, NULL
);
211 pthread_sigmask(SIG_SETMASK
, &action
.sa_mask
, NULL
);
213 charon
->start(charon
);
215 sd_notifyf(0, "STATUS=charon-systemd running, strongSwan %s, %s %s, %s",
216 VERSION
, utsname
.sysname
, utsname
.release
, utsname
.machine
);