File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / charon-nm / charon-nm.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:20:08 2021 UTC (3 years, 6 months ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, HEAD
strongswan 5.9.2

    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: 			{
   99: 				DBG1(DBG_DMN, "%s received, shutting down",
  100: 					 sig == SIGINT ? "SIGINT" : "SIGTERM");
  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>