예제 #1
0
/**
 * Main function, starts the daemon.
 */
int main(int argc, char *argv[])
{
	struct sigaction action;
	struct utsname utsname;
	int group;

	/* handle simple arguments */
	handle_arguments(argc, argv, TRUE);

	dbg = dbg_stderr;
	atexit(library_deinit);
	if (!library_init(NULL, "charon-cmd"))
	{
		exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
	}
	if (lib->integrity)
	{
		if (!lib->integrity->check_file(lib->integrity, "charon-cmd", argv[0]))
		{
			exit(SS_RC_DAEMON_INTEGRITY);
		}
	}
	atexit(libhydra_deinit);
	if (!libhydra_init())
	{
		exit(SS_RC_INITIALIZATION_FAILED);
	}
	atexit(libcharon_deinit);
	if (!libcharon_init())
	{
		exit(SS_RC_INITIALIZATION_FAILED);
	}
	for (group = 0; group < DBG_MAX; group++)
	{
		levels[group] = default_loglevel;
	}
	charon->load_loggers(charon, levels, TRUE);

	if (!lookup_uid_gid())
	{
		exit(SS_RC_INITIALIZATION_FAILED);
	}
	lib->settings->set_default_str(lib->settings, "charon-cmd.port", "0");
	lib->settings->set_default_str(lib->settings, "charon-cmd.port_nat_t", "0");
	if (!charon->initialize(charon,
			lib->settings->get_str(lib->settings, "charon-cmd.load", PLUGINS)))
	{
		exit(SS_RC_INITIALIZATION_FAILED);
	}
	if (!lib->caps->drop(lib->caps))
	{
		exit(SS_RC_INITIALIZATION_FAILED);
	}

	conn = cmd_connection_create();
	atexit(cleanup_conn);
	creds = cmd_creds_create();
	atexit(cleanup_creds);

	/* handle all arguments */
	handle_arguments(argc, argv, FALSE);

	if (uname(&utsname) != 0)
	{
		memset(&utsname, 0, sizeof(utsname));
	}
	DBG1(DBG_DMN, "Starting charon-cmd IKE client (strongSwan %s, %s %s, %s)",
		 VERSION, utsname.sysname, utsname.release, utsname.machine);
	lib->plugins->status(lib->plugins, LEVEL_CTRL);

	/* add handler for SEGV and ILL,
	 * INT, TERM and HUP are handled by sigwait() in run() */
	action.sa_handler = segv_handler;
	action.sa_flags = 0;
	sigemptyset(&action.sa_mask);
	sigaddset(&action.sa_mask, SIGINT);
	sigaddset(&action.sa_mask, SIGTERM);
	sigaddset(&action.sa_mask, SIGHUP);
	sigaddset(&action.sa_mask, SIGUSR1);
	sigaction(SIGSEGV, &action, NULL);
	sigaction(SIGILL, &action, NULL);
	sigaction(SIGBUS, &action, NULL);
	action.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &action, NULL);

	pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL);

	/* start daemon with thread-pool */
	charon->start(charon);
	/* wait for signal */
	return run();
}
예제 #2
0
/**
 * Main function, starts TKM backend.
 */
