Annotation of embedaddon/strongswan/src/charon-nm/charon-nm.c, revision 1.1.1.2
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: case SIGTERM:
98: {
1.1.1.2 ! misho 99: DBG1(DBG_DMN, "%s received, shutting down",
! 100: sig == SIGINT ? "SIGINT" : "SIGTERM");
1.1 misho 101: charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
102: return;
103: }
104: }
105: }
106: }
107:
108: #ifndef DISABLE_SIGNAL_HANDLER
109: /**
110: * Handle SIGSEGV/SIGILL signals raised by threads
111: */
112: static void segv_handler(int signal)
113: {
114: backtrace_t *backtrace;
115:
116: DBG1(DBG_DMN, "thread %u received %d", thread_current_id(), signal);
117: backtrace = backtrace_create(2);
118: backtrace->log(backtrace, stderr, TRUE);
119: backtrace->destroy(backtrace);
120:
121: DBG1(DBG_DMN, "killing ourself, received critical signal");
122: abort();
123: }
124: #endif /* DISABLE_SIGNAL_HANDLER */
125:
126: /**
127: * Lookup UID and GID
128: */
129: static bool lookup_uid_gid()
130: {
131: char *name;
132:
133: name = lib->settings->get_str(lib->settings, "charon-nm.user",
134: IPSEC_USER);
135: if (name && !lib->caps->resolve_uid(lib->caps, name))
136: {
137: return FALSE;
138: }
139: name = lib->settings->get_str(lib->settings, "charon-nm.group",
140: IPSEC_GROUP);
141: if (name && !lib->caps->resolve_gid(lib->caps, name))
142: {
143: return FALSE;
144: }
145: return TRUE;
146: }
147:
148: /**
149: * Main function, starts NetworkManager backend.
150: */
151: int main(int argc, char *argv[])
152: {
153: struct sigaction action;
154: int status = SS_RC_INITIALIZATION_FAILED;
155:
156: /* logging for library during initialization, as we have no bus yet */
157: dbg = dbg_syslog;
158:
159: /* LD causes a crash probably due to Glib */
160: setenv("LEAK_DETECTIVE_DISABLE", "1", 1);
161:
162: /* initialize library */
163: if (!library_init(NULL, "charon-nm"))
164: {
165: library_deinit();
166: exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
167: }
168:
169: if (lib->integrity &&
170: !lib->integrity->check_file(lib->integrity, "charon-nm", argv[0]))
171: {
172: dbg_syslog(DBG_DMN, 1, "integrity check of charon-nm failed");
173: library_deinit();
174: exit(SS_RC_DAEMON_INTEGRITY);
175: }
176:
177: if (!libcharon_init())
178: {
179: dbg_syslog(DBG_DMN, 1, "initialization failed - aborting charon-nm");
180: goto deinit;
181: }
182:
183: if (!lookup_uid_gid())
184: {
185: dbg_syslog(DBG_DMN, 1, "invalid uid/gid - aborting charon-nm");
186: goto deinit;
187: }
188:
189: /* make sure we log to the DAEMON facility by default */
190: lib->settings->set_int(lib->settings, "charon-nm.syslog.daemon.default",
191: lib->settings->get_int(lib->settings,
192: "charon-nm.syslog.daemon.default", 1));
193: charon->load_loggers(charon);
194:
195: /* default to random ports to avoid conflicts with regular charon */
196: lib->settings->set_default_str(lib->settings, "charon-nm.port", "0");
197: lib->settings->set_default_str(lib->settings, "charon-nm.port_nat_t", "0");
198:
199: DBG1(DBG_DMN, "Starting charon NetworkManager backend (strongSwan "VERSION")");
200: if (lib->integrity)
201: {
202: DBG1(DBG_DMN, "integrity tests enabled:");
203: DBG1(DBG_DMN, "lib 'libstrongswan': passed file and segment integrity tests");
204: DBG1(DBG_DMN, "lib 'libcharon': passed file and segment integrity tests");
205: DBG1(DBG_DMN, "daemon 'charon-nm': passed file integrity test");
206: }
207:
208: /* register NM backend to be loaded with plugins */
209: nm_backend_register();
210:
211: /* initialize daemon */
212: if (!charon->initialize(charon,
213: lib->settings->get_str(lib->settings, "charon-nm.load", PLUGINS)))
214: {
215: DBG1(DBG_DMN, "initialization failed - aborting charon-nm");
216: goto deinit;
217: }
218: lib->plugins->status(lib->plugins, LEVEL_CTRL);
219:
220: if (!lib->caps->drop(lib->caps))
221: {
222: DBG1(DBG_DMN, "capability dropping failed - aborting charon-nm");
223: goto deinit;
224: }
225:
226: /* add handler for fatal signals,
227: * INT and TERM are handled by sigwaitinfo() in run() */
228: action.sa_flags = 0;
229: sigemptyset(&action.sa_mask);
230: sigaddset(&action.sa_mask, SIGINT);
231: sigaddset(&action.sa_mask, SIGTERM);
232:
233: /* optionally let the external system handle fatal signals */
234: #ifndef DISABLE_SIGNAL_HANDLER
235: action.sa_handler = segv_handler;
236: sigaction(SIGSEGV, &action, NULL);
237: sigaction(SIGILL, &action, NULL);
238: sigaction(SIGBUS, &action, NULL);
239: #endif /* DISABLE_SIGNAL_HANDLER */
240:
241: action.sa_handler = SIG_IGN;
242: sigaction(SIGPIPE, &action, NULL);
243:
244: pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL);
245:
246: /* start daemon (i.e. the threads in the thread-pool) */
247: charon->start(charon);
248:
249: /* main thread goes to run loop */
250: run();
251:
252: status = 0;
253:
254: deinit:
255: libcharon_deinit();
256: library_deinit();
257: return status;
258: }
259:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>