Annotation of embedaddon/strongswan/src/charon-nm/charon-nm.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2012 Tobias Brunner
3: * HSR Hochschule fuer Technik Rapperswil
4: *
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>.
9: *
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
13: * for more details.
14: */
15:
16: #include <stdio.h>
17: #include <syslog.h>
18: #include <signal.h>
19: #include <sys/types.h>
20: #include <unistd.h>
21: #include <errno.h>
22:
23: #include <daemon.h>
24:
25: #include <library.h>
26: #include <utils/backtrace.h>
27: #include <threading/thread.h>
28:
29: #include <nm/nm_backend.h>
30:
31: /**
32: * Default user and group
33: */
34: #ifndef IPSEC_USER
35: #define IPSEC_USER NULL
36: #endif
37:
38: #ifndef IPSEC_GROUP
39: #define IPSEC_GROUP NULL
40: #endif
41:
42: /**
43: * Hook in library for debugging messages
44: */
45: extern void (*dbg) (debug_t group, level_t level, char *fmt, ...);
46:
47: /**
48: * Simple logging hook for library logs, using syslog output
49: */
50: static void dbg_syslog(debug_t group, level_t level, char *fmt, ...)
51: {
52: if (level <= 1)
53: {
54: char buffer[8192], groupstr[4];
55: va_list args;
56:
57: va_start(args, fmt);
58: /* write in memory buffer first */
59: vsnprintf(buffer, sizeof(buffer), fmt, args);
60: /* cache group name */
61: snprintf(groupstr, sizeof(groupstr), "%N", debug_names, group);
62: syslog(LOG_DAEMON|LOG_INFO, "00[%s] %s", groupstr, buffer);
63: va_end(args);
64: }
65: }
66:
67: /**
68: * Run the daemon and handle unix signals
69: */
70: static void run()
71: {
72: sigset_t set;
73:
74: /* handle SIGINT and SIGTERM in this handler */
75: sigemptyset(&set);
76: sigaddset(&set, SIGINT);
77: sigaddset(&set, SIGTERM);
78: sigprocmask(SIG_BLOCK, &set, NULL);
79:
80: while (TRUE)
81: {
82: int sig;
83:
84: sig = sigwaitinfo(&set, NULL);
85: if (sig == -1)
86: {
87: if (errno == EINTR)
88: { /* ignore signals we didn't wait for */
89: continue;
90: }
91: DBG1(DBG_DMN, "waiting for signal failed: %s", strerror(errno));
92: return;
93: }
94: switch (sig)
95: {
96: case SIGINT:
97: {
98: DBG1(DBG_DMN, "signal of type SIGINT received. Shutting down");
99: charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
100: return;
101: }
102: case SIGTERM:
103: {
104: DBG1(DBG_DMN, "signal of type SIGTERM received. Shutting down");
105: charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
106: return;
107: }
108: }
109: }
110: }
111:
112: #ifndef DISABLE_SIGNAL_HANDLER
113: /**
114: * Handle SIGSEGV/SIGILL signals raised by threads
115: */
116: static void segv_handler(int signal)
117: {
118: backtrace_t *backtrace;
119:
120: DBG1(DBG_DMN, "thread %u received %d", thread_current_id(), signal);
121: backtrace = backtrace_create(2);
122: backtrace->log(backtrace, stderr, TRUE);
123: backtrace->destroy(backtrace);
124:
125: DBG1(DBG_DMN, "killing ourself, received critical signal");
126: abort();
127: }
128: #endif /* DISABLE_SIGNAL_HANDLER */
129:
130: /**
131: * Lookup UID and GID
132: */
133: static bool lookup_uid_gid()
134: {
135: char *name;
136:
137: name = lib->settings->get_str(lib->settings, "charon-nm.user",
138: IPSEC_USER);
139: if (name && !lib->caps->resolve_uid(lib->caps, name))
140: {
141: return FALSE;
142: }
143: name = lib->settings->get_str(lib->settings, "charon-nm.group",
144: IPSEC_GROUP);
145: if (name && !lib->caps->resolve_gid(lib->caps, name))
146: {
147: return FALSE;
148: }
149: return TRUE;
150: }
151:
152: /**
153: * Main function, starts NetworkManager backend.
154: */
155: int main(int argc, char *argv[])
156: {
157: struct sigaction action;
158: int status = SS_RC_INITIALIZATION_FAILED;
159:
160: /* logging for library during initialization, as we have no bus yet */
161: dbg = dbg_syslog;
162:
163: /* LD causes a crash probably due to Glib */
164: setenv("LEAK_DETECTIVE_DISABLE", "1", 1);
165:
166: /* initialize library */
167: if (!library_init(NULL, "charon-nm"))
168: {
169: library_deinit();
170: exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
171: }
172:
173: if (lib->integrity &&
174: !lib->integrity->check_file(lib->integrity, "charon-nm", argv[0]))
175: {
176: dbg_syslog(DBG_DMN, 1, "integrity check of charon-nm failed");
177: library_deinit();
178: exit(SS_RC_DAEMON_INTEGRITY);
179: }
180:
181: if (!libcharon_init())
182: {
183: dbg_syslog(DBG_DMN, 1, "initialization failed - aborting charon-nm");
184: goto deinit;
185: }
186:
187: if (!lookup_uid_gid())
188: {
189: dbg_syslog(DBG_DMN, 1, "invalid uid/gid - aborting charon-nm");
190: goto deinit;
191: }
192:
193: /* make sure we log to the DAEMON facility by default */
194: lib->settings->set_int(lib->settings, "charon-nm.syslog.daemon.default",
195: lib->settings->get_int(lib->settings,
196: "charon-nm.syslog.daemon.default", 1));
197: charon->load_loggers(charon);
198:
199: /* default to random ports to avoid conflicts with regular charon */
200: lib->settings->set_default_str(lib->settings, "charon-nm.port", "0");
201: lib->settings->set_default_str(lib->settings, "charon-nm.port_nat_t", "0");
202:
203: DBG1(DBG_DMN, "Starting charon NetworkManager backend (strongSwan "VERSION")");
204: if (lib->integrity)
205: {
206: DBG1(DBG_DMN, "integrity tests enabled:");
207: DBG1(DBG_DMN, "lib 'libstrongswan': passed file and segment integrity tests");
208: DBG1(DBG_DMN, "lib 'libcharon': passed file and segment integrity tests");
209: DBG1(DBG_DMN, "daemon 'charon-nm': passed file integrity test");
210: }
211:
212: /* register NM backend to be loaded with plugins */
213: nm_backend_register();
214:
215: /* initialize daemon */
216: if (!charon->initialize(charon,
217: lib->settings->get_str(lib->settings, "charon-nm.load", PLUGINS)))
218: {
219: DBG1(DBG_DMN, "initialization failed - aborting charon-nm");
220: goto deinit;
221: }
222: lib->plugins->status(lib->plugins, LEVEL_CTRL);
223:
224: if (!lib->caps->drop(lib->caps))
225: {
226: DBG1(DBG_DMN, "capability dropping failed - aborting charon-nm");
227: goto deinit;
228: }
229:
230: /* add handler for fatal signals,
231: * INT and TERM are handled by sigwaitinfo() in run() */
232: action.sa_flags = 0;
233: sigemptyset(&action.sa_mask);
234: sigaddset(&action.sa_mask, SIGINT);
235: sigaddset(&action.sa_mask, SIGTERM);
236:
237: /* optionally let the external system handle fatal signals */
238: #ifndef DISABLE_SIGNAL_HANDLER
239: action.sa_handler = segv_handler;
240: sigaction(SIGSEGV, &action, NULL);
241: sigaction(SIGILL, &action, NULL);
242: sigaction(SIGBUS, &action, NULL);
243: #endif /* DISABLE_SIGNAL_HANDLER */
244:
245: action.sa_handler = SIG_IGN;
246: sigaction(SIGPIPE, &action, NULL);
247:
248: pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL);
249:
250: /* start daemon (i.e. the threads in the thread-pool) */
251: charon->start(charon);
252:
253: /* main thread goes to run loop */
254: run();
255:
256: status = 0;
257:
258: deinit:
259: libcharon_deinit();
260: library_deinit();
261: return status;
262: }
263:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>