int main(int argc, char *argv[])
{
	char *dmn_name;
	if (argc > 0 && strlen(argv[0]) > 0)
	{
		dmn_name = basename(argv[0]);
	}
	else
	{
		dmn_name = "charon-tkm";
	}

	/* TKM credential set */
	tkm_cred_t *creds;

	struct sigaction action;
	int status = SS_RC_INITIALIZATION_FAILED;

	/* logging for library during initialization, as we have no bus yet */
	dbg = dbg_syslog;

	/* initialize library */
	if (!library_init(NULL, dmn_name))
	{
		library_deinit();
		exit(status);
	}

	if (!libhydra_init())
	{
		dbg_syslog(DBG_DMN, 1, "initialization failed - aborting %s", dmn_name);
		libhydra_deinit();
		library_deinit();
		exit(status);
	}

	if (!libcharon_init())
	{
		dbg_syslog(DBG_DMN, 1, "initialization failed - aborting %s", dmn_name);
		goto deinit;
	}

	if (!lookup_uid_gid())
	{
		dbg_syslog(DBG_DMN, 1, "invalid uid/gid - aborting %s", dmn_name);
		goto deinit;
	}

	/* make sure we log to the DAEMON facility by default */
	lib->settings->set_int(lib->settings, "%s.syslog.daemon.default",
			lib->settings->get_int(lib->settings, "%s.syslog.daemon.default", 1,
								   dmn_name), dmn_name);
	charon->load_loggers(charon, NULL, FALSE);

	DBG1(DBG_DMN, "Starting charon with TKM backend (strongSwan "VERSION")");

	/* register TKM specific plugins */
	static plugin_feature_t features[] = {
		PLUGIN_REGISTER(NONCE_GEN, tkm_nonceg_create),
			PLUGIN_PROVIDE(NONCE_GEN),
		PLUGIN_REGISTER(PUBKEY, tkm_public_key_load, TRUE),
			PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
			PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1),
			PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA256),
		PLUGIN_CALLBACK(kernel_ipsec_register, tkm_kernel_ipsec_create),
			PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"),
	};
	lib->plugins->add_static_features(lib->plugins, "tkm-backend", features,
			countof(features), TRUE);

	if (!register_dh_mapping())
	{
		DBG1(DBG_DMN, "no DH group mapping defined - aborting %s", dmn_name);
		goto deinit;
	}

	/* register TKM keymat variant */
	keymat_register_constructor(IKEV2, (keymat_constructor_t)tkm_keymat_create);

	/* initialize daemon */
	if (!charon->initialize(charon, PLUGINS))
	{
		DBG1(DBG_DMN, "initialization failed - aborting %s", dmn_name);
		goto deinit;
	}
	lib->plugins->status(lib->plugins, LEVEL_CTRL);

	/* set global pidfile name depending on daemon name */
	if (asprintf(&pidfile_name, IPSEC_PIDDIR"/%s.pid", dmn_name) < 0)
	{
		DBG1(DBG_DMN, "unable to set pidfile name - aborting %s", dmn_name);
		goto deinit;
	};

	if (check_pidfile())
	{
		DBG1(DBG_DMN, "%s already running (\"%s\" exists)", dmn_name,
			 pidfile_name);
		goto deinit;
	}

	if (!lib->caps->drop(lib->caps))
	{
		DBG1(DBG_DMN, "capability dropping failed - aborting %s", dmn_name);
		goto deinit;
	}

	/* initialize TKM client */
	if (!tkm_init())
	{
		DBG1(DBG_DMN, "init of TKM client failed - aborting %s", dmn_name);
		goto deinit;
	}

	/* register TKM authorization hook */
	listener = tkm_listener_create();
	charon->bus->add_listener(charon->bus, &listener->listener);

	/* register TKM credential set */
	creds = tkm_cred_create();
	lib->credmgr->add_set(lib->credmgr, (credential_set_t*)creds);

	/* register TKM credential encoder */
	lib->encoding->add_encoder(lib->encoding, tkm_encoder_encode);

	/* add handler for SEGV and ILL,
	 * INT and TERM are handled by sigwait() in run() */
	action.sa_handler = segv_handler;
	action.sa_flags = 0;
	sigemptyset(&action.sa_mask);
	sigaddset(&action.sa_mask, SIGINT);
	sigaddset(&action.sa_mask, SIGTERM);
	sigaction(SIGSEGV, &action, NULL);
	sigaction(SIGILL, &action, NULL);
	sigaction(SIGBUS, &action, NULL);
	action.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &action, NULL);

	pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL);

	/* start daemon (i.e. the threads in the thread-pool) */
	charon->start(charon);

	/* main thread goes to run loop */
	run();

	unlink_pidfile();
	status = 0;
	charon->bus->remove_listener(charon->bus, &listener->listener);
	listener->destroy(listener);
	creds->destroy(creds);
	lib->encoding->remove_encoder(lib->encoding, tkm_encoder_encode);

deinit:
	destroy_dh_mapping();
	libcharon_deinit();
	libhydra_deinit();
	library_deinit();
	tkm_deinit();
	return status;
}
예제 #3
0
/**
 * Main function, starts the daemon.
 */
int main(int argc, char *argv[])
{
	struct sigaction action;
	int group, status = SS_RC_INITIALIZATION_FAILED;
	struct utsname utsname;

	/* logging for library during initialization, as we have no bus yet */
	dbg = dbg_stderr;

	/* initialize library */
	if (!library_init(NULL, "charon"))
	{
		library_deinit();
		exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
	}

	if (lib->integrity &&
		!lib->integrity->check_file(lib->integrity, "charon", argv[0]))
	{
		dbg_stderr(DBG_DMN, 1, "integrity check of charon failed");
		library_deinit();
		exit(SS_RC_DAEMON_INTEGRITY);
	}

	if (!libhydra_init())
	{
		dbg_stderr(DBG_DMN, 1, "initialization failed - aborting charon");
		libhydra_deinit();
		library_deinit();
		exit(SS_RC_INITIALIZATION_FAILED);
	}

	if (!libcharon_init())
	{
		dbg_stderr(DBG_DMN, 1, "initialization failed - aborting charon");
		goto deinit;
	}

	/* use CTRL loglevel for default */
	for (group = 0; group < DBG_MAX; group++)
	{
		levels[group] = LEVEL_CTRL;
	}

	/* handle arguments */
	for (;;)
	{
		struct option long_opts[] = {
			{ "help", no_argument, NULL, 'h' },
			{ "version", no_argument, NULL, 'v' },
			{ "use-syslog", no_argument, NULL, 'l' },
			/* TODO: handle "debug-all" */
			{ "debug-dmn", required_argument, &group, DBG_DMN },
			{ "debug-mgr", required_argument, &group, DBG_MGR },
			{ "debug-ike", required_argument, &group, DBG_IKE },
			{ "debug-chd", required_argument, &group, DBG_CHD },
			{ "debug-job", required_argument, &group, DBG_JOB },
			{ "debug-cfg", required_argument, &group, DBG_CFG },
			{ "debug-knl", required_argument, &group, DBG_KNL },
			{ "debug-net", required_argument, &group, DBG_NET },
			{ "debug-asn", required_argument, &group, DBG_ASN },
			{ "debug-enc", required_argument, &group, DBG_ENC },
			{ "debug-tnc", required_argument, &group, DBG_TNC },
			{ "debug-imc", required_argument, &group, DBG_IMC },
			{ "debug-imv", required_argument, &group, DBG_IMV },
			{ "debug-pts", required_argument, &group, DBG_PTS },
			{ "debug-tls", required_argument, &group, DBG_TLS },
			{ "debug-esp", required_argument, &group, DBG_ESP },
			{ "debug-lib", required_argument, &group, DBG_LIB },
			{ 0,0,0,0 }
		};

		int c = getopt_long(argc, argv, "", long_opts, NULL);
		switch (c)
		{
			case EOF:
				break;
			case 'h':
				usage(NULL);
				status = 0;
				goto deinit;
			case 'v':
				printf("Linux strongSwan %s\n", VERSION);
				status = 0;
				goto deinit;
			case 'l':
				use_syslog = TRUE;
				continue;
			case 0:
				/* option is in group */
				levels[group] = atoi(optarg);
				continue;
			default:
				usage("");
				status = 1;
				goto deinit;
		}
		break;
	}

	if (!lookup_uid_gid())
	{
		dbg_stderr(DBG_DMN, 1, "invalid uid/gid - aborting charon");
		goto deinit;
	}

	charon->load_loggers(charon, levels, !use_syslog);

	if (uname(&utsname) != 0)
	{
		memset(&utsname, 0, sizeof(utsname));
	}
	DBG1(DBG_DMN, "Starting IKE charon daemon (strongSwan "VERSION", %s %s, %s)",
		  utsname.sysname, utsname.release, utsname.machine);
	if (lib->integrity)
	{
		DBG1(DBG_DMN, "integrity tests enabled:");
		DBG1(DBG_DMN, "lib    'libstrongswan': passed file and segment integrity tests");
		DBG1(DBG_DMN, "lib    'libhydra': passed file and segment integrity tests");
		DBG1(DBG_DMN, "lib    'libcharon': passed file and segment integrity tests");
		DBG1(DBG_DMN, "daemon 'charon': passed file integrity test");
	}

	/* initialize daemon */
	if (!charon->initialize(charon,
				lib->settings->get_str(lib->settings, "charon.load", PLUGINS)))
	{
		DBG1(DBG_DMN, "initialization failed - aborting charon");
		goto deinit;
	}
	lib->plugins->status(lib->plugins, LEVEL_CTRL);

	if (check_pidfile())
	{
		DBG1(DBG_DMN, "charon already running (\""PID_FILE"\" exists)");
		goto deinit;
	}

	if (!lib->caps->drop(lib->caps))
	{
		DBG1(DBG_DMN, "capability dropping failed - aborting charon");
		goto deinit;
	}

	/* add handler for SEGV and ILL,
	 * INT, TERM and HUP are handled by sigwaitinfo() in run() */
	action.sa_handler = segv_handler;
	action.sa_flags = 0;
	sigemptyset(&action.sa_mask);
	sigaddset(&action.sa_mask, SIGINT);
	sigaddset(&action.sa_mask, SIGTERM);
	sigaddset(&action.sa_mask, SIGHUP);
	sigaction(SIGSEGV, &action, NULL);
	sigaction(SIGILL, &action, NULL);
	sigaction(SIGBUS, &action, NULL);
	action.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &action, NULL);

	pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL);

	/* start daemon (i.e. the threads in the thread-pool) */
	charon->start(charon);

	/* main thread goes to run loop */
	run();

	/* normal termination, cleanup and exit */
	unlink_pidfile();
	status = 0;

deinit:
	libcharon_deinit();
	libhydra_deinit();
	library_deinit();
	return status;
}
예제 #4
0
/**
 * Main function, starts NetworkManager backend.
 */
int main(int argc, char *argv[])
{
	struct sigaction action;
	int status = SS_RC_INITIALIZATION_FAILED;

	/* logging for library during initialization, as we have no bus yet */
	dbg = dbg_syslog;

	/* LD causes a crash probably due to Glib */
	setenv("LEAK_DETECTIVE_DISABLE", "1", 1);

	/* initialize library */
	if (!library_init(NULL, "charon-nm"))
	{
		library_deinit();
		exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
	}

	if (lib->integrity &&
		!lib->integrity->check_file(lib->integrity, "charon-nm", argv[0]))
	{
		dbg_syslog(DBG_DMN, 1, "integrity check of charon-nm failed");
		library_deinit();
		exit(SS_RC_DAEMON_INTEGRITY);
	}

	if (!libcharon_init())
	{
		dbg_syslog(DBG_DMN, 1, "initialization failed - aborting charon-nm");
		goto deinit;
	}

	if (!lookup_uid_gid())
	{
		dbg_syslog(DBG_DMN, 1, "invalid uid/gid - aborting charon-nm");
		goto deinit;
	}

	/* make sure we log to the DAEMON facility by default */
	lib->settings->set_int(lib->settings, "charon-nm.syslog.daemon.default",
		lib->settings->get_int(lib->settings,
							   "charon-nm.syslog.daemon.default", 1));
	charon->load_loggers(charon);

	/* use random ports to avoid conflicts with regular charon */
	lib->settings->set_int(lib->settings, "charon-nm.port", 0);
	lib->settings->set_int(lib->settings, "charon-nm.port_nat_t", 0);

	DBG1(DBG_DMN, "Starting charon NetworkManager backend (strongSwan "VERSION")");
	if (lib->integrity)
	{
		DBG1(DBG_DMN, "integrity tests enabled:");
		DBG1(DBG_DMN, "lib    'libstrongswan': passed file and segment integrity tests");
		DBG1(DBG_DMN, "lib    'libcharon': passed file and segment integrity tests");
		DBG1(DBG_DMN, "daemon 'charon-nm': passed file integrity test");
	}

	/* register NM backend to be loaded with plugins */
	nm_backend_register();

	/* initialize daemon */
	if (!charon->initialize(charon,
			lib->settings->get_str(lib->settings, "charon-nm.load", PLUGINS)))
	{
		DBG1(DBG_DMN, "initialization failed - aborting charon-nm");
		goto deinit;
	}
	lib->plugins->status(lib->plugins, LEVEL_CTRL);

	if (!lib->caps->drop(lib->caps))
	{
		DBG1(DBG_DMN, "capability dropping failed - aborting charon-nm");
		goto deinit;
	}

	/* add handler for SEGV and ILL,
	 * INT and TERM are handled by sigwaitinfo() in run() */
	action.sa_handler = segv_handler;
	action.sa_flags = 0;
	sigemptyset(&action.sa_mask);
	sigaddset(&action.sa_mask, SIGINT);
	sigaddset(&action.sa_mask, SIGTERM);
	sigaction(SIGSEGV, &action, NULL);
	sigaction(SIGILL, &action, NULL);
	sigaction(SIGBUS, &action, NULL);
	action.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &action, NULL);

	pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL);

	/* start daemon (i.e. the threads in the thread-pool) */
	charon->start(charon);

	/* main thread goes to run loop */
	run();

	status = 0;

deinit:
	libcharon_deinit();
	library_deinit();
	return status;
}