Example #1
0
File: a2c.c Project: sacado/arc2c
int main (int argc, char * argv[]) {
  gc_init();
  init_constants();
  init_symeval();
  execute(0);
  return 0;
}
Example #2
0
File: _speedups.c Project: 10sr/hue
PyMODINIT_FUNC
PyInit__speedups(void)
{
	if (!init_constants())
		return NULL;

	return PyModule_Create(&module_definition);
}
Example #3
0
File: _speedups.c Project: 10sr/hue
PyMODINIT_FUNC
init_speedups(void)
{
	if (!init_constants())
		return;

	Py_InitModule3("markupsafe._speedups", module_methods, "");
}
Example #4
0
int scheme_init(Scheme *sc) {
	init_constants();

	operators = my_g_hash_table_new(my_g_str_hash, my_g_str_equal);
	init_core_operators(operators);
	//init_system_operators(operators);
	//init_command_operators(operators);

	sc->lastCellSeg = -1;
	sc->freeCell = &g_nil;
	sc->freeCellCount = 0;
	alloc_cellseg(sc, 3);

	//sc->outPort = port_from_file(sc, stdout, PORT_OUTPUT);
	//sc->inPort = port_from_file(sc, stdin, PORT_INPUT);

	sc->code = &g_nil;
	sc->callStack = &g_nil;

	sc->objectList = oblist_initial_value(sc);
	/* init global_env */
	new_frame_in_env(sc, &g_nil);
	sc->globalEnv = sc->env;

	add_syntax_symbol(sc, "lambda");
	add_syntax_symbol(sc, "quote");
	add_syntax_symbol(sc, "define");
	add_syntax_symbol(sc, "if");
	add_syntax_symbol(sc, "begin");
	add_syntax_symbol(sc, "set!");
	add_syntax_symbol(sc, "let");
	add_syntax_symbol(sc, "let*");
	add_syntax_symbol(sc, "letrec");
	add_syntax_symbol(sc, "cond");
	add_syntax_symbol(sc, "delay");
	add_syntax_symbol(sc, "and");
	add_syntax_symbol(sc, "or");
	add_syntax_symbol(sc, "cons-stream");
	add_syntax_symbol(sc, "macro");
	add_syntax_symbol(sc, "case");

	/* initialization of global cell*s to special symbols */
	sc->sym_lambda = make_symbol(sc, "lambda");
	sc->sym_quote = make_symbol(sc, "quote");
	sc->sym_feed_to = make_symbol(sc, "=>");
	sc->sym_colon_hook = make_symbol(sc, "*colon-hook*");
	sc->sym_error_hook = make_symbol(sc, "*error-hook*");
	sc->sym_sharp_hook = make_symbol(sc, "*sharp-hook*");
	sc->sym_compile_hook = make_symbol(sc, "*compile-hook*");

	my_g_hash_table_foreach(operators, (MyGHFunc)iterator, sc);

	init_math_constants(sc);
	// init_system_constants(sc);

	return TRUE;
}
Example #5
0
install_t
install_order()
{ init_constants();

  PL_register_foreign("new_order_table",	2, pl_new_order_table, 0);
  PL_register_foreign("order_table_mapping",	3, pl_order_table_mapping,
		      PL_FA_NONDETERMINISTIC);
  PL_register_foreign("compare_strings",	4, pl_compare_strings, 0);
  PL_register_foreign("prefix_string",		3, pl_prefix_string, 0);
  PL_register_foreign("prefix_string",		4, pl_prefix_string4, 0);
  PL_register_foreign("sub_string",		3, pl_sub_string, 0);
}
Example #6
0
SeqToolBarView::SeqToolBarView(	BPoint at, const char* name,
								AmToolBarRef toolBarRef, float space)
		: inherited(BRect(at, at), name,
					B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW),
		  BToolTipable(*(BView*)this),
		  mMouseDownTool(NULL), mOverToolIndex(-1), mSpace(space), mPrefW(0), mPrefH(0)
{
	init_constants();
	mDraggingRect = invalid_rect();

	SetToolBar(toolBarRef);
}
Example #7
0
int motor_pwm_init(void)
{
	const int ret = init_constants(config_get("mot_pwm_hz"));
	if (ret) {
		return ret;
	}

	init_timers();
	start_timers();

	motor_pwm_set_freewheeling();
	return 0;
}
Example #8
0
install_t
install_plaincase()
{ init_constants();

  setlocale(LC_COLLATE, "en_GB.UTF-8");

  PL_register_foreign("is_plaincase", 1, is_plaincase1, 0);
  PL_register_foreign("is_diacritics", 1, is_diacritics1, 0);

  PL_register_foreign("plaincase_atom", 2, plaincase_atom2, 0);

  PL_register_foreign("no_diacritics_atom", 2, pl_no_diacritics_atom, 0);
}
Example #9
0
void
init(Handle<Object> ex) {
    ObjectHandle exports(ex);

    Connection::Initialize(exports);
    Watch::Initialize(exports);
    Timeout::Initialize(exports);
    Message::Initialize(exports);
    MessageIter::Initialize(exports);
    PendingCall::Initialize(exports);
    Server::Initialize(exports);

    defineFunction(exports, "createMethodCall", Message::CreateMethodCall);
    defineFunction(exports, "createMethodReturn", Message::CreateMethodReturn);
    defineFunction(exports, "createErrorMessage", Message::CreateErrorMessage);
    defineFunction(exports, "createSignal", Message::CreateSignal);

    defineFunction(exports, "introspectionXmlToJs", introspectionXmlToJs);
    
    init_constants(exports);
}
Example #10
0
int main(int argc, char **argv)
{
#if 0
	NSS_NoDB_Init(".");
	if (!test_aes_cbc(&algo_aes_cbc)) {
		printf("aes-cbc failed\n");
	}
	if (!test_camellia_cbc(&algo_camellia_cbc)) {
		printf("camellia-cbc failed\n");
	}
	if (!test_aes_ctr(&algo_aes_ctr)) {
		printf("aes-ctr failed\n");
	}
	exit(0);
#endif

	int lockfd;

	/*
	 * We read the intentions for how to log from command line options
	 * and the config file. Then we prepare to be able to log, but until
	 * then log to stderr (better then nothing). Once we are ready to
	 * actually do loggin according to the methods desired, we set the
	 * variables for those methods
	 */
	bool log_to_stderr_desired = FALSE;
	bool log_to_file_desired = FALSE;

	{
		int i;

		/* MUST BE BEFORE ANY allocs */
		for (i = 1; i < argc; ++i) {
			if (streq(argv[i], "--leak-detective"))
				leak_detective = TRUE;
		}
	}

	pluto_name = argv[0];

	coredir = clone_str("/var/run/pluto", "coredir in main()");
	pluto_vendorid = clone_str(ipsec_version_vendorid(), "vendorid in main()");

	unsigned int keep_alive = 0;

	/* Overridden by virtual_private= in ipsec.conf */
	char *virtual_private = NULL;

	libreswan_passert_fail = passert_fail;

	/* handle arguments */
	for (;; ) {
		/*
		 * Note: we don't like the way short options get parsed
		 * by getopt_long, so we simply pass an empty string as
		 * the list.  It could be "hvdenp:l:s:" "NARXPECK".
		 */
		int longindex = -1;
		int c = getopt_long(argc, argv, "", long_opts, &longindex);
		const char *optname = NULL;
		err_t ugh = NULL;	/* complaint from case */
		unsigned long u = 0;	/* scratch for case */

		if (longindex != -1) {
			const char *optmeta;
			optname = long_opts[longindex].name;

			optmeta = optname + strlen(optname) + 1;	/* after '\0' */
			switch (optmeta[0]) {
			case '_':
				libreswan_log("warning: option \"--%s\" with '_' in its name is obsolete; use '-'",
					optname);
				break;
			case '>':
				libreswan_log("warning: option \"--%s\" is obsolete; use \"--%s\"",
					optname, optmeta + 1);
				break;
			case '!':
				libreswan_log("warning: option \"--%s\" is obsolete; ignored",
					optname);
				continue;	/* ignore it! */
			}
		}

		/* Note: "breaking" from case terminates loop */
		switch (c) {
		case EOF:	/* end of flags */
			break;

		case 0:
			/*
			 * Long option already handled by getopt_long.
			 * Not currently used since we always set flag to NULL.
			 */
			continue;

		case ':':	/* diagnostic already printed by getopt_long */
		case '?':	/* diagnostic already printed by getopt_long */
			invocation_fail(NULL);
			break;

		case 'h':	/* --help */
			usage();
			break;	/* not actually reached */

		case 'X':	/* --leak-detective */
			/*
			 * This flag was already processed at the start of main()
			 * because leak_detective must be immutable from before
			 * the first alloc().
			 * If this option is specified, we must have already
			 * set it at the start of main(), so assert it.
			 */
			passert(leak_detective);
			continue;

		case 'C':	/* --coredir */
			pfree(coredir);
			coredir = clone_str(optarg, "coredir via getopt");
			continue;

		case 'V':	/* --vendorid */
			pfree(pluto_vendorid);
			coredir = clone_str(optarg, "pluto_vendorid via getopt");
			continue;

		case 'S':	/* --statsdir */
			pfreeany(pluto_stats_binary);
			pluto_stats_binary = clone_str(optarg, "statsbin");
			continue;

		case 'v':	/* --version */
			printf("%s%s\n", ipsec_version_string(),
				compile_time_interop_options);
			/* not exit_pluto because we are not initialized yet */
			exit(0);
			break;	/* not actually reached */

		case 'j':	/* --nhelpers */
			if (streq(optarg, "-1")) {
				nhelpers = -1;
			} else {
				ugh = ttoulb(optarg, 0, 10, 1000, &u);
				if (ugh != NULL)
					break;

				nhelpers = u;
			}
			continue;
		case 'c':	/* --seedbits */
			pluto_nss_seedbits = atoi(optarg);
			if (pluto_nss_seedbits == 0) {
				printf("pluto: seedbits must be an integer > 0");
				/* not exit_pluto because we are not initialized yet */
				exit(PLUTO_EXIT_NSS_FAIL);
			}
			continue;

#ifdef HAVE_LABELED_IPSEC
		case 'w':	/* --secctx-attr-type */
			ugh = ttoulb(optarg, 0, 0, 0xFFFF, &u);
			if (ugh != NULL)
				break;
			if (u != SECCTX && u != ECN_TUNNEL_or_old_SECCTX) {
				ugh = "must be a positive 32001 (default) or 10 (for backward compatibility)";
				break;
			}
			secctx_attr_type = u;
			continue;
#endif

		case 'd':	/* --nofork*/
			fork_desired = FALSE;
			continue;

		case 'e':	/* --stderrlog */
			log_to_stderr_desired = TRUE;
			continue;

		case 'g':	/* --logfile */
			pluto_log_file = optarg;
			log_to_file_desired = TRUE;
			continue;

		case 't':	/* --log-no-time */
			log_with_timestamp = FALSE;
			continue;

		case '7':	/* --log-no-append */
			log_append = FALSE;
			continue;

		case '8':	/* --drop-oppo-null */
			pluto_drop_oppo_null = TRUE;
			continue;

		case '9':	/* --expire-bare-shunt <interval> */
			ugh = ttoulb(optarg, 0, 10, 1000, &u);
			if (ugh != NULL)
				break;
			bare_shunt_interval = u;
			continue;

		case 'k':	/* --use-klips */
			kern_interface = USE_KLIPS;
			continue;

		case 'L':	/* --listen ip_addr */
		{
			ip_address lip;
			err_t e = ttoaddr(optarg, 0, AF_UNSPEC, &lip);

			if (e != NULL) {
				/*
				 *??? should we continue on failure?
				 * If not, use ugh mechanism.
				 */
				libreswan_log(
					"invalid listen argument ignored: %s\n",
					e);
			} else {
				pluto_listen =
					clone_str(optarg, "pluto_listen");
				libreswan_log(
					"bind() will be filtered for %s\n",
					pluto_listen);
			}
		}
			continue;

		case 'M':	/* --use-mast */
			kern_interface = USE_MASTKLIPS;
			continue;

		case 'F':	/* --use-bsdkame */
			kern_interface = USE_BSDKAME;
			continue;

		case 'K':	/* --use-netkey */
			kern_interface = USE_NETKEY;
			continue;

		case 'n':	/* --use-nostack */
			kern_interface = NO_KERNEL;
			continue;

		case 'D':	/* --force-busy */
			pluto_ddos_mode = DDOS_FORCE_BUSY;
			continue;
		case 'U':	/* --force-unlimited */
			pluto_ddos_mode = DDOS_FORCE_UNLIMITED;
			continue;

		case 'Z':	/* --curl-iface */
			curl_iface = optarg;
			continue;

		case 'I':	/* --curl-timeout */
			ugh = ttoulb(optarg, 0, 10, 0xFFFF, &u);
			if (ugh != NULL)
				break;
			if (u <= 0) {
				ugh = "must not be < 1";
				break;
			}
			curl_timeout = u;
			continue;

		case 'r':	/* --strictcrlpolicy */
			strict_crl_policy = TRUE;
			continue;

		case 'o':
			strict_ocsp_policy = TRUE;
			continue;

		case 'O':
			ocsp_enable = TRUE;
			continue;

		case 'Y':
			ocsp_default_uri = optarg;
			continue;

		case 'J':
			ocsp_trust_name = optarg;
			continue;

		case 'T':	/* --ocsp_timeout <seconds> */
			ugh = ttoulb(optarg, 0, 10, 0xFFFF, &u);
			if (ugh != NULL)
				break;
			if (u == 0) {
				ugh = "must not be 0";
				break;
			}
			ocsp_timeout = u;
			continue;

		case 'x':	/* --crlcheckinterval <seconds> */
			ugh = ttoulb(optarg, 0, 10, TIME_T_MAX, &u);
			if (ugh != NULL)
				break;
			crl_check_interval = deltatime(u);
			continue;

		case 'u':	/* --uniqueids */
			uniqueIDs = TRUE;
			continue;

		case 'i':	/* --interface <ifname|ifaddr> */
			if (!use_interface(optarg)) {
				ugh = "too many --interface specifications";
				break;
			}
			continue;

		/*
		 * This option does not really work, as this is the "left"
		 * site only, you also need --to --ikeport again later on
		 * It will result in: yourport -> 500, still not bypassing
		 * filters
		 */
		case 'p':	/* --ikeport <portnumber> */
			ugh = ttoulb(optarg, 0, 10, 0xFFFF, &u);
			if (ugh != NULL)
				break;
			if (u == 0) {
				ugh = "must not be 0";
				break;
			}
			pluto_port = u;
			continue;

		case 'q':	/* --natikeport <portnumber> */
			ugh = ttoulb(optarg, 0, 10, 0xFFFF, &u);
			if (ugh != NULL)
				break;
			if (u == 0) {
				ugh = "must not be 0";
				break;
			}
			pluto_nat_port = u;
			continue;

		case 'b':	/* --ctlbase <path> */
			/*
			 * ??? work to be done here:
			 *
			 * snprintf returns the required space if there
			 * isn't enough, not -1.
			 * -1 indicates another kind of error.
			 *
			 * This appears to be the only place where the
			 * ctlbase value is used yet it is set elsewhere.
			 * (This isn't clear -- it may be OK.)
			 */
			ctlbase = optarg;
			if (snprintf(ctl_addr.sun_path,
					sizeof(ctl_addr.sun_path),
					"%s%s", ctlbase, CTL_SUFFIX) == -1) {
				ugh = "<path>" CTL_SUFFIX " too long for sun_path";
				break;
			}

			if (snprintf(info_addr.sun_path,
					sizeof(info_addr.sun_path),
					"%s%s", ctlbase, INFO_SUFFIX) == -1) {
				ugh = "<path>" INFO_SUFFIX " too long for sun_path";
				break;
			}

			if (snprintf(pluto_lock, sizeof(pluto_lock),
					"%s%s", ctlbase, LOCK_SUFFIX) == -1) {
				ugh = "<path>" LOCK_SUFFIX " must fit";
				break;
			}
			continue;

		case 's':	/* --secretsfile <secrets-file> */
			lsw_conf_secretsfile(optarg);
			continue;

		case 'f':	/* --ipsecdir <ipsec-dir> */
			lsw_init_ipsecdir(optarg);
			continue;

		case 'N':	/* --debug-none */
			base_debugging = DBG_NONE;
			continue;

		case 'A':	/* --debug-all */
			base_debugging = DBG_ALL;
			continue;

		case 'P':	/* --perpeerlogbase */
			base_perpeer_logdir = optarg;
			continue;

		case 'l':	/* --perpeerlog */
			log_to_perpeer = TRUE;
			continue;

		case '2':	/* --keep-alive <delay_secs> */
			ugh = ttoulb(optarg, 0, 10, secs_per_day, &u);
			if (ugh != NULL)
				break;
			keep_alive = u;
			continue;

		case '5':	/* --debug-nat-t */
			base_debugging |= DBG_NATT;
			continue;
		case '6':	/* --virtual-private */
			virtual_private = optarg;
			continue;

		case 'z':	/* --config */
		{
			/*
			 * Config struct to variables mapper. This will
			 * overwrite all previously set options. Keep this
			 * in the same order as long_opts[] is.
			 */
			struct starter_config *cfg = read_cfg_file(optarg);

			/* leak */
			set_cfg_string(&pluto_log_file,
				cfg->setup.strings[KSF_PLUTOSTDERRLOG]);
			if (pluto_log_file != NULL)
				log_to_syslog = FALSE;
			/* plutofork= no longer supported via config file */
			log_with_timestamp =
				cfg->setup.options[KBF_PLUTOSTDERRLOGTIME];
			log_append = cfg->setup.options[KBF_PLUTOSTDERRLOGAPPEND];
			pluto_drop_oppo_null = cfg->setup.options[KBF_DROP_OPPO_NULL];
			pluto_ddos_mode = cfg->setup.options[KBF_DDOS_MODE];
			if (cfg->setup.options[KBF_FORCEBUSY]) {
				/* force-busy is obsoleted, translate to ddos-mode= */
				pluto_ddos_mode = cfg->setup.options[KBF_DDOS_MODE] = DDOS_FORCE_BUSY;
			}
			/* ddos-ike-threshold and max-halfopen-ike */
			pluto_ddos_threshold = cfg->setup.options[KBF_DDOS_IKE_THRESHOLD];
			pluto_max_halfopen = cfg->setup.options[KBF_MAX_HALFOPEN_IKE];

			strict_crl_policy =
				cfg->setup.options[KBF_STRICTCRLPOLICY];

			pluto_shunt_lifetime = deltatime(cfg->setup.options[KBF_SHUNTLIFETIME]);

			strict_ocsp_policy =
				cfg->setup.options[KBF_STRICTOCSPPOLICY];

			ocsp_enable = cfg->setup.options[KBF_OCSPENABLE];

			set_cfg_string(&ocsp_default_uri,
				       cfg->setup.strings[KSF_OCSPURI]);

			ocsp_timeout = cfg->setup.options[KBF_OCSPTIMEOUT];

			set_cfg_string(&ocsp_trust_name,
				       cfg->setup.strings[KSF_OCSPTRUSTNAME]);

			crl_check_interval = deltatime(
				cfg->setup.options[KBF_CRLCHECKINTERVAL]);
			uniqueIDs = cfg->setup.options[KBF_UNIQUEIDS];
			/*
			 * We don't check interfaces= here because that part
			 * has been dealt with in _stackmanager before we
			 * started
			 */
			set_cfg_string(&pluto_listen,
				cfg->setup.strings[KSF_LISTEN]);

			/* --ikeport */
			pluto_port = cfg->setup.options[KBF_IKEPORT];

			/* --nflog-all */
			/* only causes nflog nmber to show in ipsec status */
			pluto_nflog_group = cfg->setup.options[KBF_NFLOG_ALL];

			/* only causes nflog nmber to show in ipsec status */
			pluto_xfrmlifetime = cfg->setup.options[KBF_XFRMLIFETIME];

			/* no config option: ctlbase */
			/* --secrets */
			if (cfg->setup.strings[KSF_SECRETSFILE] &&
			    *cfg->setup.strings[KSF_SECRETSFILE]) {
				lsw_conf_secretsfile(cfg->setup.strings[KSF_SECRETSFILE]);
			}
			if (cfg->setup.strings[KSF_IPSECDIR] != NULL &&
				*cfg->setup.strings[KSF_IPSECDIR] != 0) {
				/* --ipsecdir */
				lsw_init_ipsecdir(cfg->setup.strings[KSF_IPSECDIR]);
			}

			/* --perpeerlog */
			log_to_perpeer = cfg->setup.options[KBF_PERPEERLOG];
			if (log_to_perpeer) {
				/* --perpeerlogbase */
				if (cfg->setup.strings[KSF_PERPEERDIR]) {
					set_cfg_string(&base_perpeer_logdir,
						cfg->setup.strings[KSF_PERPEERDIR]);
				} else {
					base_perpeer_logdir = clone_str("/var/log/pluto/", "perpeer_logdir");
				}
			}

			if (cfg->setup.strings[KSF_CURLIFACE]) {
				pfreeany(curl_iface);
				/* curl-iface= */
				curl_iface = clone_str(cfg->setup.strings[KSF_CURLIFACE],
						"curl-iface= via --config");
			}

			if (cfg->setup.options[KBF_CURLTIMEOUT])
				curl_timeout = cfg->setup.options[KBF_CURLTIMEOUT];

			if (cfg->setup.strings[KSF_DUMPDIR]) {
				pfree(coredir);
				/* dumpdir= */
				coredir = clone_str(cfg->setup.strings[KSF_DUMPDIR],
						"coredir via --config");
			}
			/* --vendorid */
			if (cfg->setup.strings[KSF_MYVENDORID]) {
				pfree(pluto_vendorid);
				pluto_vendorid = clone_str(cfg->setup.strings[KSF_MYVENDORID],
						"pluto_vendorid via --config");
			}

			/* no config option: pluto_adns_option */

			if (cfg->setup.strings[KSF_STATSBINARY] != NULL) {
				if (access(cfg->setup.strings[KSF_STATSBINARY], X_OK) == 0) {
					pfreeany(pluto_stats_binary);
					/* statsbin= */
					pluto_stats_binary = clone_str(cfg->setup.strings[KSF_STATSBINARY], "statsbin via --config");
					libreswan_log("statsbinary set to %s", pluto_stats_binary);
				} else {
					libreswan_log("statsbinary= '%s' ignored - file does not exist or is not executable",
						pluto_stats_binary);
				}
			}

			pluto_nss_seedbits = cfg->setup.options[KBF_SEEDBITS];
			pluto_nat_port =
				cfg->setup.options[KBF_NATIKEPORT];
			keep_alive = cfg->setup.options[KBF_KEEPALIVE];

			set_cfg_string(&virtual_private,
				cfg->setup.strings[KSF_VIRTUALPRIVATE]);

			nhelpers = cfg->setup.options[KBF_NHELPERS];
#ifdef HAVE_LABELED_IPSEC
			secctx_attr_type = cfg->setup.options[KBF_SECCTX];
#endif
			base_debugging = cfg->setup.options[KBF_PLUTODEBUG];

			char *protostack = cfg->setup.strings[KSF_PROTOSTACK];

			if (protostack == NULL || *protostack == '\0') {
				kern_interface = USE_NETKEY;
			} else if (streq(protostack, "none")) {
				kern_interface = NO_KERNEL;
			} else if (streq(protostack, "auto")) {
				libreswan_log(
					"The option protostack=auto is obsoleted, falling back to protostack=netkey\n");
				kern_interface = USE_NETKEY;
			} else if (streq(protostack, "klips")) {
				kern_interface = USE_KLIPS;
			} else if (streq(protostack, "mast")) {
				kern_interface = USE_MASTKLIPS;
			} else if (streq(protostack, "netkey") ||
				streq(protostack, "native")) {
				kern_interface = USE_NETKEY;
			} else if (streq(protostack, "bsd") ||
				streq(protostack, "kame") ||
				streq(protostack, "bsdkame")) {
				kern_interface = USE_BSDKAME;
			} else if (streq(protostack, "win2k")) {
				kern_interface = USE_WIN2K;
			}

			confread_free(cfg);
			continue;
		}

		default:
			if (DBG_OFFSET <= c &&
			    c < DBG_OFFSET + IMPAIR_roof_IX) {
				base_debugging |= LELEM(c - DBG_OFFSET);
				continue;
			}
			bad_case(c);
		}
		/* if ugh is set, bail with diagnostic */
		if (ugh != NULL) {
			char mess[200];

			if (longindex == -1) {
				snprintf(mess, sizeof(mess), "unknown option: %s",
					ugh);
			} else if (optarg == NULL) {
				snprintf(mess, sizeof(mess), "--%s option: %s",
					optname, ugh);
			} else {
				snprintf(mess, sizeof(mess), "--%s \"%s\" option: %s",
					optname, optarg, ugh);
			}
			invocation_fail(mess);
		}
		break;
	}
	if (optind != argc)
		invocation_fail("unexpected argument");
	reset_debugging();

	if (chdir(coredir) == -1) {
		int e = errno;

		libreswan_log("pluto: warning: chdir(\"%s\") to dumpdir failed (%d: %s)",
			coredir, e, strerror(e));
	}

	oco = lsw_init_options();
	lockfd = create_lock();

	/* select between logging methods */

	if (log_to_stderr_desired || log_to_file_desired)
		log_to_syslog = FALSE;
	if (!log_to_stderr_desired)
		log_to_stderr = FALSE;

#if 0
	if (kernel_ops->set_debug != NULL)
		(*kernel_ops->set_debug)(cur_debugging, DBG_log, DBG_log);

#endif

	/*
	 * create control socket.
	 * We must create it before the parent process returns so that
	 * there will be no race condition in using it.  The easiest
	 * place to do this is before the daemon fork.
	 */
	{
		err_t ugh = init_ctl_socket();

		if (ugh != NULL) {
			fprintf(stderr, "pluto: FATAL: %s", ugh);
			exit_pluto(PLUTO_EXIT_SOCKET_FAIL);
		}
	}

	/* If not suppressed, do daemon fork */
	if (fork_desired) {
#if USE_DAEMON
		if (daemon(TRUE, TRUE) < 0) {
			fprintf(stderr, "pluto: FATAL: daemon failed (%d %s)\n",
				errno, strerror(errno));
			exit_pluto(PLUTO_EXIT_FORK_FAIL);
		}
		/*
		 * Parent just exits, so need to fill in our own PID
		 * file.  This is racy, since the file won't be
		 * created until after the parent has exited.
		 *
		 * Since "ipsec start" invokes pluto with --nofork, it
		 * is probably safer to leave this feature disabled
		 * then implement it using the daemon call.
		 */
		(void) fill_lock(lockfd, getpid());
#elif USE_FORK
		{
			pid_t pid = fork();

			if (pid < 0) {
				int e = errno;

				fprintf(stderr, "pluto: FATAL: fork failed (%d %s)\n",
					errno, strerror(e));
				exit_pluto(PLUTO_EXIT_FORK_FAIL);
			}

			if (pid != 0) {
				/*
				 * parent: die, after filling PID into lock
				 * file.
				 * must not use exit_pluto: lock would be
				 * removed!
				 */
				exit(fill_lock(lockfd, pid) ? 0 : 1);
			}
		}
#else
		fprintf(stderr, "pluto: FATAL: fork/daemon not supported\n");
		exit_pluto(PLUTO_EXIT_FORK_FAIL);		
#endif
		if (setsid() < 0) {
			int e = errno;

			fprintf(stderr,
				"FATAL: setsid() failed in main(). Errno %d: %s\n",
				errno, strerror(e));
			exit_pluto(PLUTO_EXIT_FAIL);
		}
	} else {
		/* no daemon fork: we have to fill in lock file */
		(void) fill_lock(lockfd, getpid());
		if (isatty(fileno(stdout))) {
			fprintf(stdout, "Pluto initialized\n");
			fflush(stdout);
		}
	}

	/*
	 * Close everything but ctl_fd and (if needed) stderr.
	 * There is some danger that a library that we don't know
	 * about is using some fd that we don't know about.
	 * I guess we'll soon find out.
	 */
	{
		int i;

		for (i = getdtablesize() - 1; i >= 0; i--)	/* Bad hack */
			if ((!log_to_stderr || i != 2) &&
				i != ctl_fd)
				close(i);

		/* make sure that stdin, stdout, stderr are reserved */
		if (open("/dev/null", O_RDONLY) != 0)
			lsw_abort();
		if (dup2(0, 1) != 1)
			lsw_abort();
		if (!log_to_stderr && dup2(0, 2) != 2)

			lsw_abort();
	}

	init_constants();
	init_pluto_constants();

	pluto_init_log();

	if (!pluto_init_nss(oco->nssdb)) {
		loglog(RC_LOG_SERIOUS, "FATAL: NSS initialization failure");
		exit_pluto(PLUTO_EXIT_NSS_FAIL);
	}
	libreswan_log("NSS crypto library initialized");

	if (ocsp_enable) {
		if (!init_nss_ocsp(ocsp_default_uri, ocsp_trust_name,
						     ocsp_timeout,
						     strict_ocsp_policy)) {
			loglog(RC_LOG_SERIOUS, "Initializing NSS OCSP failed");
			exit_pluto(PLUTO_EXIT_NSS_FAIL);
		} else {
			libreswan_log("NSS OCSP Enabled");
		}
	}

#ifdef HAVE_LIBCAP_NG
	/*
	 * Drop capabilities - this generates a false positive valgrind warning
	 * See: http://marc.info/?l=linux-security-module&m=125895232029657
	 *
	 * We drop these after creating the pluto socket or else we can't
	 * create a socket if the parent dir is non-root (eg openstack)
	 */
	capng_clear(CAPNG_SELECT_BOTH);

	capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED,
		CAP_NET_BIND_SERVICE, CAP_NET_ADMIN, CAP_NET_RAW,
		CAP_IPC_LOCK, CAP_AUDIT_WRITE,
		/* for google authenticator pam */
		CAP_SETGID, CAP_SETUID,
		CAP_DAC_READ_SEARCH,
		-1);
	/*
	 * We need to retain some capabilities for our children (updown):
	 * CAP_NET_ADMIN to change routes
	 * CAP_NET_RAW for iptables -t mangle
	 * CAP_DAC_READ_SEARCH for pam / google authenticator
	 */
	capng_updatev(CAPNG_ADD, CAPNG_BOUNDING_SET, CAP_NET_ADMIN, CAP_NET_RAW,
			CAP_DAC_READ_SEARCH, -1);
	capng_apply(CAPNG_SELECT_BOTH);
	libreswan_log("libcap-ng support [enabled]");
#else
	libreswan_log("libcap-ng support [disabled]");
#endif

#ifdef FIPS_CHECK
	libreswan_log("FIPS HMAC integrity support [enabled]");
	/*
	 * FIPS mode requires two conditions to be true:
	 *  - FIPS Kernel mode: fips=1 kernel boot parameter
	 *  - FIPS Product mode: See FIPSPRODUCTCHECK in Makefile.inc
	 *     (in RHEL/Fedora, dracut-fips installs $FIPSPRODUCTCHECK)
	 *
	 * When FIPS mode, abort on self-check hmac failure. Otherwise, complain
	 */
	{
		if (DBGP(IMPAIR_FORCE_FIPS)) {
			libreswan_log("Forcing FIPS checks to true to emulate FIPS mode");
			lsw_set_fips_mode(LSW_FIPS_ON);
		}

		enum lsw_fips_mode pluto_fips_mode = lsw_get_fips_mode();
		bool nss_fips_mode = PK11_IsFIPS();

		/*
		 * Now verify the consequences.  Always run the tests
		 * as combinations such as NSS in fips mode but as out
		 * of it could be bad.
		 */
		switch (pluto_fips_mode) {
		case LSW_FIPS_UNKNOWN:
			loglog(RC_LOG_SERIOUS, "ABORT: pluto FIPS mode could not be determined");
			exit_pluto(PLUTO_EXIT_FIPS_FAIL);
			break;
		case LSW_FIPS_ON:
			libreswan_log("FIPS mode enabled for pluto daemon");
			if (nss_fips_mode) {
				libreswan_log("NSS library is running in FIPS mode");
			} else {
				loglog(RC_LOG_SERIOUS, "ABORT: pluto in FIPS mode but NSS library is not");
				exit_pluto(PLUTO_EXIT_FIPS_FAIL);
			}
			break;
		case LSW_FIPS_OFF:
			libreswan_log("FIPS mode disabled for pluto daemon");
			if (nss_fips_mode) {
				loglog(RC_LOG_SERIOUS, "Warning: NSS library is running in FIPS mode");
			}
			break;
		case LSW_FIPS_UNSET:
		default:
			bad_case(pluto_fips_mode);
		}

		/* always run hmac check so we can print diagnostic */
		bool fips_files = FIPSCHECK_verify_files(fips_package_files);

		if (fips_files) {
			libreswan_log("FIPS HMAC integrity verification self-test passed");
		} else {
			loglog(RC_LOG_SERIOUS, "FIPS HMAC integrity verification self-test FAILED");
		}
		if (pluto_fips_mode == LSW_FIPS_ON && !fips_files) {
			exit_pluto(PLUTO_EXIT_FIPS_FAIL);
		}
	}
#else
	libreswan_log("FIPS HMAC integrity support [disabled]");
#endif

#ifdef USE_LINUX_AUDIT
	linux_audit_init();
#else
	libreswan_log("Linux audit support [disabled]");
#endif

	{
		const char *vc = ipsec_version_code();
		libreswan_log("Starting Pluto (Libreswan Version %s%s) pid:%u",
			vc, compile_time_interop_options, getpid());
	}

	libreswan_log("core dump dir: %s", coredir);
	if (oco->secretsfile && *oco->secretsfile)
		libreswan_log("secrets file: %s", oco->secretsfile);

	libreswan_log(leak_detective ?
		"leak-detective enabled" : "leak-detective disabled");

	/* Check for SAREF support */
#ifdef KLIPS_MAST
#include <ipsec_saref.h>
	{
		int e, sk, saref;
		saref = 1;
		errno = 0;

		sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
		e = setsockopt(sk, IPPROTO_IP, IP_IPSEC_REFINFO, &saref,
			sizeof(saref));
		if (e == -1 )
			libreswan_log("SAref support [disabled]: %s",
				strerror(errno));
		else
			libreswan_log("SAref support [enabled]");
		errno = 0;
		e = setsockopt(sk, IPPROTO_IP, IP_IPSEC_BINDREF, &saref,
			sizeof(saref));
		if (e == -1 )
			libreswan_log("SAbind support [disabled]: %s",
				strerror(errno));
		else
			libreswan_log("SAbind support [enabled]");

		close(sk);
	}
#endif

	libreswan_log("NSS crypto [enabled]");

#ifdef XAUTH_HAVE_PAM
	libreswan_log("XAUTH PAM support [enabled]");
#else
	libreswan_log("XAUTH PAM support [disabled]");
#endif

/* Log various impair-* functions if they were enabled */

	if (DBGP(IMPAIR_BUST_MI2))
		libreswan_log("Warning: IMPAIR_BUST_MI2 enabled");
	if (DBGP(IMPAIR_BUST_MR2))
		libreswan_log("Warning: IMPAIR_BUST_MR2 enabled");
	if (DBGP(IMPAIR_SA_CREATION))
		libreswan_log("Warning: IMPAIR_SA_CREATION enabled");
	if (DBGP(IMPAIR_JACOB_TWO_TWO))
		libreswan_log("Warning: IMPAIR_JACOB_TWO_TWO enabled");
	if (DBGP(IMPAIR_DIE_ONINFO))
		libreswan_log("Warning: IMPAIR_DIE_ONINFO enabled");
	if (DBGP(IMPAIR_MAJOR_VERSION_BUMP))
		libreswan_log("Warning: IMPAIR_MAJOR_VERSION_BUMP enabled");
	if (DBGP(IMPAIR_MINOR_VERSION_BUMP))
		libreswan_log("Warning: IMPAIR_MINOR_VERSION_BUMP enabled");
	if (DBGP(IMPAIR_RETRANSMITS))
		libreswan_log("Warning: IMPAIR_RETRANSMITS enabled");
	if (DBGP(IMPAIR_SEND_BOGUS_ISAKMP_FLAG))
		libreswan_log("Warning: IMPAIR_SEND_BOGUS_ISAKMP_FLAG enabled");
	if (DBGP(IMPAIR_SEND_BOGUS_PAYLOAD_FLAG))
		libreswan_log("Warning: IMPAIR_SEND_BOGUS_PAYLOAD_FLAG enabled");
	if (DBGP(IMPAIR_SEND_IKEv2_KE))
		libreswan_log("Warning: IMPAIR_SEND_IKEv2_KE enabled");
	if (DBGP(IMPAIR_SEND_KEY_SIZE_CHECK))
		libreswan_log("Warning: IMPAIR_SEND_KEY_SIZE_CHECK enabled");
	if (DBGP(IMPAIR_SEND_NO_DELETE))
		libreswan_log("Warning: IMPAIR_SEND_NO_DELETE enabled");
	if (DBGP(IMPAIR_FORCE_FIPS))
		libreswan_log("Warning: IMPAIR_FORCE_FIPS enabled");
	if (DBGP(IMPAIR_SEND_NO_IKEV2_AUTH))
		libreswan_log("Warning: IMPAIR_SEND_NO_IKEV2_AUTH enabled");
	if (DBGP(IMPAIR_SEND_ZERO_GX))
		libreswan_log("Warning: IMPAIR_SEND_ZERO_GX enabled");
	if (DBGP(IMPAIR_SEND_BOGUS_DCOOKIE))
		libreswan_log("Warning: IMPAIR_SEND_BOGUS_DCOOKIE enabled");

/* Initialize all of the various features */

	init_nat_traversal(keep_alive);

	init_virtual_ip(virtual_private);
	/* obsoleted by nss code init_rnd_pool(); */
	init_event_base();
	init_secret();
	init_states();
	init_connections();
	init_crypto();
	init_crypto_helpers(nhelpers);
	init_demux();
	init_kernel();
	init_id();
	init_vendorid();
#if defined(LIBCURL) || defined(LDAP_VER)
	init_fetch();
#endif
	load_crls();
#ifdef HAVE_LABELED_IPSEC
	init_avc();
#endif
	daily_log_event();
#ifdef USE_SYSTEMD_WATCHDOG
	pluto_sd_init();
#endif

	call_server();
	return -1;	/* Shouldn't ever reach this */
}
Example #11
0
int main(int argc, char **argv) {
    IDEAL* pp;
    IDEAL** Ms;
    IDEAL** Rads;

    char M_name[MAX_LABEL_LENGTH];
    char N_name[MAX_LABEL_LENGTH];

    /* learn who we really are */
    progname = (const char *)strrchr(argv[0], '/');
    progname = progname ? (progname + 1) : argv[0];

    /* handle cmdline */
    handle_cmdline(&argc, &argv);

    /* initializing needed things */
    init_constants();

    if ( !(i < numofMs) || !(j < nilindex) ) {
        fprintf(stderr, "i must be less than numofMs = m*(pi - 1) + 1, "
                        "j must be less than nilindex = l*(p - 1) + 1.\n");
        exit(EXIT_FAILURE);
    }

    /* we need at most 2 IDEALs per array */
    Ms   = (IDEAL**) malloc(2*sizeof(IDEAL*));
    Rads = (IDEAL**) malloc(2*sizeof(IDEAL*));

    if (Ms == NULL || Rads == NULL) {
        fprintf(stderr, "Unable to allocate memory for ideals' arrays.\n");
        exit(EXIT_FAILURE);
    }

    /* do the job */
    if ((output_control & WAS_SPECIFIED_M) && (output_control & WAS_SPECIFIED_RAD)) {
        /* both M_pi(m,i) and Rad^j were specified, process only them*/
        pp = ideal_create(q);
        ideal_init(pp, pi, m, i);
        Ms[0] = pp;

        pp = ideal_create(q);
        ideal_init(pp, p, l, l*(p - 1) - j);
        Rads[0] = pp;

        sprintf(M_name, "M_%llu(%u,%llu)", pi, m, i);
        sprintf(N_name, "Rad^%llu", j);

        if (ideal_issubset(Rads[0], Ms[0])) {
            print_diff(Ms[0], Ms[0], Rads[0], M_name, N_name, use_colors);

            if (debug >= 2) {
                fprintf(stdout, "%s\t\t=\n", N_name);
                if (use_colors) {
                    color_ideal_print(SPECIAL_COLOR, Rads[0], isspecial_integer);
                } else {
                    ideal_print(Rads[0]);
                }
                fprintf(stdout, "\n");
            }
        } else if (ideal_issubset(Ms[0], Rads[0])) {
            print_diff(Rads[0], Rads[0], Ms[0], N_name, M_name, use_colors);

            if (debug >= 2) {
                fprintf(stdout, "%s\t\t=\n", M_name);
                if (use_colors) {
                    color_ideal_print(SPECIAL_COLOR, Ms[0], isspecial_integer);
                } else {
                    ideal_print(Ms[0]);
                }
                fprintf(stdout, "\n");
            }
        } else {
            /* we will store intersection here */
            pp = ideal_create(q);
            Ms[1] = pp;

            if (debug >= 2) {
                fprintf(stdout, "%s\t\t=\n", M_name);
                if (use_colors) {
                    color_ideal_print(SPECIAL_COLOR, Ms[0], isspecial_integer);
                } else {
                    ideal_print(Ms[0]);
                }
                fprintf(stdout, "\n");
            }

            if (debug >= 2) {
                fprintf(stdout, "%s\t\t=\n", N_name);
                if (use_colors) {
                    color_ideal_print(SPECIAL_COLOR, Rads[0], isspecial_integer);
                } else {
                    ideal_print(Rads[0]);
                }
                fprintf(stdout, "\n");
            }

            ideal_intersect(Ms[1], Ms[0], Rads[0]);

            sprintf(N_name, "(M_%llu(%u,%llu) /\\ Rad^%llu)", pi, m, i, j);

            sprintf(M_name, "M_%llu(%u,%llu)", pi, m, i);
            print_diff(Ms[0], Ms[0], Ms[1], M_name, N_name, use_colors);

            sprintf(M_name, "Rad^%llu", j);
            print_diff(Rads[0], Rads[0], Ms[1], M_name, N_name, use_colors);
        }
    } else if (output_control & WAS_SPECIFIED_RAD) {
        /* only Rad^j was specified, find sup and inf M_pi(m,k) and process all three of them */
        unsigned long long Mpi_to_Rad, Rad_to_Mpi;

        Rad_to_Mpi = maximum_Pi_for_P(l*(p - 1) - j, p, m);
        Mpi_to_Rad = minimum_Pi_for_P(l*(p - 1) - j, p, m, lambda);

        if (Mpi_to_Rad == Rad_to_Mpi) {
            fprintf(stdout, "Rad^%llu == M_%llu(%u,%llu)\n\n",
                    j, pi, m, Rad_to_Mpi);
            goto end;
        }

        pp = ideal_create(q);
        ideal_init(pp, pi, m, Rad_to_Mpi);
        Ms[0] = pp;

        pp = ideal_create(q);
        ideal_init(pp, pi, m, Mpi_to_Rad);
        Ms[1] = pp;

        pp = ideal_create(q);
        ideal_init(pp, p, l, l*(p - 1) - j);
        Rads[0] = pp;

        fprintf(stdout, "M_%llu(%u,%llu) -> Rad^%llu -> M_%llu(%u,%llu)\n\n",
                pi, m, Mpi_to_Rad, j, pi, m, Rad_to_Mpi);

        sprintf(N_name, "Rad^%llu", j);

        sprintf(M_name, "M_%llu(%u,%llu)", pi, m, Mpi_to_Rad);
        print_diff(Ms[1], Ms[1], Rads[0], M_name, N_name, use_colors);

        sprintf(M_name, "M_%llu(%u,%llu)", pi, m, Rad_to_Mpi);
        print_diff(Ms[0], Rads[0], Ms[0], N_name, M_name, use_colors);

        if (debug >= 2) {
            fprintf(stdout, "%s\t\t=\n", N_name);
            if (use_colors) {
                color_ideal_print(SPECIAL_COLOR, Rads[0], isspecial_integer);
            } else {
                ideal_print(Rads[0]);
            }
            fprintf(stdout, "\n");
        }
    } else if (output_control & WAS_SPECIFIED_M) {
        /* only M_pi(m,i) was specified, find sup and inf Rad^j and process all three of them */
        unsigned long long Mpi_to_Rad, Rad_to_Mpi;

        Rad_to_Mpi = minimum_P_for_Pi(i, p, m);
        Mpi_to_Rad = maximum_P_for_Pi(i, p, m, l, lambda, numofMs - 1);

        if (Mpi_to_Rad == Rad_to_Mpi) {
            fprintf(stdout, "M_%llu(%u,%llu) == Rad^%llu\n\n",
                    pi, m, i, l*(p - 1) - Rad_to_Mpi);
            goto end;
        }

        pp = ideal_create(q);
        ideal_init(pp, p, l, Mpi_to_Rad);
        Rads[0] = pp;

        pp = ideal_create(q);
        ideal_init(pp, p, l, Rad_to_Mpi);
        Rads[1] = pp;

        pp = ideal_create(q);
        ideal_init(pp, pi, m, i);
        Ms[0] = pp;

        fprintf(stdout, "Rad^%llu -> M_%llu(%u,%llu) -> Rad^%llu\n\n",
                l*(p - 1) - Rad_to_Mpi, pi, m, i, l*(p - 1) - Mpi_to_Rad);

        sprintf(M_name, "M_%llu(%u,%llu)", pi, m, i);

        sprintf(N_name, "Rad^%llu", l*(p - 1) - Rad_to_Mpi);
        print_diff(Rads[1], Rads[1], Ms[0], N_name, M_name, use_colors);

        sprintf(N_name, "Rad^%llu", l*(p - 1) - Mpi_to_Rad);
        print_diff(Rads[0], Ms[0], Rads[0], M_name, N_name, use_colors);

        if (debug >= 2) {
            fprintf(stdout, "%s\t\t=\n", M_name);
            if (use_colors) {
                color_ideal_print(SPECIAL_COLOR, Ms[0], isspecial_integer);
            } else {
                ideal_print(Ms[0]);
            }
            fprintf(stdout, "\n");
        }
    } else {
        fprintf(stderr, "Incorrect usage. See --help.\n");
    }

end:
    /* do cleanup */
    dbg_msg_l(5, "Freeing Ms...\n");
    for (i = 0; i < 2; ++i) {
        ideal_free(Ms[i]);
    }
    free(Ms);

    dbg_msg_l(5, "Freeing Rads...\n");
    for (i = 0; i < 2; ++i) {
        ideal_free(Rads[i]);
    }
    free(Rads);

    return 0;
}
Example #12
0
int
main(int argc, char **argv)
{
    bool fork_desired = TRUE;
    int lockfd;
    char* ocspuri = NULL;
    int nhelpers = -1;
    char *coredir;
    const struct osw_conf_options *oco;

#ifdef NAT_TRAVERSAL
    /** Overridden by nat_traversal= in ipsec.conf */
    bool nat_traversal = FALSE;
    bool nat_t_spf = TRUE;  /* support port floating */
    unsigned int keep_alive = 0;
    bool force_keepalive = FALSE;
#endif
    /** Overridden by virtual_private= in ipsec.conf */
    char *virtual_private = NULL;
#ifdef LEAK_DETECTIVE
    leak_detective=1;
#else
    leak_detective=0;
#endif

#ifdef HAVE_LIBCAP_NG
	/* Drop capabilities */
	capng_clear(CAPNG_SELECT_BOTH);
	capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
			CAP_NET_BIND_SERVICE, CAP_NET_ADMIN, CAP_NET_RAW,
			CAP_IPC_LOCK, -1);
	/* our children must be able to CAP_NET_ADMIN to change routes.
	 */
	capng_updatev(CAPNG_ADD, CAPNG_BOUNDING_SET,
			CAP_NET_ADMIN, -1);
	capng_apply(CAPNG_SELECT_BOTH);
#endif


    global_argv = argv;
    global_argc = argc;
#ifdef DEBUG
    openswan_passert_fail = passert_fail;
#endif

    /* see if there is an environment variable */
    coredir = getenv("PLUTO_CORE_DIR");

    if(getenv("PLUTO_WAIT_FOR_GDB")) {
	sleep(120);
    }

    /* handle arguments */
    for (;;)
    {
#	define DBG_OFFSET 256
	static const struct option long_opts[] = {
	    /* name, has_arg, flag, val */
	    { "help", no_argument, NULL, 'h' },
	    { "version", no_argument, NULL, 'v' },
	    { "optionsfrom", required_argument, NULL, '+' },
	    { "nofork", no_argument, NULL, 'd' },
	    { "stderrlog", no_argument, NULL, 'e' },
	    { "noklips", no_argument, NULL, 'n' },
	    { "use-nostack",  no_argument, NULL, 'n' },
	    { "use-none",     no_argument, NULL, 'n' },
	    { "force_busy", no_argument, NULL, 'D' },
	    { "nocrsend", no_argument, NULL, 'c' },
	    { "strictcrlpolicy", no_argument, NULL, 'r' },
	    { "crlcheckinterval", required_argument, NULL, 'x'},
	    { "ocsprequestcert", required_argument, NULL, 'q'},
	    { "ocspuri", required_argument, NULL, 'o'},
	    { "uniqueids", no_argument, NULL, 'u' },
	    { "useklips",  no_argument, NULL, 'k' },
	    { "use-klips",  no_argument, NULL, 'k' },
	    { "use-auto",  no_argument, NULL, 'G' },
	    { "usenetkey", no_argument, NULL, 'K' },
	    { "use-netkey", no_argument, NULL, 'K' },
	    { "use-mast",   no_argument, NULL, 'M' },
	    { "use-mastklips",   no_argument, NULL, 'M' },
	    { "use-bsdkame",   no_argument, NULL, 'F' },
	    { "interface", required_argument, NULL, 'i' },
	    { "listen", required_argument, NULL, 'L' },
	    { "ikeport", required_argument, NULL, 'p' },
	    { "ctlbase", required_argument, NULL, 'b' },
	    { "secretsfile", required_argument, NULL, 's' },
	    { "foodgroupsdir", required_argument, NULL, 'f' },
	    { "perpeerlogbase", required_argument, NULL, 'P' },
	    { "perpeerlog", no_argument, NULL, 'l' },
	    { "noretransmits", no_argument, NULL, 'R' },
	    { "coredir", required_argument, NULL, 'C' },
	    { "ipsecdir", required_argument, NULL, 'f' },
	    { "ipsec_dir", required_argument, NULL, 'f' },
#ifdef USE_LWRES
	    { "lwdnsq", required_argument, NULL, 'a' },
#else /* !USE_LWRES */
	    { "adns", required_argument, NULL, 'a' },
#endif /* !USE_LWRES */
#ifdef NAT_TRAVERSAL
	    { "nat_traversal", no_argument, NULL, '1' },
	    { "keep_alive", required_argument, NULL, '2' },
	    { "force_keepalive", no_argument, NULL, '3' },
	    { "disable_port_floating", no_argument, NULL, '4' },
	    { "debug-nat_t", no_argument, NULL, '5' },
	    { "debug-nattraversal", no_argument, NULL, '5' },
	    { "debug-nat-t", no_argument, NULL, '5' },
#endif
	    { "virtual_private", required_argument, NULL, '6' },
	    { "nhelpers", required_argument, NULL, 'j' },
#ifdef DEBUG
	    { "debug-none", no_argument, NULL, 'N' },
	    { "debug-all", no_argument, NULL, 'A' },

	    { "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },
	    { "debug-crypt", no_argument, NULL, DBG_CRYPT + DBG_OFFSET },
	    { "debug-crypto", no_argument, NULL, DBG_CRYPT + DBG_OFFSET },
	    { "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
	    { "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET },
	    { "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET },
	    { "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET },
	    { "debug-klips", no_argument, NULL, DBG_KLIPS + DBG_OFFSET },
	    { "debug-netkey", no_argument, NULL, DBG_NETKEY + DBG_OFFSET },
	    { "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET },
	    { "debug-oppo", no_argument, NULL, DBG_OPPO + DBG_OFFSET },
	    { "debug-oppoinfo", no_argument, NULL, DBG_OPPOINFO + DBG_OFFSET },
	    { "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET },
	    { "debug-dpd", no_argument, NULL, DBG_DPD + DBG_OFFSET },
            { "debug-x509", no_argument, NULL, DBG_X509 + DBG_OFFSET },
	    { "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },
	    { "debug-pfkey", no_argument, NULL, DBG_PFKEY + DBG_OFFSET },

	    { "impair-delay-adns-key-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_KEY_ANSWER + DBG_OFFSET },
	    { "impair-delay-adns-txt-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_TXT_ANSWER + DBG_OFFSET },
	    { "impair-bust-mi2", no_argument, NULL, IMPAIR_BUST_MI2 + DBG_OFFSET },
	    { "impair-bust-mr2", no_argument, NULL, IMPAIR_BUST_MR2 + DBG_OFFSET },
	    { "impair-sa-creation", no_argument, NULL, IMPAIR_SA_CREATION + DBG_OFFSET },
	    { "impair-die-oninfo", no_argument, NULL, IMPAIR_DIE_ONINFO + DBG_OFFSET },
	    { "impair-jacob-two-two", no_argument, NULL, IMPAIR_JACOB_TWO_TWO + DBG_OFFSET },
#endif
	    { 0,0,0,0 }
	    };
	/* Note: we don't like the way short options get parsed
	 * by getopt_long, so we simply pass an empty string as
	 * the list.  It could be "hvdenp:l:s:" "NARXPECK".
	 */
	int c = getopt_long(argc, argv, "", long_opts, NULL);

	/** Note: "breaking" from case terminates loop */
	switch (c)
	{
	case EOF:	/* end of flags */
	    break;

	case 0: /* long option already handled */
	    continue;

	case ':':	/* diagnostic already printed by getopt_long */
	case '?':	/* diagnostic already printed by getopt_long */
	    usage("");
	    break;   /* not actually reached */

	case 'h':	/* --help */
	    usage(NULL);
	    break;	/* not actually reached */

	case 'C':
	    coredir = clone_str(optarg, "coredir");
	    break;

	case 'v':	/* --version */
	    {
		const char **sp = ipsec_copyright_notice();

		printf("%s%s\n", ipsec_version_string(),
				 compile_time_interop_options);
		for (; *sp != NULL; sp++)
		    puts(*sp);
	    }
	    exit(0);	/* not exit_pluto because we are not initialized yet */
	    break;	/* not actually reached */

	case '+':	/* --optionsfrom <filename> */
	    optionsfrom(optarg, &argc, &argv, optind, stderr);
	    /* does not return on error */
	    continue;

	case 'j':	/* --nhelpers */
            if (optarg == NULL || !isdigit(optarg[0]))
                usage("missing number of pluto helpers");

            {
                char *endptr;
                long count = strtol(optarg, &endptr, 0);

                if (*endptr != '\0' || endptr == optarg
		    || count < -1)
                    usage("<nhelpers> must be a positive number, 0 or -1");
                nhelpers = count;
            }
	    continue;

	case 'd':	/* --nofork*/
	    fork_desired = FALSE;
	    continue;

	case 'e':	/* --stderrlog */
	    log_to_stderr_desired = TRUE;
	    continue;

	case 'G':       /* --use-auto */
	    kern_interface = AUTO_PICK;
	    continue;

	case 'k':       /* --use-klips */
	    kern_interface = USE_KLIPS;
	    continue;

	case 'L':	/* --listen ip_addr */
	    {
	    ip_address lip;
	     err_t e = ttoaddr(optarg,0,0,&lip);
	    if(e) {
		openswan_log("invalid listen argument ignored: %s\n",e);
	    } else {
		pluto_listen = clone_str(optarg, "pluto_listen");
		openswan_log("bind() will be filtered for %s\n",pluto_listen);
	    }
            }
	   continue;

	case 'M':       /* --use-mast */
	    kern_interface = USE_MASTKLIPS;
	    continue;

	case 'F':       /* --use-bsdkame */
	    kern_interface = USE_BSDKAME;
	    continue;

	case 'K':       /* --use-netkey */
	    kern_interface = USE_NETKEY;
	    continue;

	case 'n':	/* --use-nostack */
	    kern_interface = NO_KERNEL;
	    continue;

	case 'D':	/* --force_busy */
	    force_busy = TRUE;
	    continue
	    ;

	case 'c':	/* --nocrsend */
	    no_cr_send = TRUE;
	    continue
	    ;

	case 'r':	/* --strictcrlpolicy */
	    strict_crl_policy = TRUE;
	    continue
	    ;

	case 'R':
	    no_retransmits = TRUE;
	    continue;

	case 'x':	/* --crlcheckinterval <time>*/
            if (optarg == NULL || !isdigit(optarg[0]))
                usage("missing interval time");

            {
                char *endptr;
                long interval = strtol(optarg, &endptr, 0);

                if (*endptr != '\0' || endptr == optarg
                || interval <= 0)
                    usage("<interval-time> must be a positive number");
                crl_check_interval = interval;
            }
	    continue
	    ;

	case 'o':	/* --ocspuri */
	    ocspuri = optarg;
	    continue;

	case 'u':	/* --uniqueids */
	    uniqueIDs = TRUE;
	    continue;

	case 'i':	/* --interface <ifname|ifaddr> */
	    if (!use_interface(optarg))
		usage("too many --interface specifications");
	    continue;

	/* 
	 * This option does not really work, as this is the "left"
	 * site only, you also need --to --ikeport again later on
	 * It will result in: yourport -> 500, still not bypassing filters
	 */
	case 'p':	/* --ikeport <portnumber> */
	    if (optarg == NULL || !isdigit(optarg[0]))
		usage("missing port number");
	    {
		char *endptr;
		long port = strtol(optarg, &endptr, 0);

		if (*endptr != '\0' || endptr == optarg
		|| port <= 0 || port > 0x10000)
		    usage("<port-number> must be a number between 1 and 65535");
		pluto_port = port;
	    }
	    continue;

	case 'b':	/* --ctlbase <path> */
	    ctlbase = optarg;
	    if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
			 , "%s%s", ctlbase, CTL_SUFFIX) == -1)
		usage("<path>" CTL_SUFFIX " too long for sun_path");
	    if (snprintf(info_addr.sun_path, sizeof(info_addr.sun_path)
			 , "%s%s", ctlbase, INFO_SUFFIX) == -1)
		usage("<path>" INFO_SUFFIX " too long for sun_path");
	    if (snprintf(pluto_lock, sizeof(pluto_lock)
			 , "%s%s", ctlbase, LOCK_SUFFIX) == -1)
		usage("<path>" LOCK_SUFFIX " must fit");
	    continue;

	case 's':	/* --secretsfile <secrets-file> */
	    pluto_shared_secrets_file = optarg;
	    continue;

	case 'f':	/* --ipsecdir <ipsec-dir> */
	    (void)osw_init_ipsecdir(optarg);
	    continue;

	case 'a':	/* --adns <pathname> */
	    pluto_adns_option = optarg;
	    continue;

#ifdef DEBUG
	case 'N':	/* --debug-none */
	    base_debugging = DBG_NONE;
	    continue;

	case 'A':	/* --debug-all */
	    base_debugging = DBG_ALL;
	    continue;
#endif

	case 'P':       /* --perpeerlogbase */
	    base_perpeer_logdir = optarg;
	    continue;

	case 'l':
	    log_to_perpeer = TRUE;
	    continue;

#ifdef NAT_TRAVERSAL
	case '1':	/* --nat_traversal */
	    nat_traversal = TRUE;
	    continue;
	case '2':	/* --keep_alive */
	    keep_alive = atoi(optarg);
	    continue;
	case '3':	/* --force_keepalive */
	    force_keepalive = TRUE;
	    continue;
	case '4':	/* --disable_port_floating */
	    nat_t_spf = FALSE;
	    continue;
#ifdef DEBUG
	case '5':	/* --debug-nat_t */
	    base_debugging |= DBG_NATT;
	    continue;
#endif
#endif
	case '6':	/* --virtual_private */
	    virtual_private = optarg;
	    continue;

	default:
#ifdef DEBUG
	    if (c >= DBG_OFFSET)
	    {
		base_debugging |= c - DBG_OFFSET;
		continue;
	    }
#	undef DBG_OFFSET
#endif
	    bad_case(c);
	}
	break;
    }
    if (optind != argc)
	usage("unexpected argument");
    reset_debugging();

#ifdef HAVE_NO_FORK
	fork_desired = FALSE;
	nhelpers = 0;
#endif

    /* if a core dir was set, chdir there */
    if(coredir) 
	if(chdir(coredir) == -1) {
	   int e = errno;
	   openswan_log("pluto: chdir() do dumpdir failed (%d %s)\n",
                    e, strerror(e));
    }

    oco = osw_init_options();
    lockfd = create_lock();

    /* select between logging methods */

    if (log_to_stderr_desired)
	log_to_syslog = FALSE;
    else
	log_to_stderr = FALSE;

#ifdef DEBUG
#if 0
    if(kernel_ops->set_debug) {
	(*kernel_ops->set_debug)(cur_debugging, DBG_log, DBG_log);
    }
#endif
#endif

    /** create control socket.
     * We must create it before the parent process returns so that
     * there will be no race condition in using it.  The easiest
     * place to do this is before the daemon fork.
     */
    {
	err_t ugh = init_ctl_socket();

	if (ugh != NULL)
	{
	    fprintf(stderr, "pluto: %s", ugh);
	    exit_pluto(1);
	}
    }

#ifdef IPSECPOLICY
    /* create info socket. */
    {
	err_t ugh = init_info_socket();

	if (ugh != NULL)
	{
	    fprintf(stderr, "pluto: %s", ugh);
	    exit_pluto(1);
	}
    }
#endif

    /* If not suppressed, do daemon fork */

    if (fork_desired)
    {
	{
	    pid_t pid = fork();

	    if (pid < 0)
	    {
		int e = errno;

		fprintf(stderr, "pluto: fork failed (%d %s)\n",
		    errno, strerror(e));
		exit_pluto(1);
	    }

	    if (pid != 0)
	    {
		/* parent: die, after filling PID into lock file.
		 * must not use exit_pluto: lock would be removed!
		 */
		exit(fill_lock(lockfd, pid)? 0 : 1);
	    }
	}

	if (setsid() < 0)
	{
	    int e = errno;

	    fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",
		errno, strerror(e));
	    exit_pluto(1);
	}
    }
    else
    {
	/* no daemon fork: we have to fill in lock file */
	(void) fill_lock(lockfd, getpid());
	fprintf(stdout, "Pluto initialized\n");
	fflush(stdout);
    }

    /** Close everything but ctl_fd and (if needed) stderr.
     * There is some danger that a library that we don't know
     * about is using some fd that we don't know about.
     * I guess we'll soon find out.
     */
    {
	int i;

	for (i = getdtablesize() - 1; i >= 0; i--)  /* Bad hack */
	    if ((!log_to_stderr || i != 2)
#ifdef IPSECPOLICY
	    && i != info_fd
#endif
	    && i != ctl_fd)
		close(i);

	/* make sure that stdin, stdout, stderr are reserved */
	if (open("/dev/null", O_RDONLY) != 0)
	    osw_abort();
	if (dup2(0, 1) != 1)
	    osw_abort();
	if (!log_to_stderr && dup2(0, 2) != 2)
	    osw_abort();
    }

    init_constants();
    pluto_init_log();

#ifdef HAVE_LIBNSS
	char buf[100];
	snprintf(buf, sizeof(buf), "%s",oco->confddir);
	loglog(RC_LOG_SERIOUS,"nss directory plutomain: %s",buf);
	SECStatus nss_init_status= NSS_InitReadWrite(buf);
	if (nss_init_status != SECSuccess) {
	    loglog(RC_LOG_SERIOUS, "NSS initialization failed (err %d)\n", PR_GetError());
        exit_pluto(10);
	} else {
	    loglog(RC_LOG_SERIOUS, "NSS Initialized");
	    PK11_SetPasswordFunc(getNSSPassword);

#ifdef FIPS_CHECK
	const char *package_files[]= { IPSECLIBDIR"/setup",
				        IPSECLIBDIR"/addconn",
				        IPSECLIBDIR"/auto",
				        IPSECLIBDIR"/barf",
				        IPSECLIBDIR"/_copyright",
				        IPSECLIBDIR"/eroute",
  				        IPSECLIBDIR"/ikeping",
				        IPSECLIBDIR"/_include",
					IPSECLIBDIR"/_keycensor",
					IPSECLIBDIR"/klipsdebug",
					IPSECLIBDIR"/look",
					IPSECLIBDIR"/newhostkey",
					IPSECLIBDIR"/pf_key",
					IPSECLIBDIR"/_pluto_adns",
					IPSECLIBDIR"/_plutoload",
					IPSECLIBDIR"/_plutorun",
					IPSECLIBDIR"/ranbits",
					IPSECLIBDIR"/_realsetup",
					IPSECLIBDIR"/rsasigkey",
					IPSECLIBDIR"/pluto",
					IPSECLIBDIR"/_secretcensor",
					IPSECLIBDIR"/secrets",
					IPSECLIBDIR"/showdefaults",
					IPSECLIBDIR"/showhostkey",
					IPSECLIBDIR"/showpolicy",
					IPSECLIBDIR"/spi",
					IPSECLIBDIR"/spigrp",
					IPSECLIBDIR"/_startklips",
					IPSECLIBDIR"/_startnetkey",
					IPSECLIBDIR"/tncfg",
					IPSECLIBDIR"/_updown",
					IPSECLIBDIR"/_updown.klips",
					IPSECLIBDIR"/_updown.mast",
					IPSECLIBDIR"/_updown.netkey", 
					IPSECLIBDIR"/verify",
					IPSECLIBDIR"/whack",
					IPSECSBINDIR"/ipsec",
					NULL
					};

       if (Pluto_IsFIPS() && !FIPSCHECK_verify_files(package_files)) {
             loglog(RC_LOG_SERIOUS, "FIPS integrity verification test failed");
             exit_pluto(10);
        }
#endif

      }
#endif

    /* Note: some scripts may look for this exact message -- don't change
     * ipsec barf was one, but it no longer does.
     */
    {
	const char *vc = ipsec_version_code();
#ifdef PLUTO_SENDS_VENDORID
	const char *v = init_pluto_vendorid();
	openswan_log("Starting Pluto (Openswan Version %s%s; Vendor ID %s) pid:%u"
		     , vc, compile_time_interop_options, v, getpid());
#else
	openswan_log("Starting Pluto (Openswan Version %s%s) pid:%u"
		     , vc, compile_time_interop_options, getpid());
#endif
#ifdef HAVE_LIBNSS
	if(Pluto_IsFIPS()) {
		openswan_log("Pluto is running in FIPS mode");
	}
#endif

	if((vc[0]=='c' && vc[1]=='v' && vc[2]=='s') ||
	   (vc[2]=='g' && vc[3]=='i' && vc[4]=='t')) {
	    /*
	     * when people build RPMs from CVS or GIT, make sure they
	     * get blamed appropriately, and that we get some way to
	     * identify who did it, and when they did it. Use string concat,
	     * so that strings the binary can or classic SCCS "what", will find
	     * stuff too.
	     */
	    openswan_log("@(#) built on "__DATE__":" __TIME__ " by " BUILDER);
	}
#if defined(USE_1DES)
	openswan_log("WARNING: 1DES is enabled");
#endif
    }

    if(coredir) {
	openswan_log("core dump dir: %s", coredir);
    }

#ifdef LEAK_DETECTIVE
	openswan_log("LEAK_DETECTIVE support [enabled]");
#else
	openswan_log("LEAK_DETECTIVE support [disabled]");
#endif

#ifdef HAVE_OCF
       {
        struct stat buf;
	errno=0;

	if( stat("/dev/crypto",&buf) != -1) 
		openswan_log("OCF support for IKE via /dev/crypto [enabled]");
	else 
		openswan_log("OCF support for IKE via /dev/crypto [failed:%s]", strerror(errno));
       }
#else
	openswan_log("OCF support for IKE [disabled]");
#endif

   /* Check for SAREF support */
#ifdef KLIPS_MAST
#include <ipsec_saref.h>
    {
	int e, sk, saref;
	saref = 1;
	errno=0;

	sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	e = setsockopt(sk, IPPROTO_IP, IP_IPSEC_REFINFO, &saref, sizeof(saref));
	if (e == -1 ) {
		openswan_log("SAref support [disabled]: %s" , strerror(errno));
	}
	else {
		openswan_log("SAref support [enabled]");
	}
	errno=0;
	e = setsockopt(sk, IPPROTO_IP, IP_IPSEC_BINDREF, &saref, sizeof(saref));
	if (e == -1 ) {
		openswan_log("SAbind support [disabled]: %s" , strerror(errno));
	}
	else {
		openswan_log("SAbind support [enabled]");
	}


	close(sk);
    }
#endif

#ifdef HAVE_LIBNSS
	openswan_log("NSS support [enabled]");
#else
	openswan_log("NSS support [disabled]");
#endif

#ifdef HAVE_STATSD
	openswan_log("HAVE_STATSD notification via /bin/openswan-statsd enabled");
#else
	openswan_log("HAVE_STATSD notification support not compiled in");
#endif


/** Log various impair-* functions if they were enabled */

    if(DBGP(IMPAIR_BUST_MI2))
	openswan_log("Warning: IMPAIR_BUST_MI2 enabled");
    if(DBGP(IMPAIR_BUST_MR2))
	openswan_log("Warning: IMPAIR_BUST_MR2 enabled");
    if(DBGP(IMPAIR_SA_CREATION))
	openswan_log("Warning: IMPAIR_SA_CREATION enabled");
    if(DBGP(IMPAIR_JACOB_TWO_TWO))
	openswan_log("Warning: IMPAIR_JACOB_TWO_TWO enabled");
    if(DBGP(IMPAIR_DIE_ONINFO))
	openswan_log("Warning: IMPAIR_DIE_ONINFO enabled");
    if(DBGP(IMPAIR_DELAY_ADNS_KEY_ANSWER))
	openswan_log("Warning: IMPAIR_DELAY_ADNS_KEY_ANSWER enabled");
    if(DBGP(IMPAIR_DELAY_ADNS_TXT_ANSWER))
	openswan_log("Warning: IMPAIR_DELAY_ADNS_TXT_ANSWER enabled");

/** Initialize all of the various features */

#ifdef NAT_TRAVERSAL
    init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
#endif

    init_virtual_ip(virtual_private);
    init_rnd_pool();
    init_timer();
    init_secret();
    init_states();
    init_connections();
    init_crypto();
    init_crypto_helpers(nhelpers);
    load_oswcrypto();
    init_demux();
    init_kernel();
    init_adns();
    init_id();

#ifdef TPM
    init_tpm();
#endif

#ifdef HAVE_THREADS
    init_fetch();
#endif

    ocsp_set_default_uri(ocspuri);

    /* loading X.509 CA certificates */
    load_authcerts("CA cert", oco->cacerts_dir, AUTH_CA);
    /* loading X.509 AA certificates */
    load_authcerts("AA cert", oco->aacerts_dir, AUTH_AA);
    /* loading X.509 OCSP certificates */
    load_authcerts("OCSP cert", oco->ocspcerts_dir, AUTH_OCSP);

    /* loading X.509 CRLs */
    load_crls();
    /* loading attribute certificates (experimental) */
    load_acerts();

#ifdef HAVE_LIBNSS
    /*Loading CA certs from NSS DB*/
    load_authcerts_from_nss("CA cert",  AUTH_CA);
#endif

    daily_log_event();
    call_server();
    return -1;	/* Shouldn't ever reach this */
}
Example #13
0
void separation(const char* filename, double background_integral, double* stream_integrals)
{
    int q[ap->number_streams];
    double nstars[ap->number_streams];
    int total;
    double sprob[ap->number_streams];
    double prob_s[ap->number_streams];
    double prob_b;
    double pbx;
    double psg[ap->number_streams];
    double d;
    int twoPanel;
    double** cmatrix;
    double dnormal[3];
    double dortho[3];
    double xsun[3];
    double epsilon_s[ap->number_streams];
    double epsilon_b;
    double star_coords[3];
    double starxyz[3];
    double starxyzTransform[3];
    int s_ok = 0;
    int i, j, retval;
    FILE* file;
    double reff_xr_rp3, *qw_r3_N, *r_point;

    twoPanel = 1;
    for (j = 0; j < ap->number_streams; j++)
    {
        nstars[j] = 0;
        q[j] = 0;
    }
    total = 0;
    prob_ok_init();

    printf("Integral complete.\n Beginning probability calculations...\n");
    file = fopen(filename, "w");

    if (ap->sgr_coordinates == 0)
    {
        stripe_normal(ap->wedge, dnormal);
    }
    else if (ap->sgr_coordinates == 1)
    {
        sgr_stripe_normal(ap->wedge, dnormal);
    }
    else
    {
        printf("Error: ap->sgr_coordinates not valid");
    }

    free_star_points(sp);
    free(sp);
    sp = (STAR_POINTS*)malloc(sizeof(STAR_POINTS));
    retval = read_star_points(star_points_file, sp);
    if (retval)
    {
        fprintf(stderr, "APP: error reading star points: %d\n", retval);
        exit(1);
    }
    printf("read %d stars.\n", sp->number_stars);


    cmatrix = (double**)malloc(sizeof(double*) * 3);
    for (i = 0; i < 3; i++)
        cmatrix[i] = (double*)malloc(sizeof(double) * 3);
    dortho[0] = 0.0;
    dortho[1] = 0.0;
    dortho[2] = 1.0;
    get_transform(dnormal, dortho, cmatrix);

    printf("\nTransformation matrix:\n");
    printf("\t%lf %lf %lf\n", cmatrix[0][0], cmatrix[0][1], cmatrix[0][2]);
    printf("\t%lf %lf %lf\n", cmatrix[1][0], cmatrix[1][1], cmatrix[1][2]);
    printf("\t%lf %lf %lf\n\n", cmatrix[2][0], cmatrix[2][1], cmatrix[2][2]);

    xsun[0] = -8.5;
    xsun[1] = 0.0;
    xsun[2] = 0.0;
    d = dotp(dnormal, xsun);

    printf("==============================================\n");
    printf("bint: %lf", background_integral);
    for (j = 0; j < ap->number_streams; j++)
    {
        printf(", ");
        printf("sint[%d]: %lf", j, stream_integrals[j]);
    }
    printf("\n");

    /*get stream & background weight constants*/
    double denom = 1.0;
    for (j = 0; j < ap->number_streams; j++)
    {
        denom += exp(ap->stream_weights[j]);
    }

    for (j = 0; j < ap->number_streams; j++)
    {
        epsilon_s[j] = exp(ap->stream_weights[j]) / denom;
        printf("epsilon_s[%d]: %lf\n", j, epsilon_s[j]);
    }
    epsilon_b = 1.0 / denom;
    printf("epsilon_b:    %lf\n", epsilon_b);

    r_point = (double*)malloc(sizeof(double) * ap->convolve);
    qw_r3_N = (double*)malloc(sizeof(double) * ap->convolve);

    init_constants(ap);

    printf("initialized constants\n");

    for (i = 0; i < sp->number_stars; i++)
    {
        MW_DEBUG("[%d/%d] setting star coords\n", i, sp->number_stars);
        star_coords[0] = sp->stars[i][0];
        star_coords[1] = sp->stars[i][1];
        star_coords[2] = sp->stars[i][2];
        MW_DEBUG("star_coords: %g %g %g\n", star_coords[0], star_coords[1], star_coords[2]);

        MW_DEBUG("twoPanel: %d\n", twoPanel);

        if (twoPanel == 1)
        {
            MW_DEBUG("setting probability constants\n");
            set_probability_constants(ap->convolve, star_coords[2], r_point, qw_r3_N, &reff_xr_rp3);
            MW_DEBUG("calculating probabilities\n");
            calculate_probabilities(r_point, qw_r3_N, reff_xr_rp3, star_coords, ap, &prob_b, prob_s);
            MW_DEBUG("calculated probabilities\n");

            MW_DEBUG("prob_s: %lf\n", prob_s[0]);
            MW_DEBU("prob_b: %lf\n", prob_b);

            pbx = epsilon_b * prob_b / background_integral;

            for (j = 0; j < ap->number_streams; j++)
            {
                psg[j] = epsilon_s[j] * prob_s[j] / stream_integrals[j];
            }

            MW_DEBUG("pbx: %g\n", pbx);
            MW_DEBUG("psg: %g\n", psg[0]);

            double psgSum = 0;
            for (j = 0; j < ap->number_streams; j++)
            {
                psgSum += psg[j];
            }

            for (j = 0; j < ap->number_streams; j++)
            {
                sprob[j] = psg[j] / (psgSum + pbx);
            }

            MW_DEBUG("sprob: %g\n", sprob[0]);

            for (j = 0; j < ap->number_streams; j++)
            {
                nstars[j] += sprob[j];
            }

            MW_DEBUG("nstars: %g\n", nstars[0]);
        }
        else
        {
            for (j = 0; j < ap->number_streams; j++)
            {
                sprob[j] = 1.0;
                nstars[j] += 1.0;
            }
        }


        /*determine if star with sprob should be put into stream*/
        //for(j = 0; j < ap->number_streams; j++) {
        s_ok = prob_ok(ap->number_streams, sprob);
        //  if (s_ok == 1) {
        //      s_ok += j;
        //      break;
        //  }
        //}

        MW_DEBUG("s_ok: %d\n", s_ok);

        if (s_ok >= 1)
        {
            q[s_ok-1]++;
        }

        lbr2xyz(star_coords, starxyz);
        transform_point(starxyz, cmatrix, xsun, starxyzTransform);

        fprintf(file, "%d %lf %lf %lf\n", s_ok, starxyzTransform[0], starxyzTransform[1], starxyzTransform[2]);
        //free(starxyz);
        //free(starxyzTransform);

        total += 1;

        if ( (total % 10000) == 0 )
            printf("%d\n", total);
    }

    printf("%d total stars\n", total);
    for (j = 0; j < ap->number_streams; j++)
    {
        printf("%lf in stream[%d] (%lf%%)\n", nstars[j], j, (nstars[j] / total * 100));
    }

    for (j = 0; j < ap->number_streams; j++)
    {
        printf("%d stars separated into stream\n", q[j]);
    }
    fclose(file);
    printf("Output written to: %s\n", filename);
    free(r_point);
    free(qw_r3_N);
    free_constants(ap);
}
Example #14
0
int main(int argc, char **argv)
{
	bool fork_desired = TRUE;
	bool log_to_stderr_desired = FALSE;
	bool nat_traversal = FALSE;
	bool nat_t_spf = TRUE;  /* support port floating */
	unsigned int keep_alive = 0;
	bool force_keepalive = FALSE;
	char *virtual_private = NULL;
	int lockfd;
#ifdef CAPABILITIES
	cap_t caps;
	int keep[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE };
#endif /* CAPABILITIES */

	/* initialize library and optionsfrom */
	if (!library_init(NULL))
	{
		library_deinit();
		exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
	}
	if (!libhydra_init("pluto"))
	{
		libhydra_deinit();
		library_deinit();
		exit(SS_RC_INITIALIZATION_FAILED);
	}
	if (!pluto_init(argv[0]))
	{
		pluto_deinit();
		libhydra_deinit();
		library_deinit();
		exit(SS_RC_DAEMON_INTEGRITY);
	}
	options = options_create();

	ha_mcast_addr.s_addr = inet_addr(SA_SYNC_MULTICAST);

	/* handle arguments */
	for (;;)
	{
#       define DBG_OFFSET 256
		static const struct option long_opts[] = {
			/* name, has_arg, flag, val */
			{ "help", no_argument, NULL, 'h' },
			{ "version", no_argument, NULL, 'v' },
			{ "optionsfrom", required_argument, NULL, '+' },
			{ "nofork", no_argument, NULL, 'd' },
			{ "stderrlog", no_argument, NULL, 'e' },
			{ "noklips", no_argument, NULL, 'n' },
			{ "nocrsend", no_argument, NULL, 'c' },
			{ "strictcrlpolicy", no_argument, NULL, 'r' },
			{ "crlcheckinterval", required_argument, NULL, 'x'},
			{ "cachecrls", no_argument, NULL, 'C' },
			{ "probe-psk", no_argument, NULL, 'o' },
			{ "uniqueids", no_argument, NULL, 'u' },
			{ "interface", required_argument, NULL, 'i' },
			{ "ha_interface", required_argument, NULL, 'H' },
			{ "ha_multicast", required_argument, NULL, 'M' },
			{ "ha_vips", required_argument, NULL, 'V' },
			{ "ha_seqdiff_in", required_argument, NULL, 'S' },
			{ "ha_seqdiff_out", required_argument, NULL, 'O' },
			{ "ikeport", required_argument, NULL, 'p' },
			{ "ctlbase", required_argument, NULL, 'b' },
			{ "secretsfile", required_argument, NULL, 's' },
			{ "foodgroupsdir", required_argument, NULL, 'f' },
			{ "perpeerlogbase", required_argument, NULL, 'P' },
			{ "perpeerlog", no_argument, NULL, 'l' },
			{ "policygroupsdir", required_argument, NULL, 'f' },
#ifdef USE_LWRES
			{ "lwdnsq", required_argument, NULL, 'a' },
#else /* !USE_LWRES */
			{ "adns", required_argument, NULL, 'a' },
#endif /* !USE_LWRES */
			{ "pkcs11module", required_argument, NULL, 'm' },
			{ "pkcs11keepstate", no_argument, NULL, 'k' },
			{ "pkcs11initargs", required_argument, NULL, 'z' },
			{ "pkcs11proxy", no_argument, NULL, 'y' },
			{ "nat_traversal", no_argument, NULL, '1' },
			{ "keep_alive", required_argument, NULL, '2' },
			{ "force_keepalive", no_argument, NULL, '3' },
			{ "disable_port_floating", no_argument, NULL, '4' },
			{ "debug-natt", no_argument, NULL, '5' },
			{ "virtual_private", required_argument, NULL, '6' },
#ifdef DEBUG
			{ "debug-none", no_argument, NULL, 'N' },
			{ "debug-all", no_argument, NULL, 'A' },
			{ "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },
			{ "debug-crypt", no_argument, NULL, DBG_CRYPT + DBG_OFFSET },
			{ "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
			{ "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET },
			{ "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET },
			{ "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET },
			{ "debug-klips", no_argument, NULL, DBG_KLIPS + DBG_OFFSET },
			{ "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET },
			{ "debug-oppo", no_argument, NULL, DBG_OPPO + DBG_OFFSET },
			{ "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET },
			{ "debug-ha", no_argument, NULL, DBG_HA + DBG_OFFSET },
			{ "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },

			{ "impair-delay-adns-key-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_KEY_ANSWER + DBG_OFFSET },
			{ "impair-delay-adns-txt-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_TXT_ANSWER + DBG_OFFSET },
			{ "impair-bust-mi2", no_argument, NULL, IMPAIR_BUST_MI2 + DBG_OFFSET },
			{ "impair-bust-mr2", no_argument, NULL, IMPAIR_BUST_MR2 + DBG_OFFSET },
#endif
			{ 0,0,0,0 }
			};
		/* Note: we don't like the way short options get parsed
		 * by getopt_long, so we simply pass an empty string as
		 * the list.  It could be "hvdenp:l:s:" "NARXPECK".
		 */
		int c = getopt_long(argc, argv, "", long_opts, NULL);

		/* Note: "breaking" from case terminates loop */
		switch (c)
		{
		case EOF:       /* end of flags */
			break;

		case 0: /* long option already handled */
			continue;

		case ':':       /* diagnostic already printed by getopt_long */
		case '?':       /* diagnostic already printed by getopt_long */
			usage("");
			break;   /* not actually reached */

		case 'h':       /* --help */
			usage(NULL);
			break;      /* not actually reached */

		case 'v':       /* --version */
			{
				const char **sp = ipsec_copyright_notice();

				printf("strongSwan "VERSION"%s\n", compile_time_interop_options);
				for (; *sp != NULL; sp++)
					puts(*sp);
			}
			exit_pluto(0);
			break;      /* not actually reached */

		case '+':       /* --optionsfrom <filename> */
			if (!options->from(options, optarg, &argc, &argv, optind))
			{
				exit_pluto(1);
			}
			continue;

		case 'd':       /* --nofork*/
			fork_desired = FALSE;
			continue;

		case 'e':       /* --stderrlog */
			log_to_stderr_desired = TRUE;
			continue;

		case 'n':       /* --noklips */
			no_klips = TRUE;
			continue;

		case 'c':       /* --nocrsend */
			no_cr_send = TRUE;
			continue;

		case 'r':       /* --strictcrlpolicy */
			strict_crl_policy = TRUE;
			continue;

		case 'x':       /* --crlcheckinterval <time>*/
			if (optarg == NULL || !isdigit(optarg[0]))
				usage("missing interval time");

			{
				char *endptr;
				long interval = strtol(optarg, &endptr, 0);

				if (*endptr != '\0' || endptr == optarg
				|| interval <= 0)
					usage("<interval-time> must be a positive number");
				crl_check_interval = interval;
			}
			continue;

		case 'C':       /* --cachecrls */
			cache_crls = TRUE;
			continue;

		case 'o':       /* --probe-psk */
			probe_psk = TRUE;
			continue;

		case 'u':       /* --uniqueids */
			uniqueIDs = TRUE;
			continue;

		case 'i':       /* --interface <ifname> */
			if (!use_interface(optarg))
				usage("too many --interface specifications");
			continue;

		case 'H':       /* --ha_interface <ifname> */
			if (optarg && strcmp(optarg, "none") != 0)
				ha_interface = optarg;
			continue;

		case 'M':	/* --ha_multicast <ip> */
			ha_mcast_addr.s_addr = inet_addr(optarg);
			if (ha_mcast_addr.s_addr == INADDR_NONE ||
				(((unsigned char *) &ha_mcast_addr.s_addr)[0] & 0xF0) != 0xE0)
				ha_mcast_addr.s_addr = inet_addr(SA_SYNC_MULTICAST);
			continue;

		case 'V':	/* --ha_vips <ip addresses> */
			if(add_ha_vips(optarg))
				usage("misconfigured ha_vip addresses");
			continue;

		case 'S':	/* --ha_seqdiff_in <diff> */
			ha_seqdiff_in = strtoul(optarg, NULL, 0);
			continue;

		case 'O':       /* --ha_seqdiff_out <diff> */
			ha_seqdiff_out = strtoul(optarg, NULL, 0);
			continue;

		case 'p':       /* --port <portnumber> */
			if (optarg == NULL || !isdigit(optarg[0]))
				usage("missing port number");

			{
				char *endptr;
				long port = strtol(optarg, &endptr, 0);

				if (*endptr != '\0' || endptr == optarg
				|| port <= 0 || port > 0x10000)
					usage("<port-number> must be a number between 1 and 65535");
				pluto_port = port;
			}
			continue;

		case 'b':       /* --ctlbase <path> */
			if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
			, "%s%s", optarg, CTL_SUFFIX) == -1)
				usage("<path>" CTL_SUFFIX " too long for sun_path");
			if (snprintf(info_addr.sun_path, sizeof(info_addr.sun_path)
			, "%s%s", optarg, INFO_SUFFIX) == -1)
				usage("<path>" INFO_SUFFIX " too long for sun_path");
			if (snprintf(pluto_lock, sizeof(pluto_lock)
			, "%s%s", optarg, LOCK_SUFFIX) == -1)
				usage("<path>" LOCK_SUFFIX " must fit");
			continue;

		case 's':       /* --secretsfile <secrets-file> */
			shared_secrets_file = optarg;
			continue;

		case 'f':       /* --policygroupsdir <policygroups-dir> */
			policygroups_dir = optarg;
			continue;

		case 'a':       /* --adns <pathname> */
			pluto_adns_option = optarg;
			continue;

		case 'm':       /* --pkcs11module <pathname> */
			pkcs11_module_path = optarg;
			continue;

		case 'k':       /* --pkcs11keepstate */
			pkcs11_keep_state = TRUE;
			continue;

		case 'y':       /* --pkcs11proxy */
			pkcs11_proxy = TRUE;
			continue;

		case 'z':       /* --pkcs11initargs */
			pkcs11_init_args = optarg;
			continue;

#ifdef DEBUG
		case 'N':       /* --debug-none */
			base_debugging = DBG_NONE;
			continue;

		case 'A':       /* --debug-all */
			base_debugging = DBG_ALL;
			continue;
#endif

		case 'P':       /* --perpeerlogbase */
			base_perpeer_logdir = optarg;
			continue;

		case 'l':
			log_to_perpeer = TRUE;
			continue;

		case '1':       /* --nat_traversal */
			nat_traversal = TRUE;
			continue;
		case '2':       /* --keep_alive */
			keep_alive = atoi(optarg);
			continue;
		case '3':       /* --force_keepalive */
			force_keepalive = TRUE;
			continue;
		case '4':       /* --disable_port_floating */
			nat_t_spf = FALSE;
			continue;
		case '5':       /* --debug-nat_t */
			base_debugging |= DBG_NATT;
			continue;
		case '6':       /* --virtual_private */
			virtual_private = optarg;
			continue;

		default:
#ifdef DEBUG
			if (c >= DBG_OFFSET)
			{
				base_debugging |= c - DBG_OFFSET;
				continue;
			}
#       undef DBG_OFFSET
#endif
			bad_case(c);
		}
		break;
	}
	if (optind != argc)
		usage("unexpected argument");
	reset_debugging();
	lockfd = create_lock();

	/* select between logging methods */

	if (log_to_stderr_desired)
	{
		log_to_syslog = FALSE;
	}
	else
	{
		log_to_stderr = FALSE;
	}

	/* set the logging function of pfkey debugging */
#ifdef DEBUG
	pfkey_debug_func = DBG_log;
#else
	pfkey_debug_func = NULL;
#endif

	/* create control socket.
	 * We must create it before the parent process returns so that
	 * there will be no race condition in using it.  The easiest
	 * place to do this is before the daemon fork.
	 */
	{
		err_t ugh = init_ctl_socket();

		if (ugh != NULL)
		{
			fprintf(stderr, "pluto: %s", ugh);
			exit_pluto(1);
		}
	}

	/* If not suppressed, do daemon fork */

	if (fork_desired)
	{
		{
			pid_t pid = fork();

			if (pid < 0)
			{
				int e = errno;

				fprintf(stderr, "pluto: fork failed (%d %s)\n",
					errno, strerror(e));
				exit_pluto(1);
			}

			if (pid != 0)
			{
				/* parent: die, after filling PID into lock file.
				 * must not use exit_pluto: lock would be removed!
				 */
				exit(fill_lock(lockfd, pid)? 0 : 1);
			}
		}

		if (setsid() < 0)
		{
			int e = errno;

			fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",
				errno, strerror(e));
			exit_pluto(1);
		}
	}
	else
	{
		/* no daemon fork: we have to fill in lock file */
		(void) fill_lock(lockfd, getpid());
		fprintf(stdout, "Pluto initialized\n");
		fflush(stdout);
	}

	/* Close everything but ctl_fd and (if needed) stderr.
	 * There is some danger that a library that we don't know
	 * about is using some fd that we don't know about.
	 * I guess we'll soon find out.
	 */
	{
		int i;

		for (i = getdtablesize() - 1; i >= 0; i--)  /* Bad hack */
		{
			if ((!log_to_stderr || i != 2) && i != ctl_fd)
				close(i);
		}

		/* make sure that stdin, stdout, stderr are reserved */
		if (open("/dev/null", O_RDONLY) != 0)
			abort();
		if (dup2(0, 1) != 1)
			abort();
		if (!log_to_stderr && dup2(0, 2) != 2)
			abort();
	}

	init_constants();
	init_log("pluto");

	/* Note: some scripts may look for this exact message -- don't change
	 * ipsec barf was one, but it no longer does.
	 */
	plog("Starting IKEv1 pluto daemon (strongSwan "VERSION")%s",
		 compile_time_interop_options);

	if (lib->integrity)
	{
		plog("integrity tests enabled:");
		plog("lib    'libstrongswan': passed file and segment integrity tests");
		plog("lib    'libhydra': passed file and segment integrity tests");
		plog("daemon 'pluto': passed file integrity test");
	}

	/* load plugins, further infrastructure may need it */
	if (!lib->plugins->load(lib->plugins, NULL,
			lib->settings->get_str(lib->settings, "pluto.load", PLUGINS)))
	{
		exit(SS_RC_INITIALIZATION_FAILED);
	}
	print_plugins();

	init_builder();
	if (!init_secret() || !init_crypto())
	{
		plog("initialization failed - aborting pluto");
		exit_pluto(SS_RC_INITIALIZATION_FAILED);
	}
	init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
	init_virtual_ip(virtual_private);
	scx_init(pkcs11_module_path, pkcs11_init_args);
	init_states();
	init_demux();
	init_kernel();
	init_adns();
	init_myid();
	fetch_initialize();
	ac_initialize();
	whack_attribute_initialize();

	/* HA System: set sequence number delta and open HA interface */
	if (ha_interface != NULL)
	{
		int version;

		if (kernel_ops->type == KERNEL_TYPE_LINUX
		&& (version = xfrm_aevent_version()) != XFRM_AEVENT_VERSION)
		{
			if (version == 0)
				plog("HA system: XFRM sequence number updates only "
				     "supported with kernel version 2.6.17 and later.");
			else if (version == -1)
				plog("HA system: error reading kernel version. "
				     "Sequence number updates disabled.");
			else
				plog("HA system: Strongswan compiled for wrong kernel "
				     "AEVENT version! Please set XFRM_AEVENT_VERSION "
				     "to %d in src/include/linux/xfrm.h", version);

			ha_seqdiff_in = 0;
			ha_seqdiff_out = 0;
		}
		else
		{
			FILE *etime = fopen("/proc/sys/net/core/xfrm_aevent_etime", "w");
			FILE *rseqth = fopen("/proc/sys/net/core/xfrm_aevent_rseqth", "w");

			if (etime == NULL || rseqth == NULL)
			{
				plog("HA System: no sequence number support in Kernel! "
					"Please use at least kernel 2.6.17.");
				ha_seqdiff_in = 0;
				ha_seqdiff_out = 0;
			}
			else
			{
				/*
				 * Disable etime (otherwise set to a multiple of 100ms,
				 * e.g. 300 for 30 seconds). Using ha_seqdiff_out.
				 */
				fprintf(etime, "0");
				fprintf(rseqth, "%d", ha_seqdiff_out);
			}

			fclose(etime);
			fclose(rseqth);
		}

		if (open_ha_iface() >= 0)
		{
			plog("HA system enabled and listening on interface %s", ha_interface);
			if (access("/var/master", F_OK) == 0)
			{
				plog("Initial HA switch to master mode");
				ha_master = 1;
				event_schedule(EVENT_SA_SYNC_UPDATE, 30, NULL);
			}
		}
		else
		{
			plog("HA system failed to listen on interface %s. "
			     "HA system disabled.", ha_interface);
			ha_interface = NULL;
		}
	}

	/* drop unneeded capabilities and change UID/GID */
	prctl(PR_SET_KEEPCAPS, 1);

#ifdef IPSEC_GROUP
	{
		struct group group, *grp;
	char buf[1024];

		if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) != 0 ||
				grp == NULL || setgid(grp->gr_gid) != 0)
		{
			plog("unable to change daemon group");
			abort();
		}
	}
#endif
#ifdef IPSEC_USER
	{
		struct passwd passwd, *pwp;
	char buf[1024];

		if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) != 0 ||
				pwp == NULL || setuid(pwp->pw_uid) != 0)
		{
			plog("unable to change daemon user");
			abort();
		}
		}
#endif

#ifdef CAPABILITIES
	caps = cap_init();
	cap_set_flag(caps, CAP_EFFECTIVE, 2, keep, CAP_SET);
	cap_set_flag(caps, CAP_INHERITABLE, 2, keep, CAP_SET);
	cap_set_flag(caps, CAP_PERMITTED, 2, keep, CAP_SET);
	if (cap_set_proc(caps) != 0)
	{
		plog("unable to drop daemon capabilities");
		abort();
	}
	cap_free(caps);
#endif /* CAPABILITIES */

	/* loading X.509 CA certificates */
	load_authcerts("ca", CA_CERT_PATH, X509_CA);
	/* loading X.509 AA certificates */
	load_authcerts("aa", AA_CERT_PATH, X509_AA);
	/* loading X.509 OCSP certificates */
	load_authcerts("ocsp", OCSP_CERT_PATH, X509_OCSP_SIGNER);
	/* loading X.509 CRLs */
	load_crls();
	/* loading attribute certificates (experimental) */
	ac_load_certs();

	daily_log_event();
	call_server();
	return -1;  /* Shouldn't ever reach this */
}
static void worker(int argc, const char** argv)
{
    double* parameters;
    int ret1, ret2;
    int number_parameters, ap_number_parameters;
    ASTRONOMY_PARAMETERS ap = { 0 };
    STAR_POINTS sp = { 0 };
    EVALUATION_STATE es = { 0 };

    parameters = parse_parameters(argc, argv, &number_parameters);

    if (!parameters)
    {
        fprintf(stderr, "Could not parse parameters from the command line\n");
        mw_finish(EXIT_FAILURE);
    }

    ret1 = read_astronomy_parameters(astronomy_parameter_file, &ap);
    ret2 = read_star_points(star_points_file, &sp);

    MW_DEBUG("ap.number_stream_parameters = %d\n", ap.number_stream_parameters);

    if (ret1)
    {
        fprintf(stderr,
                "APP: error reading astronomy parameters from file %s: %d\n",
                astronomy_parameter_file,
                ret1);
    }

    if (ret2)
    {
        fprintf(stderr,
                "APP: error reading star points from file %s: %d\n",
                star_points_file,
                ret2);
    }

    if (ret1 | ret2)
    {
        free(parameters);
        cleanup_worker();
		mw_finish(EXIT_FAILURE);
    }

    initialize_state(&ap, &sp, &es);

    ap_number_parameters = get_optimized_parameter_count(&ap);

    if (number_parameters < 1 || number_parameters != ap_number_parameters)
    {
        fprintf(stderr,
                "Error reading parameters: number of parameters from the "
                "command line (%d) does not match the number of parameters "
                "to be optimized in %s (%d)\n",
                number_parameters,
                astronomy_parameter_file,
                ap_number_parameters);

        free(parameters);
        cleanup_worker();
        mw_finish(EXIT_FAILURE);
    }

    set_astronomy_parameters(&ap, parameters);

#if COMPUTE_ON_CPU
    init_constants(&ap);
    init_simple_evaluator(cpu_evaluate);
#elif USE_CUDA
    init_constants(&ap);
    init_simple_evaluator(cuda_evaluate);
#elif USE_OCL
    init_constants(&ap);
    init_simple_evaluator(ocl_evaluate);
#else
    #error "Must choose CUDA, OpenCL or CPU"
#endif /* COMPUTE_ON_CPU */

    /* CHECKME: What is this magic 3.0, and why was it being
     * subtracted from CPU and CUDA result, but not OpenCL? */
    double likelihood = evaluate(parameters, &ap, &es, &sp) - 3.0;

    fprintf(stderr, "<search_likelihood> %0.20f </search_likelihood>\n", likelihood);
    fprintf(stderr, "<search_application> %s %s </search_application>\n", BOINC_APP_VERSION, PRECISION);

    free(parameters);
	cleanup_worker();

    mw_finish(EXIT_SUCCESS);

}
Example #16
0
//
// GPU calculation: given a vector ptext of plain text words, compute and
// return their MD5 hashes
//
int cuda_compute_md5s(std::vector<md5hash> &hashes, const std::vector<std::string> &ptext)
{

	// pad dictionary words to 64 bytes (MD5 block size)
	std::valarray<char> paddedWords;
	md5_prep_array(paddedWords, ptext);

	uint *gpuWords, *gpuHashes = NULL;

	double gpuTime = 0.;

	int dynShmemPerThread = 64;	// built in the algorithm

	uint n = ptext.size(), tpb;	// n is number of message words, and tpb is number of threads per block

	int gridDim[3];

	// load the MD5 constant arrays into GPU constant memory
	init_constants();

	hashes.resize(n);

	/**
	 * 8 is the max length of a single message word (00000000~99999999),
	 * and as for 16, everybody knows.
	 */
#define CHUNK_NUM 100
	if (n * (8 + 16) < GLOBAL_MEMORY_CAPACITY)
	{
		printf ("Global Memory is still enough!\n");

		// Upload the dictionary onto the GPU device
		cudaMalloc((void **)&gpuWords, paddedWords.size());
		cudaMemcpy(gpuWords, &paddedWords[0], paddedWords.size(), cudaMemcpyHostToDevice);

		// allocate GPU memory for computed hashes
		cudaMalloc((void **)&gpuHashes, n * 4 * sizeof(uint));

		tpb = 100;
		gridDim[0] = (n + tpb - 1) / tpb, gridDim[1] = 1, gridDim[2] = 1;

		// Call the kernel niters times and calculate the average running time
		for (int k = 0; k != niters; k++)
		{
			gpuTime += gpu_execute_kernel(gridDim[0], gridDim[1], tpb, tpb * dynShmemPerThread, n, gpuWords, gpuHashes);
		}
		gpuTime /= niters;
		// Download the computed hashes
		cudaMemcpy(&hashes.front(), gpuHashes, n * 4 * sizeof(uint), cudaMemcpyDeviceToHost);
	} 
	else
	{
		printf ("Global Memory is limited!\n");

		double localTime = 0.;
		uint pChunkSize = (paddedWords.size() + CHUNK_NUM - 1) / CHUNK_NUM;
		uint nChunkSize = (n + CHUNK_NUM - 1) / CHUNK_NUM;

		tpb = 100;
		gridDim[0] = (nChunkSize + tpb - 1) / tpb, gridDim[1] = 1, gridDim[2] = 1;

		cudaMalloc ((void **)&gpuWords, pChunkSize);
		cudaMalloc ((void **)&gpuHashes, nChunkSize * 4 * sizeof (uint));
		for (uint i = 0; i < CHUNK_NUM; i++)
		{
			cudaMemcpy (gpuWords, &paddedWords[i * pChunkSize], pChunkSize, cudaMemcpyHostToDevice);

			localTime = 0.;
			for (int k = 0; k != niters; k++)
			{
				localTime += gpu_execute_kernel(gridDim[0], gridDim[1], tpb, tpb * dynShmemPerThread, nChunkSize, gpuWords, gpuHashes);
			}
			localTime /= niters;

			gpuTime += localTime;

			cudaMemcpy((uint *)(&hashes.front()) + i * nChunkSize * 4, gpuHashes, nChunkSize * 4 * sizeof(uint), cudaMemcpyDeviceToHost);

		}
	}

	// Shutdown
	cudaFree(gpuWords);
	cudaFree(gpuHashes);

#undef CHUNK_NUM

	std::cerr << "GPU MD5 time : " <<  gpuTime << "ms\n";


	return 0;
}
Example #17
0
int
main(int argc_orig, char **argv)
#endif
{
    int i;

    /* We want the current value of argc to persist across a LONGJMP from int_error().
     * Without this the compiler may put it on the stack, which LONGJMP clobbers.
     * Here we try make it a volatile variable that optimization will not affect.
     * Why do we not have to do the same for argv?   I don't know.
     * But the test cases that broke with generic argc seem fine with generic argv.
     */
    static volatile int argc;
    argc = argc_orig;

#ifdef LINUXVGA
    LINUX_setup();		/* setup VGA before dropping privilege DBT 4/5/99 */
    drop_privilege();
#endif
/* make sure that we really have revoked root access, this might happen if
   gnuplot is compiled without vga support but is installed suid by mistake */
#ifdef __linux__
    if (setuid(getuid()) != 0) {
	fprintf(stderr,"gnuplot: refusing to run at elevated privilege\n");
	exit(EXIT_FAILURE);
    }
#endif

/* HBB: Seems this isn't needed any more for DJGPP V2? */
/* HBB: disable all floating point exceptions, just keep running... */
#if defined(DJGPP) && (DJGPP!=2)
    _control87(MCW_EM, MCW_EM);
#endif

#if defined(OS2)
    {
	int rc;
#ifdef OS2_IPC
	char semInputReadyName[40];

	sprintf(semInputReadyName, "\\SEM32\\GP%i_Input_Ready", getpid());
	rc = DosCreateEventSem(semInputReadyName, &semInputReady, 0, 0);
	if (rc != 0)
	    fputs("DosCreateEventSem error\n", stderr);
#endif
	rc = RexxRegisterSubcomExe("GNUPLOT", (PFN) RexxInterface, NULL);
    }
#endif

/* malloc large blocks, otherwise problems with fragmented mem */
#ifdef MALLOCDEBUG
    malloc_debug(7);
#endif


/* init progpath and get helpfile from executable directory */
#if defined(MSDOS) || defined(OS2)
    {
	char *s;

#ifdef __EMX__
	_execname(progpath, sizeof(progpath));
#else
	safe_strncpy(progpath, argv[0], sizeof(progpath));
#endif
	/* convert '/' to '\\' */
	for (s = progpath; *s != NUL; s++)
	    if (*s == DIRSEP2)
		*s = DIRSEP1;
	/* cut program name */
	s = strrchr(progpath, DIRSEP1);
	if (s != NULL)
	    s++;
	else
	    s = progpath;
	*s = NUL;
	/* init HelpFile */
	strcpy(HelpFile, progpath);
	strcat(HelpFile, "gnuplot.gih");
	/* remove trailing "bin/" from progpath */
	if ((s != NULL) && (s - progpath >= 4)) {
	    s -= 4;
	    if (strncasecmp(s, "bin", 3) == 0)
		*s = NUL;
	}
    }
#endif /* DJGPP */

#if (defined(PIPE_IPC) || defined(_WIN32)) && (defined(HAVE_LIBREADLINE) || (defined(HAVE_LIBEDITLINE) && defined(X11)))
    /* Editline needs this to be set before the very first call to readline(). */
    /* Support for rl_getc_function is broken for utf-8 in editline. Since it is only
       really required for X11, disable this section when building without X11. */
    rl_getc_function = getc_wrapper;
#endif

#if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDITLINE)
    /* T.Walter 1999-06-24: 'rl_readline_name' must be this fix name.
     * It is used to parse a 'gnuplot' specific section in '~/.inputrc'
     * or gnuplot specific commands in '.editrc' (when using editline
     * instead of readline) */
    rl_readline_name = "Gnuplot";
    rl_terminal_name = getenv("TERM");
#if defined(HAVE_LIBREADLINE)
    using_history();
#else
    history_init();
#endif
#endif
#if defined(HAVE_LIBREADLINE) && !defined(MISSING_RL_TILDE_EXPANSION)
    rl_complete_with_tilde_expansion = 1;
#endif

    for (i = 1; i < argc; i++) {
	if (!argv[i])
	    continue;

	if (!strcmp(argv[i], "-V") || !strcmp(argv[i], "--version")) {
	    printf("gnuplot %s patchlevel %s\n",
		    gnuplot_version, gnuplot_patchlevel);
	    return 0;

	} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
	    printf( "Usage: gnuplot [OPTION] ... [FILE]\n"
#ifdef X11
		    "for X11 options see 'help X11->command-line-options'\n"
#endif
		    "  -V, --version\n"
		    "  -h, --help\n"
		    "  -p  --persist\n"
		    "  -s  --slow\n"
		    "  -d  --default-settings\n"
		    "  -c  scriptfile ARG1 ARG2 ... \n"
		    "  -e  \"command1; command2; ...\"\n"
		    "gnuplot %s patchlevel %s\n",
		    gnuplot_version, gnuplot_patchlevel);
#ifdef DEVELOPMENT_VERSION
	    printf(
#ifdef DIST_CONTACT
		    "Report bugs to "DIST_CONTACT"\n"
		    "            or %s\n",
#else
		    "Report bugs to %s\n",
#endif
		    bug_email);
#endif
	    return 0;

	} else if (!strncmp(argv[i], "-persist", 2) || !strcmp(argv[i], "--persist")
#ifdef _WIN32
		|| !stricmp(argv[i], "-noend") || !stricmp(argv[i], "/noend")
#endif
		) {
	    persist_cl = TRUE;
	} else if (!strncmp(argv[i], "-slow", 2) || !strcmp(argv[i], "--slow")) {
	    slow_font_startup = TRUE;
	} else if (!strncmp(argv[i], "-d", 2) || !strcmp(argv[i], "--default-settings")) {
	    /* Skip local customization read from ~/.gnuplot */
	    skip_gnuplotrc = TRUE;
	}
    }

#ifdef X11
    /* the X11 terminal removes tokens that it recognizes from argv. */
    {
	int n = X11_args(argc, argv);
	argv += n;
	argc -= n;
    }
#endif

    setbuf(stderr, (char *) NULL);

#ifdef HAVE_SETVBUF
    /* This was once setlinebuf(). Docs say this is
     * identical to setvbuf(,NULL,_IOLBF,0), but MS C
     * faults this (size out of range), so we try with
     * size of 1024 instead. [SAS/C does that, too. -lh]
     */
    if (setvbuf(stdout, (char *) NULL, _IOLBF, (size_t) 1024) != 0)
	(void) fputs("Could not linebuffer stdout\n", stderr);

    /* Switching to unbuffered mode causes all characters in the input
     * buffer to be lost. So the only safe time to do it is on program entry.
     * Do any non-X platforms suffer from this problem?
     * EAM - Jan 2013 YES.
     */
    setvbuf(stdin, (char *) NULL, _IONBF, 0);
#endif

    gpoutfile = stdout;

    /* Initialize pre-loaded user variables */
    /* "pi" is hard-wired as the first variable */
    (void) add_udv_by_name("GNUTERM");
    (void) add_udv_by_name("NaN");
    init_constants();
    udv_user_head = &(udv_NaN->next_udv);

    init_memory();

    interactive = FALSE;

    /* April 2017:  We used to call init_terminal() here, but now   */
    /* We defer initialization until error handling has been set up. */

# if defined(_WIN32) && !defined(WGP_CONSOLE)
    interactive = TRUE;
# else
    interactive = isatty(fileno(stdin));
# endif

    /* Note: we want to know whether this is an interactive session so that we can
     * decide whether or not to write status information to stderr.  The old test
     * for this was to see if (argc > 1) but the addition of optional command line
     * switches broke this.  What we really wanted to know was whether any of the
     * command line arguments are file names or an explicit in-line "-e command".
     */
    for (i = 1; i < argc; i++) {
# ifdef _WIN32
	if (!stricmp(argv[i], "/noend"))
	    continue;
# endif
	if ((argv[i][0] != '-') || (argv[i][1] == 'e') || (argv[i][1] == 'c') ) {
	    interactive = FALSE;
	    break;
	}
    }

    /* Need this before show_version is called for the first time */

    if (interactive)
	show_version(stderr);
    else
	show_version(NULL); /* Only load GPVAL_COMPILE_OPTIONS */

    update_gpval_variables(3);  /* update GPVAL_ variables available to user */

#ifdef VMS
    /* initialise screen management routines for command recall */
    {
    unsigned int ierror;
    if (ierror = smg$create_virtual_keyboard(&vms_vkid) != SS$_NORMAL)
	done(ierror);
    if (ierror = smg$create_key_table(&vms_ktid) != SS$_NORMAL)
	done(ierror);
    }
#endif /* VMS */

    if (!SETJMP(command_line_env, 1)) {
	/* first time */
	interrupt_setup();
	get_user_env();
	init_loadpath();
	init_locale();

	memset(&sm_palette, 0, sizeof(sm_palette));
	init_fit();		/* Initialization of fitting module */
#ifdef READLINE
	/* When using the built-in readline, we set the initial
	   encoding according to the locale as this is required
	   to properly handle keyboard input. */
	init_encoding();
#endif
	init_gadgets();

	/* April 2017: Now that error handling is in place, it is safe parse
	 * GNUTERM during terminal initialization.
	 * atexit processing is done in reverse order. We want
	 * the generic terminal shutdown in term_reset to be executed before
	 * any terminal specific cleanup requested by individual terminals.
	 */
	init_terminal();
	push_terminal(0);	/* remember the initial terminal */
	gp_atexit(term_reset);

	/* Execute commands in ~/.gnuplot */
	init_session();

	if (interactive && term != 0) {		/* not unknown */
#ifdef GNUPLOT_HISTORY
#if (defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDITLINE)) && !defined(_WIN32)
	    expanded_history_filename = tilde_expand(GNUPLOT_HISTORY_FILE);
#else
	    expanded_history_filename = gp_strdup(GNUPLOT_HISTORY_FILE);
	    gp_expand_tilde(&expanded_history_filename);
#endif
	    read_history(expanded_history_filename);

	    /*
	     * It is safe to ignore the return values of 'atexit()' and
	     * 'on_exit()'. In the worst case, there is no history of your
	     * currrent session and you have to type all again in your next
	     * session.
	     */
	    gp_atexit(wrapper_for_write_history);
#endif /* GNUPLOT_HISTORY */

#if defined(READLINE) && defined(WGP_CONSOLE)
	    fprintf(stderr, "Encoding set to '%s'.\n", encoding_names[encoding]);
#endif
	}			/* if (interactive && term != 0) */
    } else {
	/* come back here from int_error() */
	if (!successful_initialization) {
	    /* Only print the warning once */
	    successful_initialization = TRUE;
	    fprintf(stderr,"WARNING: Error during initialization\n\n");
	}
	if (interactive == FALSE)
	    exit_status = EXIT_FAILURE;
#ifdef HAVE_READLINE_RESET
	else {
	    /* reset properly readline after a SIGINT+longjmp */
	    rl_reset_after_signal ();
	}
#endif

	load_file_error();	/* if we were in load_file(), cleanup */
	SET_CURSOR_ARROW;

#ifdef VMS
	/* after catching interrupt */
	/* VAX stuffs up stdout on SIGINT while writing to stdout,
	   so reopen stdout. */
	if (gpoutfile == stdout) {
	    if ((stdout = freopen("SYS$OUTPUT", "w", stdout)) == NULL) {
		/* couldn't reopen it so try opening it instead */
		if ((stdout = fopen("SYS$OUTPUT", "w")) == NULL) {
		    /* don't use int_error here - causes infinite loop! */
		    fputs("Error opening SYS$OUTPUT as stdout\n", stderr);
		}
	    }
	    gpoutfile = stdout;
	}
#endif /* VMS */

	/* Why a goto?  Because we exited the loop below via int_error */
	/* using LONGJMP.  The compiler was not expecting this, and    */
	/* "optimized" the handling of argc and argv such that simply  */
	/* entering the loop again from the top finds them messed up.  */
	/* If we reenter the loop via a goto then there is some hope   */
	/* that code reordering does not hurt us.                      */
	if (reading_from_dash && interactive)
	    goto RECOVER_FROM_ERROR_IN_DASH;
	reading_from_dash = FALSE;

	if (!interactive && !noinputfiles) {
	    term_reset();
	    gp_exit(EXIT_FAILURE);	/* exit on non-interactive error */
	}
    }

    /* load filenames given as arguments */
    while (--argc > 0) {
	    ++argv;
	    c_token = 0;
	    if (!strncmp(*argv, "-persist", 2) || !strcmp(*argv, "--persist")
#ifdef _WIN32
		|| !stricmp(*argv, "-noend") || !stricmp(*argv, "/noend")
#endif
	    ) {
		FPRINTF((stderr,"'persist' command line option recognized\n"));
	    } else if (strcmp(*argv, "-") == 0) {
#if defined(_WIN32) && !defined(WGP_CONSOLE)
		TextShow(&textwin);
		interactive = TRUE;
#else
		interactive = isatty(fileno(stdin));
#endif

RECOVER_FROM_ERROR_IN_DASH:
		reading_from_dash = TRUE;
		while (!com_line());
		reading_from_dash = FALSE;
		interactive = FALSE;
		noinputfiles = FALSE;

	    } else if (strcmp(*argv, "-e") == 0) {
		int save_state = interactive;
		--argc; ++argv;
		if (argc <= 0) {
		    fprintf(stderr, "syntax:  gnuplot -e \"commands\"\n");
		    return 0;
		}
		interactive = FALSE;
		noinputfiles = FALSE;
		do_string(*argv);
		interactive = save_state;

	    } else if (!strncmp(*argv, "-slow", 2) || !strcmp(*argv, "--slow")) {
		slow_font_startup = TRUE;

	    } else if (!strncmp(*argv, "-d", 2) || !strcmp(*argv, "--default-settings")) {
		/* Ignore this; it already had its effect */
		FPRINTF((stderr, "ignoring -d\n"));

	    } else if (strcmp(*argv, "-c") == 0) {
		/* Pass command line arguments to the gnuplot script in the next
		 * argument. This consumes the remainder of the command line
		 */
		interactive = FALSE;
		noinputfiles = FALSE;
		--argc; ++argv;
		if (argc <= 0) {
		    fprintf(stderr, "syntax:  gnuplot -c scriptname args\n");
		    gp_exit(EXIT_FAILURE);
		}
		call_argc = GPMIN(9, argc - 1);
		for (i=0; i<=call_argc; i++) {
		    /* Need to stash argv[i] somewhere visible to load_file() */
		    call_args[i] = gp_strdup(argv[i+1]);
		}

		load_file(loadpath_fopen(*argv, "r"), gp_strdup(*argv), 5);
		gp_exit(EXIT_SUCCESS);

	    } else if (*argv[0] == '-') {
		fprintf(stderr, "unrecognized option %s\n", *argv);
	    } else {
		interactive = FALSE;
		noinputfiles = FALSE;
		load_file(loadpath_fopen(*argv, "r"), gp_strdup(*argv), 4);
	    }
    }

    /* take commands from stdin */
    if (noinputfiles) {
	while (!com_line())
	    ctrlc_flag = FALSE; /* reset asynchronous Ctrl-C flag */
    }

#ifdef _WIN32
    /* On Windows, handle 'persist' by keeping the main input loop running (windows/wxt), */
    /* but only if there are any windows open. Note that qt handles this properly. */
    if (persist_cl) {
	if (WinAnyWindowOpen()) {
#ifdef WGP_CONSOLE
	    if (!interactive) {
		/* no further input from pipe */
		while (WinAnyWindowOpen())
		win_sleep(100);
	    } else
#endif
	    {
		interactive = TRUE;
		while (!com_line())
		    ctrlc_flag = FALSE; /* reset asynchronous Ctrl-C flag */
		interactive = FALSE;
	    }
	}
    }
#endif

#if (defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDITLINE)) && defined(GNUPLOT_HISTORY)
#if !defined(HAVE_ATEXIT) && !defined(HAVE_ON_EXIT)
    /* You should be here if you neither have 'atexit()' nor 'on_exit()' */
    wrapper_for_write_history();
#endif /* !HAVE_ATEXIT && !HAVE_ON_EXIT */
#endif /* (HAVE_LIBREADLINE || HAVE_LIBEDITLINE) && GNUPLOT_HISTORY */

#ifdef OS2
    RexxDeregisterSubcom("GNUPLOT", NULL);
#endif

    /* HBB 20040223: Not all compilers like exit() to end main() */
    /* exit(exit_status); */
#if ! defined(_WIN32)
    /* Windows does the cleanup later */
    gp_exit_cleanup();
#endif
    return exit_status;
}
Example #18
0
int
main(int argc, char **argv)
{
    bool fork_desired = TRUE;
    bool log_to_stderr_desired = FALSE;
    int lockfd;
    char* ocspuri = NULL;

#ifdef NAT_TRAVERSAL
    /** Overridden by nat_traversal= in ipsec.conf */
    bool nat_traversal = FALSE;
    bool nat_t_spf = TRUE;  /* support port floating */
    unsigned int keep_alive = 0;
    bool force_keepalive = FALSE;
#endif
#ifdef VIRTUAL_IP
    /** Overridden by virtual_private= in ipsec.conf */
    char *virtual_private = NULL;
#endif

    /* handle arguments */
    for (;;)
    {
#	define DBG_OFFSET 256
	static const struct option long_opts[] = {
	    /* name, has_arg, flag, val */
	    { "help", no_argument, NULL, 'h' },
	    { "version", no_argument, NULL, 'v' },
	    { "optionsfrom", required_argument, NULL, '+' },
	    { "nofork", no_argument, NULL, 'd' },
	    { "stderrlog", no_argument, NULL, 'e' },
	    { "noklips", no_argument, NULL, 'n' },
	    { "nocrsend", no_argument, NULL, 'c' },
	    { "strictcrlpolicy", no_argument, NULL, 'r' },
	    { "crlcheckinterval", required_argument, NULL, 'x'},
	    { "ocsprequestcert", required_argument, NULL, 'q'},
	    { "ocspuri", required_argument, NULL, 'o'},
	    { "uniqueids", no_argument, NULL, 'u' },
	    { "interface", required_argument, NULL, 'i' },
	    { "ikeport", required_argument, NULL, 'p' },
	    { "ctlbase", required_argument, NULL, 'b' },
	    { "secretsfile", required_argument, NULL, 's' },
	    { "foodgroupsdir", required_argument, NULL, 'f' },
	    { "perpeerlogbase", required_argument, NULL, 'P' },
	    { "perpeerlog", no_argument, NULL, 'l' },
	    { "noretransmits", no_argument, NULL, 'R' },
	    { "ipsecdir", required_argument, NULL, 'f' },
	    { "ipsec_dir", required_argument, NULL, 'f' },
#ifdef USE_LWRES
	    { "lwdnsq", required_argument, NULL, 'a' },
#else /* !USE_LWRES */
	    { "adns", required_argument, NULL, 'a' },
#endif /* !USE_LWRES */
#ifdef NAT_TRAVERSAL
	    { "nat_traversal", no_argument, NULL, '1' },
	    { "keep_alive", required_argument, NULL, '2' },
	    { "force_keepalive", no_argument, NULL, '3' },
	    { "disable_port_floating", no_argument, NULL, '4' },
	    { "debug-nat_t", no_argument, NULL, '5' },
#endif
#ifdef VIRTUAL_IP
	    { "virtual_private", required_argument, NULL, '6' },
#endif
#ifdef DEBUG
	    { "debug-none", no_argument, NULL, 'N' },
	    { "debug-all]", no_argument, NULL, 'A' },

	    { "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },
	    { "debug-crypt", no_argument, NULL, DBG_CRYPT + DBG_OFFSET },
	    { "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
	    { "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET },
	    { "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET },
	    { "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET },
	    { "debug-klips", no_argument, NULL, DBG_KLIPS + DBG_OFFSET },
	    { "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET },
	    { "debug-oppo", no_argument, NULL, DBG_OPPO + DBG_OFFSET },
	    { "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET },
	    { "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },
	    { "debug-pfkey", no_argument, NULL, DBG_PFKEY + DBG_OFFSET },

	    { "impair-delay-adns-key-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_KEY_ANSWER + DBG_OFFSET },
	    { "impair-delay-adns-txt-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_TXT_ANSWER + DBG_OFFSET },
	    { "impair-bust-mi2", no_argument, NULL, IMPAIR_BUST_MI2 + DBG_OFFSET },
	    { "impair-bust-mr2", no_argument, NULL, IMPAIR_BUST_MR2 + DBG_OFFSET },
#endif
	    { 0,0,0,0 }
	    };
	/* Note: we don't like the way short options get parsed
	 * by getopt_long, so we simply pass an empty string as
	 * the list.  It could be "hvdenp:l:s:" "NARXPECK".
	 */
	int c = getopt_long(argc, argv, "", long_opts, NULL);

	/** Note: "breaking" from case terminates loop */
	switch (c)
	{
	case EOF:	/* end of flags */
	    break;

	case 0: /* long option already handled */
	    continue;

	case ':':	/* diagnostic already printed by getopt_long */
	case '?':	/* diagnostic already printed by getopt_long */
	    usage("");
	    break;   /* not actually reached */

	case 'h':	/* --help */
	    usage(NULL);
	    break;	/* not actually reached */

	case 'v':	/* --version */
	    {
		const char **sp = ipsec_copyright_notice();

		printf("%s%s\n", ipsec_version_string(),
				 compile_time_interop_options);
		for (; *sp != NULL; sp++)
		    puts(*sp);
	    }
	    exit(0);	/* not exit_pluto because we are not initialized yet */
	    break;	/* not actually reached */

	case '+':	/* --optionsfrom <filename> */
	    optionsfrom(optarg, &argc, &argv, optind, stderr);
	    /* does not return on error */
	    continue;

	case 'd':	/* --nofork*/
	    fork_desired = FALSE;
	    continue;

	case 'e':	/* --stderrlog */
	    log_to_stderr_desired = TRUE;
	    continue;

	case 'n':	/* --noklips */
	    no_klips = TRUE;
	    continue;

	case 'c':	/* --nocrsend */
	    no_cr_send = TRUE;
	    continue
	    ;

	case 'r':	/* --strictcrlpolicy */
	    strict_crl_policy = TRUE;
	    continue
	    ;

	case 'R':
	    no_retransmits = TRUE;
	    continue;

	case 'x':	/* --crlcheckinterval <time>*/
            if (optarg == NULL || !isdigit(optarg[0]))
                usage("missing interval time");

            {
                char *endptr;
                long interval = strtol(optarg, &endptr, 0);

                if (*endptr != '\0' || endptr == optarg
                || interval <= 0)
                    usage("<interval-time> must be a positive number");
                crl_check_interval = interval;
            }
	    continue
	    ;

	case 'o':	/* --ocspuri */
	    ocspuri = optarg;
	    continue;

	case 'u':	/* --uniqueids */
	    uniqueIDs = TRUE;
	    continue;

	case 'i':	/* --interface <ifname> */
	    if (!use_interface(optarg))
		usage("too many --interface specifications");
	    continue;

	case 'p':	/* --port <portnumber> */
	    if (optarg == NULL || !isdigit(optarg[0]))
		usage("missing port number");

	    {
		char *endptr;
		long port = strtol(optarg, &endptr, 0);

		if (*endptr != '\0' || endptr == optarg
		|| port <= 0 || port > 0x10000)
		    usage("<port-number> must be a number between 1 and 65535");
		pluto_port = port;
	    }
	    continue;

	case 'b':	/* --ctlbase <path> */
	    if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
	    , "%s%s", optarg, CTL_SUFFIX) == -1)
		usage("<path>" CTL_SUFFIX " too long for sun_path");
	    if (snprintf(info_addr.sun_path, sizeof(info_addr.sun_path)
	    , "%s%s", optarg, INFO_SUFFIX) == -1)
		usage("<path>" INFO_SUFFIX " too long for sun_path");
	    if (snprintf(pluto_lock, sizeof(pluto_lock)
	    , "%s%s", optarg, LOCK_SUFFIX) == -1)
		usage("<path>" LOCK_SUFFIX " must fit");
	    continue;

	case 's':	/* --secretsfile <secrets-file> */
	    shared_secrets_file = optarg;
	    continue;

	case 'f':	/* --ipsecdir <ipsec-dir> */
	    ipsec_dir = optarg;
	    continue;

	case 'a':	/* --adns <pathname> */
	    pluto_adns_option = optarg;
	    continue;

#ifdef DEBUG
	case 'N':	/* --debug-none */
	    base_debugging = DBG_NONE;
	    continue;

	case 'A':	/* --debug-all */
	    base_debugging = DBG_ALL;
	    continue;
#endif

	case 'P':       /* --perpeerlogbase */
	    base_perpeer_logdir = optarg;
	    continue;

	case 'l':
	    log_to_perpeer = TRUE;
	    continue;

#ifdef NAT_TRAVERSAL
	case '1':	/* --nat_traversal */
	    nat_traversal = TRUE;
	    continue;
	case '2':	/* --keep_alive */
	    keep_alive = atoi(optarg);
	    continue;
	case '3':	/* --force_keepalive */
	    force_keepalive = TRUE;
	    continue;
	case '4':	/* --disable_port_floating */
	    nat_t_spf = FALSE;
	    continue;
	case '5':	/* --debug-nat_t */
	    base_debugging |= DBG_NATT;
	    continue;
#endif
#ifdef VIRTUAL_IP
	case '6':	/* --virtual_private */
	    virtual_private = optarg;
	    continue;
#endif

	default:
#ifdef DEBUG
	    if (c >= DBG_OFFSET)
	    {
		base_debugging |= c - DBG_OFFSET;
		continue;
	    }
#	undef DBG_OFFSET
#endif
	    bad_case(c);
	}
	break;
    }
    if (optind != argc)
	usage("unexpected argument");
    reset_debugging();
    lockfd = create_lock();

    /* select between logging methods */

    if (log_to_stderr_desired)
	log_to_syslog = FALSE;
    else
	log_to_stderr = FALSE;

    /* set the logging function of pfkey debugging */
#ifdef DEBUG
    pfkey_debug_func = DBG_log;
    pfkey_error_func = DBG_log;
#else
    pfkey_debug_func = NULL;
    pfkey_error_func = NULL;
#endif

    /** create control socket.
     * We must create it before the parent process returns so that
     * there will be no race condition in using it.  The easiest
     * place to do this is before the daemon fork.
     */
    {
	err_t ugh = init_ctl_socket();

	if (ugh != NULL)
	{
	    fprintf(stderr, "pluto: %s", ugh);
	    exit_pluto(1);
	}
    }

#ifdef IPSECPOLICY
    /* create info socket. */
    {
	err_t ugh = init_info_socket();

	if (ugh != NULL)
	{
	    fprintf(stderr, "pluto: %s", ugh);
	    exit_pluto(1);
	}
    }
#endif

    /* If not suppressed, do daemon fork */

    if (fork_desired)
    {
	{
	    pid_t pid = fork();

	    if (pid < 0)
	    {
		int e = errno;

		fprintf(stderr, "pluto: fork failed (%d %s)\n",
		    errno, strerror(e));
		exit_pluto(1);
	    }

	    if (pid != 0)
	    {
		/* parent: die, after filling PID into lock file.
		 * must not use exit_pluto: lock would be removed!
		 */
		exit(fill_lock(lockfd, pid)? 0 : 1);
	    }
	}

	if (setsid() < 0)
	{
	    int e = errno;

	    fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",
		errno, strerror(e));
	    exit_pluto(1);
	}
    }
    else
    {
	/* no daemon fork: we have to fill in lock file */
	(void) fill_lock(lockfd, getpid());
	fprintf(stdout, "Pluto initialized\n");
	fflush(stdout);
    }

    /** Close everything but ctl_fd and (if needed) stderr.
     * There is some danger that a library that we don't know
     * about is using some fd that we don't know about.
     * I guess we'll soon find out.
     */
    {
	int i;

	for (i = getdtablesize() - 1; i >= 0; i--)  /* Bad hack */
	    if ((!log_to_stderr || i != 2)
#ifdef IPSECPOLICY
	    && i != info_fd
#endif
	    && i != ctl_fd)
		close(i);

	/* make sure that stdin, stdout, stderr are reserved */
	if (open("/dev/null", O_RDONLY) != 0)
	    abort();
	if (dup2(0, 1) != 1)
	    abort();
	if (!log_to_stderr && dup2(0, 2) != 2)
	    abort();
    }

    init_constants();
    pluto_init_log();

    /* Note: some scripts may look for this exact message -- don't change
     * ipsec barf was one, but it no longer does.
     */
    {
#ifdef PLUTO_SENDS_VENDORID
        const char *v = init_pluto_vendorid();

        openswan_log("Starting Pluto (Openswan Version %s%s; Vendor ID %s)"
            , ipsec_version_code()
            , compile_time_interop_options
            , v);
#else
        openswan_log("Starting Pluto (Openswan Version %s%s)"
            , ipsec_version_code()
            , compile_time_interop_options);
#endif
    }

/** Initialize all of the various features */

#ifdef NAT_TRAVERSAL
    init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
#endif

#ifdef VIRTUAL_IP
    init_virtual_ip(virtual_private);
#endif
    init_rnd_pool();
    init_secret();
    init_states();
    init_crypto();
    init_demux();
    init_kernel();
    init_adns();
    init_id();

#ifdef HAVE_THREADS
    init_fetch();
#endif

    ocsp_set_default_uri(ocspuri);

    /* loading X.509 CA certificates */
    load_authcerts("CA cert", CA_CERT_PATH, AUTH_CA);
    /* loading X.509 AA certificates */
    load_authcerts("AA cert", AA_CERT_PATH, AUTH_AA);
    /* loading X.509 OCSP certificates */
    load_authcerts("OCSP cert", OCSP_CERT_PATH, AUTH_OCSP);

    /* loading X.509 CRLs */
    load_crls();
    /* loading attribute certificates (experimental) */
    load_acerts();

    daily_log_event();
    call_server();
    return -1;	/* Shouldn't ever reach this */
}
Example #19
0
int main(int argc, char **argv)
{
	bool fork_desired = TRUE;
	bool log_to_stderr_desired = FALSE;
	bool nat_traversal = FALSE;
	bool nat_t_spf = TRUE;  /* support port floating */
	unsigned int keep_alive = 0;
	bool force_keepalive = FALSE;
	char *virtual_private = NULL;
	int lockfd;
#ifdef CAPABILITIES
	int keep[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE };
#endif /* CAPABILITIES */

	/* initialize library and optionsfrom */
	if (!library_init(NULL))
	{
		library_deinit();
		exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
	}
	if (!libhydra_init("pluto"))
	{
		libhydra_deinit();
		library_deinit();
		exit(SS_RC_INITIALIZATION_FAILED);
	}
	if (!pluto_init(argv[0]))
	{
		pluto_deinit();
		libhydra_deinit();
		library_deinit();
		exit(SS_RC_DAEMON_INTEGRITY);
	}
	options = options_create();

	/* handle arguments */
	for (;;)
	{
#       define DBG_OFFSET 256
		static const struct option long_opts[] = {
			/* name, has_arg, flag, val */
			{ "help", no_argument, NULL, 'h' },
			{ "version", no_argument, NULL, 'v' },
			{ "optionsfrom", required_argument, NULL, '+' },
			{ "nofork", no_argument, NULL, 'd' },
			{ "stderrlog", no_argument, NULL, 'e' },
			{ "nocrsend", no_argument, NULL, 'c' },
			{ "strictcrlpolicy", no_argument, NULL, 'r' },
			{ "crlcheckinterval", required_argument, NULL, 'x'},
			{ "cachecrls", no_argument, NULL, 'C' },
			{ "uniqueids", no_argument, NULL, 'u' },
      { "disableuniqreqids", no_argument, NULL, 'Z'},			
			{ "interface", required_argument, NULL, 'i' },
			{ "ikeport", required_argument, NULL, 'p' },
			{ "ctlbase", required_argument, NULL, 'b' },
			{ "secretsfile", required_argument, NULL, 's' },
			{ "foodgroupsdir", required_argument, NULL, 'f' },
			{ "perpeerlogbase", required_argument, NULL, 'P' },
			{ "perpeerlog", no_argument, NULL, 'l' },
			{ "policygroupsdir", required_argument, NULL, 'f' },
#ifdef USE_LWRES
			{ "lwdnsq", required_argument, NULL, 'a' },
#else /* !USE_LWRES */
			{ "adns", required_argument, NULL, 'a' },
#endif /* !USE_LWRES */
			{ "pkcs11module", required_argument, NULL, 'm' },
			{ "pkcs11keepstate", no_argument, NULL, 'k' },
			{ "pkcs11initargs", required_argument, NULL, 'z' },
			{ "pkcs11proxy", no_argument, NULL, 'y' },
			{ "nat_traversal", no_argument, NULL, '1' },
			{ "keep_alive", required_argument, NULL, '2' },
			{ "force_keepalive", no_argument, NULL, '3' },
			{ "disable_port_floating", no_argument, NULL, '4' },
			{ "debug-natt", no_argument, NULL, '5' },
			{ "virtual_private", required_argument, NULL, '6' },
#ifdef DEBUG
			{ "debug-none", no_argument, NULL, 'N' },
			{ "debug-all", no_argument, NULL, 'A' },
			{ "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },
			{ "debug-crypt", no_argument, NULL, DBG_CRYPT + DBG_OFFSET },
			{ "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
			{ "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET },
			{ "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET },
			{ "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET },
			{ "debug-klips", no_argument, NULL, DBG_KERNEL + DBG_OFFSET },
			{ "debug-kernel", no_argument, NULL, DBG_KERNEL + DBG_OFFSET },
			{ "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET },
			{ "debug-oppo", no_argument, NULL, DBG_OPPO + DBG_OFFSET },
			{ "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET },
			{ "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },

			{ "impair-delay-adns-key-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_KEY_ANSWER + DBG_OFFSET },
			{ "impair-delay-adns-txt-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_TXT_ANSWER + DBG_OFFSET },
			{ "impair-bust-mi2", no_argument, NULL, IMPAIR_BUST_MI2 + DBG_OFFSET },
			{ "impair-bust-mr2", no_argument, NULL, IMPAIR_BUST_MR2 + DBG_OFFSET },
#endif
			{ 0,0,0,0 }
			};
		/* Note: we don't like the way short options get parsed
		 * by getopt_long, so we simply pass an empty string as
		 * the list.  It could be "hvdenp:l:s:" "NARXPECK".
		 */
		int c = getopt_long(argc, argv, "", long_opts, NULL);

		/* Note: "breaking" from case terminates loop */
		switch (c)
		{
		case EOF:       /* end of flags */
			break;

		case 0: /* long option already handled */
			continue;

		case ':':       /* diagnostic already printed by getopt_long */
		case '?':       /* diagnostic already printed by getopt_long */
			usage("");
			break;   /* not actually reached */

		case 'h':       /* --help */
			usage(NULL);
			break;      /* not actually reached */

		case 'v':       /* --version */
			{
				const char **sp = ipsec_copyright_notice();

				printf("strongSwan "VERSION"%s\n", compile_time_interop_options);
				for (; *sp != NULL; sp++)
					puts(*sp);
			}
			exit_pluto(0);
			break;      /* not actually reached */

		case '+':       /* --optionsfrom <filename> */
			if (!options->from(options, optarg, &argc, &argv, optind))
			{
				exit_pluto(1);
			}
			continue;

		case 'd':       /* --nofork*/
			fork_desired = FALSE;
			continue;

		case 'e':       /* --stderrlog */
			log_to_stderr_desired = TRUE;
			continue;

		case 'c':       /* --nocrsend */
			no_cr_send = TRUE;
			continue;

		case 'r':       /* --strictcrlpolicy */
			strict_crl_policy = TRUE;
			continue;

		case 'x':       /* --crlcheckinterval <time>*/
			if (optarg == NULL || !isdigit(optarg[0]))
				usage("missing interval time");

			{
				char *endptr;
				long interval = strtol(optarg, &endptr, 0);

				if (*endptr != '\0' || endptr == optarg
				|| interval <= 0)
					usage("<interval-time> must be a positive number");
				crl_check_interval = interval;
			}
			continue;

		case 'C':       /* --cachecrls */
			cache_crls = TRUE;
			continue;

		case 'u':       /* --uniqueids */
			uniqueIDs = TRUE;
			continue;
	
	  case 'Z':       /* --disableuniqreqids */
	    disable_uniqreqids = TRUE;
	    continue;

		case 'i':       /* --interface <ifname> */
			if (!use_interface(optarg))
				usage("too many --interface specifications");
			continue;

		case 'p':       /* --port <portnumber> */
			if (optarg == NULL || !isdigit(optarg[0]))
				usage("missing port number");

			{
				char *endptr;
				long port = strtol(optarg, &endptr, 0);

				if (*endptr != '\0' || endptr == optarg
				|| port <= 0 || port > 0x10000)
					usage("<port-number> must be a number between 1 and 65535");
				pluto_port = port;
			}
			continue;

		case 'b':       /* --ctlbase <path> */
			if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
			, "%s%s", optarg, CTL_SUFFIX) == -1)
				usage("<path>" CTL_SUFFIX " too long for sun_path");
			if (snprintf(info_addr.sun_path, sizeof(info_addr.sun_path)
			, "%s%s", optarg, INFO_SUFFIX) == -1)
				usage("<path>" INFO_SUFFIX " too long for sun_path");
			if (snprintf(pluto_lock, sizeof(pluto_lock)
			, "%s%s", optarg, LOCK_SUFFIX) == -1)
				usage("<path>" LOCK_SUFFIX " must fit");
			continue;

		case 's':       /* --secretsfile <secrets-file> */
			shared_secrets_file = optarg;
			continue;

		case 'f':       /* --policygroupsdir <policygroups-dir> */
			policygroups_dir = optarg;
			continue;

		case 'a':       /* --adns <pathname> */
			pluto_adns_option = optarg;
			continue;

		case 'm':       /* --pkcs11module <pathname> */
			pkcs11_module_path = optarg;
			continue;

		case 'k':       /* --pkcs11keepstate */
			pkcs11_keep_state = TRUE;
			continue;

		case 'y':       /* --pkcs11proxy */
			pkcs11_proxy = TRUE;
			continue;

		case 'z':       /* --pkcs11initargs */
			pkcs11_init_args = optarg;
			continue;

#ifdef DEBUG
		case 'N':       /* --debug-none */
			base_debugging = DBG_NONE;
			continue;

		case 'A':       /* --debug-all */
			base_debugging = DBG_ALL;
			continue;
#endif

		case 'P':       /* --perpeerlogbase */
			base_perpeer_logdir = optarg;
			continue;

		case 'l':
			log_to_perpeer = TRUE;
			continue;

		case '1':       /* --nat_traversal */
			nat_traversal = TRUE;
			continue;
		case '2':       /* --keep_alive */
			keep_alive = atoi(optarg);
			continue;
		case '3':       /* --force_keepalive */
			force_keepalive = TRUE;
			continue;
		case '4':       /* --disable_port_floating */
			nat_t_spf = FALSE;
			continue;
		case '5':       /* --debug-nat_t */
			base_debugging |= DBG_NATT;
			continue;
		case '6':       /* --virtual_private */
			virtual_private = optarg;
			continue;

		default:
#ifdef DEBUG
			if (c >= DBG_OFFSET)
			{
				base_debugging |= c - DBG_OFFSET;
				continue;
			}
#       undef DBG_OFFSET
#endif
			bad_case(c);
		}
		break;
	}
	if (optind != argc)
		usage("unexpected argument");
	reset_debugging();
	lockfd = create_lock();

	/* select between logging methods */

	if (log_to_stderr_desired)
	{
		log_to_syslog = FALSE;
	}
	else
	{
		log_to_stderr = FALSE;
	}

	/* set the logging function of pfkey debugging */
#ifdef DEBUG
	pfkey_debug_func = DBG_log;
#else
	pfkey_debug_func = NULL;
#endif

	/* create control socket.
	 * We must create it before the parent process returns so that
	 * there will be no race condition in using it.  The easiest
	 * place to do this is before the daemon fork.
	 */
	{
		err_t ugh = init_ctl_socket();

		if (ugh != NULL)
		{
			fprintf(stderr, "pluto: %s", ugh);
			exit_pluto(1);
		}
	}

	/* If not suppressed, do daemon fork */

	if (fork_desired)
	{
		{
			pid_t pid = fork();

			if (pid < 0)
			{
				int e = errno;

				fprintf(stderr, "pluto: fork failed (%d %s)\n",
					errno, strerror(e));
				exit_pluto(1);
			}

			if (pid != 0)
			{
				/* parent: die, after filling PID into lock file.
				 * must not use exit_pluto: lock would be removed!
				 */
				exit(fill_lock(lockfd, pid)? 0 : 1);
			}
		}

		if (setsid() < 0)
		{
			int e = errno;

			fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",
				errno, strerror(e));
			exit_pluto(1);
		}
	}
	else
	{
		/* no daemon fork: we have to fill in lock file */
		(void) fill_lock(lockfd, getpid());
		fprintf(stdout, "Pluto initialized\n");
		fflush(stdout);
	}

	/* Redirect stdin, stdout and stderr to /dev/null
	 */
	{
		int fd;
		if ((fd = open("/dev/null", O_RDWR)) == -1)
			abort();
		if (dup2(fd, 0) != 0)
			abort();
		if (dup2(fd, 1) != 1)
			abort();
		if (!log_to_stderr && dup2(fd, 2) != 2)
			abort();
		close(fd);
	}

	init_constants();
	init_log("pluto");

	/* Note: some scripts may look for this exact message -- don't change
	 * ipsec barf was one, but it no longer does.
	 */
	plog("Starting IKEv1 pluto daemon (strongSwan "VERSION")%s",
		 compile_time_interop_options);

	if (lib->integrity)
	{
		plog("integrity tests enabled:");
		plog("lib    'libstrongswan': passed file and segment integrity tests");
		plog("lib    'libhydra': passed file and segment integrity tests");
		plog("daemon 'pluto': passed file integrity test");
	}

	/* load plugins, further infrastructure may need it */
	if (!lib->plugins->load(lib->plugins, NULL,
			lib->settings->get_str(lib->settings, "pluto.load", PLUGINS)))
	{
		exit(SS_RC_INITIALIZATION_FAILED);
	}
	print_plugins();

	init_builder();
	if (!init_secret() || !init_crypto())
	{
		plog("initialization failed - aborting pluto");
		exit_pluto(SS_RC_INITIALIZATION_FAILED);
	}
	init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
	init_virtual_ip(virtual_private);
	scx_init(pkcs11_module_path, pkcs11_init_args);
	init_states();
	init_demux();
	init_kernel();
	init_adns();
	init_myid();
	fetch_initialize();
	ac_initialize();
	whack_attribute_initialize();

	/* drop unneeded capabilities and change UID/GID */
	prctl(PR_SET_KEEPCAPS, 1);

#ifdef IPSEC_GROUP
	{
		struct group group, *grp;
	char buf[1024];

		if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) != 0 ||
				grp == NULL || setgid(grp->gr_gid) != 0)
		{
			plog("unable to change daemon group");
			abort();
		}
	}
#endif
#ifdef IPSEC_USER
	{
		struct passwd passwd, *pwp;
	char buf[1024];

		if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) != 0 ||
				pwp == NULL || setuid(pwp->pw_uid) != 0)
		{
			plog("unable to change daemon user");
			abort();
		}
		}
#endif

#ifdef CAPABILITIES_LIBCAP
	{
		cap_t caps;
		caps = cap_init();
		cap_set_flag(caps, CAP_EFFECTIVE, countof(keep), keep, CAP_SET);
		cap_set_flag(caps, CAP_INHERITABLE, countof(keep), keep, CAP_SET);
		cap_set_flag(caps, CAP_PERMITTED, countof(keep), keep, CAP_SET);
		if (cap_set_proc(caps) != 0)
		{
			plog("unable to drop daemon capabilities");
			abort();
		}
		cap_free(caps);
	}
#endif /* CAPABILITIES_LIBCAP */
#ifdef CAPABILITIES_NATIVE
	{
		struct __user_cap_data_struct caps = { .effective = 0 };
		struct __user_cap_header_struct header = {
			.version = _LINUX_CAPABILITY_VERSION,
		};
		int i;
		for (i = 0; i < countof(keep); i++)
		{
			caps.effective |= 1 << keep[i];
			caps.permitted |= 1 << keep[i];
			caps.inheritable |= 1 << keep[i];
		}
		if (capset(&header, &caps) != 0)
		{
			plog("unable to drop daemon capabilities");
			abort();
		}
	}
#endif /* CAPABILITIES_NATIVE */

	/* loading X.509 CA certificates */
	load_authcerts("ca", CA_CERT_PATH, X509_CA);
	/* loading X.509 AA certificates */
	load_authcerts("aa", AA_CERT_PATH, X509_AA);
	/* loading X.509 OCSP certificates */
	load_authcerts("ocsp", OCSP_CERT_PATH, X509_OCSP_SIGNER);
	/* loading X.509 CRLs */
	load_crls();
	/* loading attribute certificates (experimental) */
	ac_load_certs();

	lib->processor->set_threads(lib->processor,
			lib->settings->get_int(lib->settings, "pluto.threads",
								   DEFAULT_THREADS));

	daily_log_event();
	call_server();
	return -1;  /* Shouldn't ever reach this */
}

/* leave pluto, with status.
 * Once child is launched, parent must not exit this way because
 * the lock would be released.
 *
 *  0 OK
 *  1 general discomfort
 * 10 lock file exists
 */
void exit_pluto(int status)
{
	lib->processor->set_threads(lib->processor, 0);
	reset_globals();    /* needed because we may be called in odd state */
	free_preshared_secrets();
	free_remembered_public_keys();
	delete_every_connection();
	whack_attribute_finalize(); /* free in-memory pools */
	kernel_finalize();
	fetch_finalize();           /* stop fetching thread */
	free_crl_fetch();           /* free chain of crl fetch requests */
	free_ocsp_fetch();          /* free chain of ocsp fetch requests */
	free_authcerts();           /* free chain of X.509 authority certificates */
	free_crls();                /* free chain of X.509 CRLs */
	free_ca_infos();            /* free chain of X.509 CA information records */
	free_ocsp();                /* free ocsp cache */
	free_ifaces();
	ac_finalize();              /* free X.509 attribute certificates */
	scx_finalize();             /* finalize and unload PKCS #11 module */
	stop_adns();
	free_md_pool();
	free_crypto();
	free_myid();                /* free myids */
	free_events();              /* free remaining events */
	free_vendorid();            /* free all vendor id records */
	free_builder();
	delete_lock();
	options->destroy(options);
	pluto_deinit();
	lib->plugins->unload(lib->plugins);
	libhydra_deinit();
	library_deinit();
	close_log();
	exit(status);
}
Example #20
0
int main(int argc, char **argv)
{
	int lockfd;
    bool restore_vrf_pluto = 0;
	
	/*此开关必须放在所有动态内存分配之前*/
	leak_detective=0;
	
	debug_info_control* dic=alloc_bytes(sizeof(debug_info_control), "malloc debug_info_control in main");

	openswan_passert_fail = passert_fail;

	/*设备类型初始化*/
	ipsec_device_type_init();
	{
		u32 pseudo_start_pluto = 0;

		for (;;)
		{
#define DBG_OFFSET 256
			static const struct option long_opts[] = {
				/* name, has_arg, flag, val */
				{ "help", no_argument, NULL, 'h' },
				{ "version", no_argument, NULL, 'v' },
				{ "start", no_argument, NULL, 'B' },
                { "quit", no_argument, NULL, 'D' },    
				{ "user", no_argument, NULL, 'u' },
				{ "krl", no_argument, NULL, 'K' },
				{ "debug-nat", no_argument, NULL, '5' },
				{ "debug-none", no_argument, NULL, 'N' },
				{ "debug-all", no_argument, NULL, 'A' },
				{ "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },	
				{ "debug-crypto", no_argument, NULL, DBG_CRYPT + DBG_OFFSET },
				{ "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
				{ "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET },
				{ "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET },
				{ "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET },
				{ "debug-klips", no_argument, NULL, DBG_KLIPS + DBG_OFFSET },
				{ "debug-netkey", no_argument, NULL, DBG_NETKEY + DBG_OFFSET },
				{ "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET },
				{ "debug-oppoinfo", no_argument, NULL, DBG_OPPOINFO + DBG_OFFSET },
				{ "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET },
				{ "debug-dpd", no_argument, NULL, DBG_DPD + DBG_OFFSET },
				{ "debug-xauth", no_argument, NULL, DBG_XAUTH+ DBG_OFFSET },
				{ "debug-x509", no_argument, NULL, DBG_X509 + DBG_OFFSET },
				{ "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },
				{ "debug-pfkey", no_argument, NULL, DBG_PFKEY + DBG_OFFSET },
                { "debug-ifchange", no_argument, NULL, DBG_IF_CHANGE + DBG_OFFSET },
                
				{ "log-openinfo", no_argument, NULL, 'i' },
				{ "log-openwar", no_argument, NULL, 'w' },
				{ "log-openerr", no_argument, NULL, 'r' },
				{ "log-openuserlog", no_argument, NULL, 'e' },				
				{ "log-openradiuslog", no_argument, NULL, 'c' },
				{ "log-openpri", no_argument, NULL, 'p' },
				{ "log-opensyserr", no_argument, NULL, 'q' },
				{ "log-closeall", no_argument, NULL, 'a' },

				{ "debug-connection", required_argument, NULL, 'O' },
				{ "debug-host", required_argument, NULL, 'H' },
				{ "debug-stop", no_argument, NULL, 'S' },
				{ "counter", no_argument, NULL, 'b' },				
				{ "isa-counter", no_argument, NULL, 'x' },

				{ "krc", no_argument, NULL, 'E'},
				{ "kss", required_argument, NULL, 'F'},
				{ "kpc", no_argument, NULL, 'G'},
				{ "kprt", required_argument, NULL, 'L'},
				{ "kspi", required_argument, NULL, 'M' },
				{ "kdst", required_argument, NULL, 'P' },
				{ "kdnet", required_argument, NULL, 'R' },
				{ "kid",  required_argument, NULL, 'Q' },
				{ "restore-vrf", no_argument, NULL, 'V' },	
				{ 0,0,0,0 }
			};

			int c = getopt_long(argc, argv, "", long_opts, NULL);
			ip_address dst_tmp;
			ip_subnet subnet_tmp;

			switch (c)
			{
				case EOF:	/* end of flags */
					break;

				case 0: /* long option already handled */
					continue;

				case ':':	/* diagnostic already printed by getopt_long */
				case '?':	/* diagnostic already printed by getopt_long */
					usage("");
					break;   

				case 'h':	
					usage(NULL);
					break;	

				case 'v':	
				{
					const char **sp = ipsec_copyright_notice();

					printf("%s%s\n", ipsec_version_string(),compile_time_interop_options);
					for (; *sp != NULL; sp++)
					{
						puts(*sp);
					}
				}
					exit(0);	
					break;	

				case 'i':
					dic->public_info.log_falg = 1;
					dic->public_info.log_level_info |= IPSEC_LOGLEVEL_INFO;
					continue;

				case 'w':
					dic->public_info.log_falg = 1;
					dic->public_info.log_level_info |= IPSEC_LOGLEVEL_WARNING;
					continue;

				case 'r':
					dic->public_info.log_falg = 1;
					dic->public_info.log_level_info |= IPSEC_LOGLEVEL_ERROR;
					continue;

				case 'e':
					dic->public_info.log_falg = 1;
					dic->public_info.log_level_info |= IPSEC_LOGLEVEL_USER_LOG;
					continue;
					
				case 'c':
					dic->public_info.log_falg = 1;
					dic->public_info.log_level_info |= IPSEC_LOGLEVEL_RADIUS_LOG;
					continue;
					
				case 'p':
					dic->public_info.log_falg = 1;
					dic->public_info.log_level_info |= IPSEC_LOGLEVEL_PRIVATE;
					continue;
					
				case 'q':
					dic->public_info.log_falg = 1;
					dic->public_info.log_level_info |= IPSEC_LOGLEVEL_SYSERROR;
					continue;

				case 'a':
					dic->public_info.log_falg = 1;
					dic->public_info.log_level_info=IPSEC_LOGLEVEL_CLOSE;
					continue;
                    
				case 'B': 				    
					dic->com_type=IPSEC_DEBUG_STAR_HANDLE;
					continue;                   

                case 'D':
                    dic->com_type=IPSEC_DEBUG_QUIT_HANDLE;
					continue;

				case 'u':                    
					dic->com_type=IPSEC_DEBUG_USER_HANDLE;
					continue;

				case 'K':	
					dic->com_type=IPSEC_DEBUG_KERNEL_HANDLE;
					continue;

				case 'N':	/* --debug-none */
					dic->public_info.public_info_flag=1;
					dic->public_info.public_info_value=DBG_NONE;
					continue;

				case 'A':	/* --debug-all */
					dic->public_info.public_info_flag=1;
					dic->public_info.public_info_value=DBG_ALL;
					continue;

				case 'O':
					if(optarg != NULL)
					{
						strcpy(dic->child_info.child_info_optarg,optarg);
						dic->child_info.child_info_type=IPSEC_CHILD_DEBUG_INFO_CON_NAME;
					}
					else
					{
						return 0;
					}
					break;

				case 'H':
					if(optarg != NULL)
					{
						strcpy(dic->child_info.child_info_optarg,optarg);
						dic->child_info.child_info_type=IPSEC_CHILD_DEBUG_INFO_HOST;
					}
					else
					{
						return 0;
					}
					break;

				case 'S':
					dic->child_info.child_info_type=IPSEC_CHILD_DEBUG_INFO_STOP;
					break;
				case 'b':
					dic->child_info.child_info_type=IPSEC_CHILD_DEBUG_INFO_PRINT_COUNTER;
					break;
                case 'x':
					dic->child_info.child_info_type=IPSEC_CHILD_DEBUG_INFO_PRINT_ISA_COUNTER;
					break;
				case 'E':	
					pseudo_start_pluto = 1;
					dic->kernel_info.flag= IPSEC_RESET_COUNTER;
					continue;

				case 'F':
					pseudo_start_pluto = 1;
					dic->kernel_info.flag = IPSEC_SET_DEBUG_SIP;
					dic->kernel_info.sip =inet_addr(optarg);
					continue;

				case 'G':
					pseudo_start_pluto = 1;
					dic->kernel_info.flag = IPSEC_DUMP_COUNTER;
					continue;
					
				case 'L':
					pseudo_start_pluto = 1;
					dic->kernel_info.flag=IPSEC_PRINT_INTERFACE_TEMP;
					if_get_index_by_name(optarg, (s32*)(&dic->kernel_info.ifindex));
					continue;	
					
				case 'M':	
					pseudo_start_pluto = 1;
					dic->kernel_info.flag=IPSEC_PRINT_INTERFACE_TEMP;

				    dic->kernel_info.spi = (u32)chartoint(optarg,strlen(optarg));
					if((int)dic->kernel_info.spi < 0)
					{
						fprintf(stderr,"%s IS ERROR INPUT(For Example:0x123...)\n",optarg);
						pfree(dic);
						return 0;
					}
				    continue;
					
				case 'P':
					pseudo_start_pluto = 1;
					dic->kernel_info.flag=IPSEC_PRINT_INTERFACE_TEMP;
					if(ttoaddr(optarg, 0, AF_INET, &dst_tmp))
					{
					    fprintf(stderr,"you must input right IP\n");
						pfree(dic);
						return 0;					    
					}
					else{
						dic->kernel_info.dsc.a4 = dst_tmp.u.v4.sin_addr.s_addr;
					    continue;
					}
				case 'R':
					pseudo_start_pluto = 1;
					dic->kernel_info.flag=IPSEC_PRINT_INTERFACE_TEMP;
					if(ttosubnet(optarg, 0, AF_INET, &subnet_tmp))
					{
					    fprintf(stderr,"you must input right subnet\n");
						pfree(dic);
						return 0;					    
					}
					else{
					    dic->kernel_info.net.a4 = subnet_tmp.addr.u.v4.sin_addr.s_addr;
					    continue;
					}

				case 'Q':	
					pseudo_start_pluto = 1;
					dic->kernel_info.flag=IPSEC_PRINT_INTERFACE_TEMP;
					dic->kernel_info.connid = atoi(optarg);
					continue;

				case 'V':
		        {
					restore_vrf_pluto = 1;
			    }		
				continue;
				
				default:
					if (c >= DBG_OFFSET)
					{
                        dic->public_info.public_info_flag=1;
						dic->public_info.public_info_value |= c - DBG_OFFSET;						
					}
					continue;
				bad_case(c);
			}
			break;

		}
		/**
		if(restore_vrf_pluto)
   	    {
   		   ipsec_restore_vrf_pluto();	   
   	    }
   	    **/
   		ipsec_restore_vrf_pluto();

	{
		u32 err;
		conplat_syscall(MODULEID_OSBASIC, OSBASIC_GET_VRF_ID, &g_ipsec_vrf_id, sizeof(g_ipsec_vrf_id), (s32*)(&err));	
		if(err != 0)
		{
			g_ipsec_vrf_id = 0;
		}

		sprintf(pluto_lock + strlen(pluto_lock), "_%d", g_ipsec_vrf_id);
		sprintf(ctl_addr.sun_path+ strlen(ctl_addr.sun_path), "_%d", g_ipsec_vrf_id);	
		sprintf(ws_ctl_addr.sun_path+ strlen(ws_ctl_addr.sun_path), "_%d", g_ipsec_vrf_id);			
	}

		switch(dic->com_type)
		{
			case IPSEC_DEBUG_STAR_HANDLE:
				if(dic->public_info.public_info_flag)
				{
					cur_debugging = dic->public_info.public_info_value;
				}

				if(dic->public_info.log_falg)
				{				    
					g_log_level = dic->public_info.log_level_info;					
				}
				break;

			case IPSEC_DEBUG_USER_HANDLE:
				send_connection_debug(dic, IPSEC_DEBUG_USER_HANDLE);
				pfree(dic);
				return 0;

			case IPSEC_DEBUG_KERNEL_HANDLE:
				if(pseudo_start_pluto == 1)
				{
					u32 syscall_result = 0;
					if((dic->kernel_info.flag==IPSEC_PRINT_INTERFACE_TEMP)&&(0 == dic->kernel_info.ifindex))
					{
						fprintf(stderr,"you must input the if name\n");
						pfree(dic);
						return 0;
					}
					
					conplat_syscall(MODULEID_IPSEC_POLICY, IPSEC_MODULE_DEBUG_PART, (void *)(&dic->kernel_info), sizeof(struct ipsec_user_debug_info), (s32 *)(&syscall_result));

					if(g_ipsec_device_is_dpx)
					{
						(u32)conplat_syscall(FW_MODULEID_IPSEC | FW_BOARD, IPSEC_MODULE_DEBUG_PART, (void *)(&dic->kernel_info), sizeof(struct ipsec_user_debug_info), (s32 *)(&syscall_result));
					}

				}
				else
				{
					fprintf(stderr,"after --kernel ,you must input the right command\n");
				}
				pfree(dic);
				return 0;
             case IPSEC_DEBUG_QUIT_HANDLE:
                send_connection_debug(dic, IPSEC_DEBUG_QUIT_HANDLE);
                pfree(dic);
                return 0;
			default:
				fprintf(stderr,"you must input --start --quit --user or --kernel\n");
				exit(0);
		}
		pfree(dic);
	}
	
	if (optind != argc)
	{
		usage("unexpected argument");
	}


	//如果你想再重启设备后默认打开调试开关
#if 0
	cur_debugging = DBG_ALL;
#endif

	lockfd = create_lock();
		

    g_log_level |= ws_get_log_level(); //获得显示级别

    g_ipsec_multiout = ws_get_multiOut(); //获取多接口转发标志位

	if(g_ipsec_multiout)
	{
	    int res;
	    conplat_syscall(MODULEID_IPSEC_POLICY, IPSEC_MODULE_MULTI_OUT, &(g_ipsec_multiout), sizeof(g_ipsec_multiout), &res);
	}

	ipsec_restore_tunnel_ipsec();

	ipsec_init_lv2_switch();
	ipsec_init_route_mode();
	ipsec_init_user_syn();
	ipsec_init_compress_enable();
	
	ipsec_init_udp_checksum_switch();

	ipsec_init_cookie();

	ipsec_esp_alg_init();
	
	init_vendorid();
	//daemon之前销毁缓冲池中的数据库句柄,使用make_daemon不用加此函数
	sqlite3_clear_buffer_ex();  
	{
		{
			pid_t pid = fork();

			if (pid < 0)
			{
				int e = errno;
				fprintf(stderr, "pluto: fork failed (%d %s)\n",errno, strerror(e));
				exit_pluto(1);
			}

			if (pid != 0)
			{
				/* parent: die, after filling PID into lock file.
				* must not use exit_pluto: lock would be removed!
				*/
				exit(fill_lock(lockfd, pid)? 0 : 1);
			}
		}

		if (setsid() < 0)
		{
			int e = errno;
			fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",errno, strerror(e));
			exit_pluto(1);	
		}
	}

	/** Close everything but  and (if needed) stderr.
	* There is some danger that a library that we don't know
	* about is using some fd that we don't know about.
	* I guess we'll soon find out.
	*/
	{
		int i;

		for (i = getdtablesize() - 1; i >= 0; i--)  /* Bad hack */
		{
			close(i);
		}

		/* make sure that stdin, stdout, stderr are reserved */
		if (open("/dev/null", O_RDONLY) != 0)
		{
			IPSEC_abort();
		}

		if (dup2(0, 1) != 1)
		{
			IPSEC_abort();
		}
	}
	init_constants();	

	init_pluto_vendorid();
	ipsec_version_code();

    ipsec_get_slot_bit();   // 需要放在ipsec_template_delete_all 前面
    
    ipsec_template_delete_all();    
    
    ipsec_enable_flag(1);
	ipsec_init_nat_traversal();

	init_rnd_pool();

	init_states();
	init_connections();//添加到elist链中phase2 pending timer
	init_crypto();
	ipsec_drv_rsa_para_init();   //初始化使用硬件模幂运算时的固定参数
	load_oswcrypto();
	init_demux();

	/* loading X.509 CA certificates */
	load_authcerts("CA cert", "/config/sys/certificate/cacerts", AUTH_CA);
	/* loading X.509 CRLs */
	load_crls();   
    
	fflush(stderr);
	fflush(stdout);
	
	IPSEC_dbg("listening for IKE messages");	

    init_ws_ctl_socket(); 
    
    /*初始化dpdns守护进程*/
    ipsec_dpdns_init_helper();   

    /*读取DPVPN相关配置并初始化*/
    //ipsec_dpvpn_init_cfg();

    /*该操作放在操作数据库之后的主进程处理不能再数据操作*/
	sqlite3_clear_buffer_ex();      
	/*初始化子进程*/
	ipsec_child_init_helpers();  	

	ipsec_main_call_server();

	return -1;	/* Shouldn't ever reach this */
}
Example #21
0
int
main(int argc, char **argv)
{
    bool fork_desired = TRUE;
    bool log_to_stderr_desired = FALSE;
    int lockfd;
#ifdef NAT_TRAVERSAL
    bool nat_traversal = FALSE;
    unsigned int keep_alive = 0;
#endif
#ifdef VIRTUAL_IP
    char *virtual_private = NULL;
#endif

    char *ipsec0 = NULL;
    char *ipsec1 = NULL;
    char *ipsec2 = NULL;
    char *ipsec3 = NULL;
    
    /* handle arguments */
    for (;;)
    {
	static const struct option long_opts[] = {
	    /* name, has_arg, flag, val */
	    { "help", no_argument, NULL, 'h' },
	    { "version", no_argument, NULL, 'v' },
	    { "optionsfrom", required_argument, NULL, '+' },
	    { "nofork", no_argument, NULL, 'd' },
	    { "stderrlog", no_argument, NULL, 'e' },
	    { "noklips", no_argument, NULL, 'n' },
	    { "nocrsend", no_argument, NULL, 'c' },
	    { "uniqueids", no_argument, NULL, 'u' },
	    { "interface", required_argument, NULL, 'i' },
	    { "ikeport", required_argument, NULL, 'p' },
	    { "ctlbase", required_argument, NULL, 'b' },
	    { "secretsfile", required_argument, NULL, 's' },
	    { "adns", required_argument, NULL, 'a' },
#ifdef DEBUG
	    { "debug-none", no_argument, NULL, 'N' },
	    { "debug-all]", no_argument, NULL, 'A' },
	    { "debug-raw", no_argument, NULL, 'R' },
	    { "debug-crypt", no_argument, NULL, 'X' },
	    { "debug-parsing", no_argument, NULL, 'P' },
	    { "debug-emitting", no_argument, NULL, 'E' },
	    { "debug-control", no_argument, NULL, 'C' },
	    { "debug-lifecycle", no_argument, NULL, 'L' },
	    { "debug-klips", no_argument, NULL, 'K' },
	    { "debug-dns", no_argument, NULL, 'D' },
	    { "debug-private", no_argument, NULL, 'Z' },
#endif
#ifdef NAT_TRAVERSAL
	    { "nat_traversal", no_argument, NULL, '1' },
	    { "keep_alive", required_argument, NULL, '2' },
#endif
#ifdef VIRTUAL_IP
	    { "virtual_private", required_argument, NULL, '3' },
#endif
    	    { "ipsec0", required_argument, NULL, '4' },
	    { "ipsec1", required_argument, NULL, '5' },
	    { "ipsec2", required_argument, NULL, '6' },
	    { "ipsec3", required_argument, NULL, '7' },
	    { 0,0,0,0 }
	    };
	/* Note: we don't like the way short options get parsed
	 * by getopt_long, so we simply pass an empty string as
	 * the list.  It could be "hvdenp:l:s:" "NARXPECK".
	 */
	int c = getopt_long(argc, argv, "", long_opts, NULL);

	/* Note: "breaking" from case terminates loop */
	switch (c)
	{
	case EOF:	/* end of flags */
	    break;

	case 0: /* long option already handled */
	    continue;

	case ':':	/* diagnostic already printed by getopt_long */
	case '?':	/* diagnostic already printed by getopt_long */
	    usage("");
	    break;   /* not actually reached */

	case 'h':	/* --help */
	    usage(NULL);
	    break;	/* not actually reached */

	case 'v':	/* --version */
	    {
		const char **sp = ipsec_copyright_notice();

		printf("%s\n", ipsec_version_string());
		for (; *sp != NULL; sp++)
		    puts(*sp);
	    }
	    exit_pluto(0);
	    break;	/* not actually reached */

	case '+':	/* --optionsfrom <filename> */
	    optionsfrom(optarg, &argc, &argv, optind, stderr);
	    /* does not return on error */
	    continue;

	case 'd':	/* --nofork*/
	    fork_desired = FALSE;
	    continue;

	case 'e':	/* --stderrlog */
	    log_to_stderr_desired = TRUE;
	    continue;

	case 'n':	/* --noklips */
	    no_klips = TRUE;
	    continue;

	case 'c':	/* --nocrsend */
	    no_cr_send = TRUE;
	    continue
	    ;
	case 'u':	/* --uniquids */
	    uniqueIDs = TRUE;
	    continue;

	case 'i':	/* --interface <ifname> */
	    if (!use_interface(optarg))
		usage("too many --interface specifications");
	    continue;

	case 'p':	/* --port <portnumber> */
	    if (optarg == NULL || !isdigit(optarg[0]))
		usage("missing port number");

	    {
		char *endptr;
		long port = strtol(optarg, &endptr, 0);

		if (*endptr != '\0' || endptr == optarg
		|| port <= 0 || port > 0x10000)
		    usage("<port-number> must be a number between 1 and 65535");
		pluto_port = port;
	    }
	    continue;

	case 'b':	/* --ctlbase <path> */
	    if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
	    , "%s%s", optarg, CTL_SUFFIX) == -1)
		usage("<path>" CTL_SUFFIX " too long for sun_path");
	    if (snprintf(pluto_lock, sizeof(pluto_lock)
	    , "%s%s", optarg, LOCK_SUFFIX) == -1)
		usage("<path>" LOCK_SUFFIX " must fit");
	    continue;

	case 's':	/* --secretsfile <secrets-file> */
	    shared_secrets_file = optarg;
	    continue;

	case 'a':	/* --adns <pathname> */
	    pluto_adns_option = optarg;
	    continue;

#ifdef DEBUG
	case 'N':	/* --debug-none */
	    base_debugging = DBG_NONE;
	    continue;

	case 'A':	/* --debug-all */
	    base_debugging = DBG_ALL;
	    continue;

	case 'R':	/* --debug-raw */
	    base_debugging |= DBG_RAW;
	    continue;

	case 'X':	/* --debug-crypt */
	    base_debugging |= DBG_CRYPT;
	    continue;

	case 'P':	/* --debug-parsing */
	    base_debugging |= DBG_PARSING;
	    continue;

	case 'E':	/* --debug-emitting */
	    base_debugging |= DBG_EMITTING;
	    continue;

	case 'C':	/* --debug-control */
	    base_debugging |= DBG_CONTROL;
	    continue;

	case 'L':	/* --debug-lifecycle */
	    base_debugging |= DBG_LIFECYCLE;
	    continue;

	case 'K':	/* --debug-klips */
	    base_debugging |= DBG_KLIPS;
	    continue;

	case 'D':	/* --debug-dns */
	    base_debugging |= DBG_DNS;
	    continue;

	case 'Z':	/* --debug-private */
	    base_debugging |= DBG_PRIVATE;
	    continue;
#endif
#ifdef NAT_TRAVERSAL
	case '1':	/* --nat_traversal */
	    nat_traversal = TRUE;
	    continue;
	case '2':	/* --keep_alive */
	    keep_alive = atoi(optarg);
	    continue;
#endif
#ifdef VIRTUAL_IP
	case '3':	/* --virtual_private */
	    virtual_private = optarg;
	    continue;
#endif
	case '4':	/* --ipsec0 */
	    ipsec0 = optarg;
	    continue;
	case '5':	/* --ipsec1 */
	    ipsec1 = optarg;
	    continue;
	case '6':	/* --ipsec2 */
	    ipsec2 = optarg;
	    continue;
	case '7':	/* --ipsec3 */
	    ipsec3 = optarg;
	    continue;

	default:
	    impossible();
	}
	break;
    }
    if (optind != argc)
	usage("unexpected argument");
    reset_debugging();
    lockfd = create_lock();

    /* select between logging methods */

    if (log_to_stderr_desired)
	log_to_syslog = FALSE;
    else
	log_to_stderr = FALSE;

    /* create control socket.
     * We must create it before the parent process returns so that
     * there will be no race condition in using it.  The easiest
     * place to do this is before the daemon fork.
     */
    {
	err_t ugh = init_ctl_socket();

	if (ugh != NULL)
	{
	    fprintf(stderr, "pluto: %s", ugh);
	    exit_pluto(1);
	}
    }

    /* If not suppressed, do daemon fork */

#ifndef EMBED
    if (fork_desired)
    {
	{
	    pid_t pid = fork();

	    if (pid < 0)
	    {
		int e = errno;

		fprintf(stderr, "pluto: fork failed (%d %s)\n",
		    errno, strerror(e));
		exit_pluto(1);
	    }

	    if (pid != 0)
	    {
		/* parent: die, after filling PID into lock file.
		 * must not use exit_pluto: lock would be removed!
		 */
		exit(fill_lock(lockfd, pid)? 0 : 1);
	    }
	}

	if (setsid() < 0)
	{
	    int e = errno;

	    fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",
		errno, strerror(e));
	    exit_pluto(1);
	}

	/* Close everything but ctl_fd and (if needed) stderr. */
	{
	    int i;

	    for (i = getdtablesize() - 1; i >= 0; i--)  /* Bad hack */
		if ((!log_to_stderr || i != 2)
		&& i != ctl_fd)
		    close(i);

	    /* make sure that stdin, stdout, stderr are reserved */
	    if (open("/dev/null", O_RDONLY) != 0)
		abort();
	    if (dup2(0, 1) != 1)
		abort();
	    if (!log_to_stderr && dup2(0, 2) != 2)
		abort();
	}
    }
    else
#endif
    {
	/* no daemon fork: we have to fill in lock file */
	(void) fill_lock(lockfd, getpid());
	fprintf(stdout, "Pluto initialized\n");
	fflush(stdout);
    }

    init_constants();
    init_log();
    /* Note: some scripts may look for this exact message -- don't change */
    log("Starting Pluto (FreeS/WAN Version %s)", ipsec_version_code());
    log("  including X.509 patch (Version %s)", x509patch_version);

#ifdef NAT_TRAVERSAL
    init_nat_traversal(nat_traversal,keep_alive);
#endif

#ifdef VIRTUAL_IP
    init_virtual_ip(virtual_private);
#endif
    init_interfaces(ipsec0, ipsec1, ipsec2, ipsec3);
    init_rnd_pool();
    init_secret();
    init_states();
    init_crypto();
    init_demux();
    init_kernel();
    init_adns();

    /* loading CA certificates */
    load_cacerts();
    /* loading CRLs */
    load_crls();
    /* loading my X.509 or OpenPGP certificate */
    load_mycert();

    call_server();
    return -1;        /* Shouldn't ever reach this */
}
Example #22
0
int
main(int argc, char **argv)
{
    int lockfd;
    int nhelpers = -1;
    char *coredir;
    const struct lsw_conf_options *oco;

    /* 
     * We read the intentions for how to log from command line options
     * and the config file. Then we prepare to be able to log, but until
     * then log to stderr (better then nothing). Once we are ready to
     * actually do loggin according to the methods desired, we set the
     * variables for those methods
     */
    bool   log_to_stderr_desired = FALSE;
    bool   log_to_file_desired = FALSE;

    coredir = NULL;

    /* set up initial defaults that need a cast */
    pluto_shared_secrets_file =
        DISCARD_CONST(char *, SHARED_SECRETS_FILE);

#ifdef NAT_TRAVERSAL
    /** Overridden by nat_traversal= in ipsec.conf */
    bool nat_traversal = FALSE;
    bool nat_t_spf = TRUE;  /* support port floating */
    unsigned int keep_alive = 0;
    bool force_keepalive = FALSE;
#endif
    /** Overridden by virtual_private= in ipsec.conf */
    char *virtual_private = NULL;
#ifdef LEAK_DETECTIVE
    leak_detective=1;
#else
    leak_detective=0;
#endif

#ifdef HAVE_LIBCAP_NG
	/* Drop capabilities */
	capng_clear(CAPNG_SELECT_BOTH);
	capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
			CAP_NET_BIND_SERVICE, CAP_NET_ADMIN, CAP_NET_RAW,
			CAP_IPC_LOCK, CAP_AUDIT_WRITE,
			-1);
	/* our children must be able to CAP_NET_ADMIN to change routes.
	 */
	capng_updatev(CAPNG_ADD, CAPNG_BOUNDING_SET,
			CAP_NET_ADMIN, -1);
	capng_apply(CAPNG_SELECT_BOTH);
#endif


#ifdef DEBUG
    libreswan_passert_fail = passert_fail;
#endif

    if(getenv("PLUTO_WAIT_FOR_GDB")) {
	sleep(120);
    }

    /* handle arguments */
    for (;;)
    {
#	define DBG_OFFSET 256
	static const struct option long_opts[] = {
	    /* name, has_arg, flag, val */
	    { "help", no_argument, NULL, 'h' },
	    { "version", no_argument, NULL, 'v' },
	    { "config", required_argument, NULL, 'z' },
	    { "nofork", no_argument, NULL, 'd' },
	    { "stderrlog", no_argument, NULL, 'e' },
	    { "logfile", required_argument, NULL, 'g' },
	    { "plutostderrlogtime", no_argument, NULL, 't' },
	    { "noklips", no_argument, NULL, 'n' },
	    { "use-nostack",  no_argument, NULL, 'n' },
	    { "use-none",     no_argument, NULL, 'n' },
	    { "force_busy", no_argument, NULL, 'D' },
	    { "strictcrlpolicy", no_argument, NULL, 'r' },
	    { "crlcheckinterval", required_argument, NULL, 'x'},
	    { "uniqueids", no_argument, NULL, 'u' },
	    { "useklips",  no_argument, NULL, 'k' },
	    { "use-klips",  no_argument, NULL, 'k' },
	    { "use-auto",  no_argument, NULL, 'G' },
	    { "usenetkey", no_argument, NULL, 'K' },
	    { "use-netkey", no_argument, NULL, 'K' },
	    { "use-mast",   no_argument, NULL, 'M' },
	    { "use-mastklips",   no_argument, NULL, 'M' },
	    { "use-bsdkame",   no_argument, NULL, 'F' },
	    { "interface", required_argument, NULL, 'i' },
	    { "listen", required_argument, NULL, 'L' },
	    { "ikeport", required_argument, NULL, 'p' },
	    { "natikeport", required_argument, NULL, 'q' },
	    { "ctlbase", required_argument, NULL, 'b' },
	    { "secretsfile", required_argument, NULL, 's' },
	    { "perpeerlogbase", required_argument, NULL, 'P' },
	    { "perpeerlog", no_argument, NULL, 'l' },
	    { "noretransmits", no_argument, NULL, 'R' },
	    { "coredir", required_argument, NULL, 'C' },
	    { "ipsecdir", required_argument, NULL, 'f' },
	    { "ipsec_dir", required_argument, NULL, 'f' },
	    { "foodgroupsdir", required_argument, NULL, 'f' },
	    { "adns", required_argument, NULL, 'a' },
#ifdef NAT_TRAVERSAL
	    { "nat_traversal", no_argument, NULL, '1' },
	    { "keep_alive", required_argument, NULL, '2' },
	    { "force_keepalive", no_argument, NULL, '3' },
	    { "disable_port_floating", no_argument, NULL, '4' },
	    { "debug-nat_t", no_argument, NULL, '5' },
	    { "debug-nattraversal", no_argument, NULL, '5' },
	    { "debug-nat-t", no_argument, NULL, '5' },
#endif
	    { "virtual_private", required_argument, NULL, '6' },
	    { "nhelpers", required_argument, NULL, 'j' },
#ifdef HAVE_LABELED_IPSEC
	    { "secctx_attr_value", required_argument, NULL, 'w' },
#endif
#ifdef DEBUG
	    { "debug-none", no_argument, NULL, 'N' },
	    { "debug-all", no_argument, NULL, 'A' },

	    { "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },
	    { "debug-crypt", no_argument, NULL, DBG_CRYPT + DBG_OFFSET },
	    { "debug-crypto", no_argument, NULL, DBG_CRYPT + DBG_OFFSET },
	    { "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
	    { "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET },
	    { "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET },
	    { "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET },
	    { "debug-klips", no_argument, NULL, DBG_KLIPS + DBG_OFFSET },
	    { "debug-netkey", no_argument, NULL, DBG_NETKEY + DBG_OFFSET },
	    { "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET },
	    { "debug-oppo", no_argument, NULL, DBG_OPPO + DBG_OFFSET },
	    { "debug-oppoinfo", no_argument, NULL, DBG_OPPOINFO + DBG_OFFSET },
	    { "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET },
	    { "debug-dpd", no_argument, NULL, DBG_DPD + DBG_OFFSET },
            { "debug-x509", no_argument, NULL, DBG_X509 + DBG_OFFSET },
	    { "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },
	    { "debug-pfkey", no_argument, NULL, DBG_PFKEY + DBG_OFFSET },

	    { "impair-delay-adns-key-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_KEY_ANSWER + DBG_OFFSET },
	    { "impair-delay-adns-txt-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_TXT_ANSWER + DBG_OFFSET },
	    { "impair-bust-mi2", no_argument, NULL, IMPAIR_BUST_MI2 + DBG_OFFSET },
	    { "impair-bust-mr2", no_argument, NULL, IMPAIR_BUST_MR2 + DBG_OFFSET },
	    { "impair-sa-creation", no_argument, NULL, IMPAIR_SA_CREATION + DBG_OFFSET },
	    { "impair-die-oninfo", no_argument, NULL, IMPAIR_DIE_ONINFO + DBG_OFFSET },
	    { "impair-jacob-two-two", no_argument, NULL, IMPAIR_JACOB_TWO_TWO + DBG_OFFSET },
	    { "impair-major-version-bump", no_argument, NULL, IMPAIR_MAJOR_VERSION_BUMP + DBG_OFFSET },
	    { "impair-minor-version-bump", no_argument, NULL, IMPAIR_MINOR_VERSION_BUMP + DBG_OFFSET },
	    { "impair-retransmits", no_argument, NULL, IMPAIR_RETRANSMITS + DBG_OFFSET },
	    { "impair-send-bogus-isakmp-flag", no_argument, NULL, IMPAIR_SEND_BOGUS_ISAKMP_FLAG + DBG_OFFSET },
#endif
	    { 0,0,0,0 }
	    };
	/* Note: we don't like the way short options get parsed
	 * by getopt_long, so we simply pass an empty string as
	 * the list.  It could be "hvdenp:l:s:" "NARXPECK".
	 */
	int c = getopt_long(argc, argv, "", long_opts, NULL);

	/** Note: "breaking" from case terminates loop */
	switch (c)
	{
	case EOF:	/* end of flags */
	    break;

	case 0: /* long option already handled */
	    continue;

	case ':':	/* diagnostic already printed by getopt_long */
	case '?':	/* diagnostic already printed by getopt_long */
	    usage("");
	    break;   /* not actually reached */

	case 'h':	/* --help */
	    usage(NULL);
	    break;	/* not actually reached */

	case 'C':
	    coredir = clone_str(optarg, "coredir");
	    continue;

	case 'v':	/* --version */
	    {
		printf("%s%s\n", ipsec_version_string(),
				 compile_time_interop_options);
	    }
	    exit(0);	/* not exit_pluto because we are not initialized yet */
	    break;	/* not actually reached */

	case 'j':	/* --nhelpers */
            if (optarg == NULL || !isdigit(optarg[0]))
                usage("missing number of pluto helpers");

            {
                char *endptr;
                long count = strtol(optarg, &endptr, 0);

                if (*endptr != '\0' || endptr == optarg
		    || count < -1)
                    usage("<nhelpers> must be a positive number, 0 or -1");
                nhelpers = count;
            }
	    continue;

#ifdef HAVE_LABELED_IPSEC
	case 'w':	/* --secctx_attr_value*/
	    if (optarg == NULL || !isdigit(optarg[0]))
		usage("missing (positive integer) value of secctx_attr_value (needed only if using labeled ipsec)");

	   {
                char *endptr;
                long value = strtol(optarg, &endptr, 0);

                if (*endptr != '\0' || endptr == optarg
                    || (value != SECCTX && value !=10) )
                    usage("<secctx_attr_value> must be a positive number (32001 by default, 10 for backward compatibility, or any other future number assigned by IANA)");
                 secctx_attr_value = (u_int16_t)value;
	   }
	   continue;
#endif

	case 'd':	/* --nofork*/
	    fork_desired = FALSE;
	    continue;

	case 'e':	/* --stderrlog */
	    log_to_stderr_desired = TRUE;
	    continue;

	case 'g':	/* --logfile */
	    pluto_log_file = optarg;
	    log_to_file_desired = TRUE;
	    continue;

	case 't':	/* --plutostderrlogtime */
	    log_with_timestamp = TRUE;
	    continue;

	case 'G':       /* --use-auto */
	    libreswan_log("The option --use-auto is obsoleted, falling back to  --use-netkey\n");
	    kern_interface = USE_NETKEY;
	    continue;

	case 'k':       /* --use-klips */
	    kern_interface = USE_KLIPS;
	    continue;

	case 'L':	/* --listen ip_addr */
	    {
	    ip_address lip;
	     err_t e = ttoaddr(optarg,0,0,&lip);
	    if(e) {
		libreswan_log("invalid listen argument ignored: %s\n",e);
	    } else {
		pluto_listen = clone_str(optarg, "pluto_listen");
		libreswan_log("bind() will be filtered for %s\n",pluto_listen);
	    }
            }
	   continue;

	case 'M':       /* --use-mast */
	    kern_interface = USE_MASTKLIPS;
	    continue;

	case 'F':       /* --use-bsdkame */
	    kern_interface = USE_BSDKAME;
	    continue;

	case 'K':       /* --use-netkey */
	    kern_interface = USE_NETKEY;
	    continue;

	case 'n':	/* --use-nostack */
	    kern_interface = NO_KERNEL;
	    continue;

	case 'D':	/* --force_busy */
	    force_busy = TRUE;
	    continue
	    ;

	case 'r':	/* --strictcrlpolicy */
	    strict_crl_policy = TRUE;
	    continue
	    ;

	case 'R':
	    no_retransmits = TRUE;
	    continue;

	case 'x':	/* --crlcheckinterval <time>*/
            if (optarg == NULL || !isdigit(optarg[0]))
                usage("missing interval time");

            {
                char *endptr;
                long interval = strtol(optarg, &endptr, 0);

                if (*endptr != '\0' || endptr == optarg
                || interval <= 0)
                    usage("<interval-time> must be a positive number");
                crl_check_interval = interval;
            }
	    continue
	    ;

	case 'u':	/* --uniqueids */
	    uniqueIDs = TRUE;
	    continue;

	case 'i':	/* --interface <ifname|ifaddr> */
	    if (!use_interface(optarg))
		usage("too many --interface specifications");
	    continue;

	/*
	 * This option does not really work, as this is the "left"
	 * site only, you also need --to --ikeport again later on
	 * It will result in: yourport -> 500, still not bypassing filters
	 */
	case 'p':	/* --ikeport <portnumber> */
	    if (optarg == NULL || !isdigit(optarg[0]))
		usage("missing port number");
	    {
		char *endptr;
		long port = strtol(optarg, &endptr, 0);

		if (*endptr != '\0' || endptr == optarg
		|| port <= 0 || port > 0x10000)
		    usage("<port-number> must be a number between 1 and 65535");
		pluto_port = port;
	    }
	    continue;

#ifdef NAT_TRAVERSAL
	case 'q':	/* --natikeport <portnumber> */
	    if (optarg == NULL || !isdigit(optarg[0]))
		usage("missing port number");
	    {
		char *endptr;
		long port = strtol(optarg, &endptr, 0);

		if (*endptr != '\0' || endptr == optarg
		|| port <= 0 || port > 0x10000)
		    usage("<port-number> must be a number between 1 and 65535");
		pluto_natt_float_port = port;
	    }
	    continue;
#endif

	case 'b':	/* --ctlbase <path> */
	    ctlbase = optarg;
	    if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
			 , "%s%s", ctlbase, CTL_SUFFIX) == -1)
		usage("<path>" CTL_SUFFIX " too long for sun_path");
	    if (snprintf(info_addr.sun_path, sizeof(info_addr.sun_path)
			 , "%s%s", ctlbase, INFO_SUFFIX) == -1)
		usage("<path>" INFO_SUFFIX " too long for sun_path");
	    if (snprintf(pluto_lock, sizeof(pluto_lock)
			 , "%s%s", ctlbase, LOCK_SUFFIX) == -1)
		usage("<path>" LOCK_SUFFIX " must fit");
	    continue;

	case 's':	/* --secretsfile <secrets-file> */
	    pluto_shared_secrets_file = optarg;
	    continue;

	case 'f':	/* --ipsecdir <ipsec-dir> */
	    (void)lsw_init_ipsecdir(optarg);
	    continue;

	case 'a':	/* --adns <pathname> */
	    pluto_adns_option = optarg;
	    continue;

#ifdef DEBUG
	case 'N':	/* --debug-none */
	    base_debugging = DBG_NONE;
	    continue;

	case 'A':	/* --debug-all */
	    base_debugging = DBG_ALL;
	    continue;
#endif

	case 'P':       /* --perpeerlogbase */
	    base_perpeer_logdir = optarg;
	    continue;

	case 'l':
	    log_to_perpeer = TRUE;
	    continue;

#ifdef NAT_TRAVERSAL
	case '1':	/* --nat_traversal */
	    nat_traversal = TRUE;
	    continue;
	case '2':	/* --keep_alive */
	    keep_alive = atoi(optarg);
	    continue;
	case '3':	/* --force_keepalive */
	    force_keepalive = TRUE;
	    continue;
	case '4':	/* --disable_port_floating */
	    nat_t_spf = FALSE;
	    continue;
#ifdef DEBUG
	case '5':	/* --debug-nat_t */
	    base_debugging |= DBG_NATT;
	    continue;
#endif
#endif
	case '6':	/* --virtual_private */
	    virtual_private = optarg;
	    continue;

	case 'z':	/* --config */
	    ;
	    /* Config struct to variables mapper. This will overwrite */
	    /* all previously set options. Keep this in the same order than */
	    /* long_opts[] is. */
	    struct starter_config *cfg = read_cfg_file(optarg);

	    set_cfg_string(&pluto_log_file, cfg->setup.strings[KSF_PLUTOSTDERRLOG]);

	    fork_desired = cfg->setup.options[KBF_PLUTOFORK]; /* plutofork= */
	    log_with_timestamp =
		cfg->setup.options[KBF_PLUTOSTDERRLOGTIME];
	    force_busy = cfg->setup.options[KBF_FORCEBUSY];
	    strict_crl_policy = cfg->setup.options[KBF_STRICTCRLPOLICY];
	    crl_check_interval = cfg->setup.options[KBF_CRLCHECKINTERVAL];
	    uniqueIDs = cfg->setup.options[KBF_UNIQUEIDS];
	    /*
	     * We don't check interfaces= here because that part has been dealt
	     * with in _stackmanager before we started
	     */

	    set_cfg_string(&pluto_listen, cfg->setup.strings[KSF_LISTEN]);

	    pluto_port = cfg->setup.options[KBF_IKEPORT]; /* --ikeport */
	    /* no config option: ctlbase */
	    set_cfg_string(&pluto_shared_secrets_file, cfg->setup.strings[KSF_SECRETSFILE]); /* --secrets */
	    if(cfg->setup.strings[KSF_IPSECDIR] != NULL &&
		*cfg->setup.strings[KSF_IPSECDIR] != 0) {
			lsw_init_ipsecdir(cfg->setup.strings[KSF_IPSECDIR]); /* --ipsecdir */
	    }
	    set_cfg_string(&base_perpeer_logdir, cfg->setup.strings[KSF_PERPEERDIR]); /* --perpeerlogbase */
	    log_to_perpeer = cfg->setup.options[KBF_PERPEERLOG]; /* --perpeerlog */
	    no_retransmits = !cfg->setup.options[KBF_RETRANSMITS]; /* --noretransmits */
	    set_cfg_string(&coredir, cfg->setup.strings[KSF_DUMPDIR]); /* --dumpdir */
	    /* no config option: pluto_adns_option */
#ifdef NAT_TRAVERSAL
	    pluto_natt_float_port = cfg->setup.options[KBF_NATIKEPORT];
	    nat_traversal = cfg->setup.options[KBF_NATTRAVERSAL];
	    keep_alive = cfg->setup.options[KBF_KEEPALIVE];
	    force_keepalive = cfg->setup.options[KBF_FORCE_KEEPALIVE];
	    nat_t_spf = !cfg->setup.options[KBF_DISABLEPORTFLOATING];
#endif
	    set_cfg_string(&virtual_private,
			   cfg->setup.strings[KSF_VIRTUALPRIVATE]);
	    nhelpers = cfg->setup.options[KBF_NHELPERS];
#ifdef HAVE_LABELED_IPSEC
	    secctx_attr_value = cfg->setup.options[KBF_SECCTX];
#endif
#ifdef DEBUG
	    base_debugging = cfg->setup.options[KBF_PLUTODEBUG];
#endif
	    char *protostack = cfg->setup.strings[KSF_PROTOSTACK];
	    if (protostack == NULL || *protostack == 0)
	        kern_interface = USE_NETKEY;
	    else if (strcmp(protostack, "none") == 0)
		kern_interface = NO_KERNEL;
	    else if (strcmp(protostack, "auto") == 0)
		{
		    libreswan_log("The option protostack=auto is obsoleted, falling back to protostack=netkey\n");
		    kern_interface = USE_NETKEY;
		}
	    else if (strcmp(protostack, "klips") == 0)
		kern_interface = USE_KLIPS;
	    else if (strcmp(protostack, "mast") == 0)
		kern_interface = USE_MASTKLIPS;
	    else if (strcmp(protostack, "netkey") == 0 ||
		     strcmp(protostack, "native") == 0)
		kern_interface = USE_NETKEY;
	    else if (strcmp(protostack, "bsd") == 0 ||
		     strcmp(protostack, "kame") == 0 ||
		     strcmp(protostack, "bsdkame") == 0)
		kern_interface = USE_BSDKAME;
	    else if (strcmp(protostack, "win2k") == 0)
		kern_interface = USE_WIN2K;

	    confread_free(cfg);
	    continue;

	default:
#ifdef DEBUG
	    if (c >= DBG_OFFSET)
	    {
		base_debugging |= c - DBG_OFFSET;
		continue;
	    }
#	undef DBG_OFFSET
#endif
	    bad_case(c);
	}
	break;
    }
    if (optind != argc)
	usage("unexpected argument");
    reset_debugging();

#ifdef HAVE_NO_FORK
	fork_desired = FALSE;
	nhelpers = 0;
#endif

    /* default coredir to location compatible with SElinux */
    if(!coredir) {
	coredir = clone_str("/var/run/pluto", "coredir");
    }
    if(chdir(coredir) == -1) {
	int e = errno;
	libreswan_log("pluto: chdir() do dumpdir failed (%d: %s)\n",
	   e, strerror(e));
    }

    oco = lsw_init_options();
    lockfd = create_lock();

    /* select between logging methods */

    if (log_to_stderr_desired || log_to_file_desired) {
	log_to_syslog = FALSE;
    }
    if (!log_to_stderr_desired)
	   log_to_stderr = FALSE;

#ifdef DEBUG
#if 0
    if(kernel_ops->set_debug) {
	(*kernel_ops->set_debug)(cur_debugging, DBG_log, DBG_log);
    }
#endif
#endif

    /** create control socket.
     * We must create it before the parent process returns so that
     * there will be no race condition in using it.  The easiest
     * place to do this is before the daemon fork.
     */
    {
	err_t ugh = init_ctl_socket();

	if (ugh != NULL)
	{
	    fprintf(stderr, "pluto: %s", ugh);
	    exit_pluto(1);
	}
    }

    /* If not suppressed, do daemon fork */

    if (fork_desired)
    {
	{
	    pid_t pid = fork();

	    if (pid < 0)
	    {
		int e = errno;

		fprintf(stderr, "pluto: fork failed (%d %s)\n",
		    errno, strerror(e));
		exit_pluto(1);
	    }

	    if (pid != 0)
	    {
		/* parent: die, after filling PID into lock file.
		 * must not use exit_pluto: lock would be removed!
		 */
		exit(fill_lock(lockfd, pid)? 0 : 1);
	    }
	}

	if (setsid() < 0)
	{
	    int e = errno;

	    fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",
		errno, strerror(e));
	    exit_pluto(1);
	}
    }
    else
    {
	/* no daemon fork: we have to fill in lock file */
	(void) fill_lock(lockfd, getpid());
	if (isatty(fileno(stdout)))
	{
	    fprintf(stdout, "Pluto initialized\n");
	    fflush(stdout);
	}
    }

    /** Close everything but ctl_fd and (if needed) stderr.
     * There is some danger that a library that we don't know
     * about is using some fd that we don't know about.
     * I guess we'll soon find out.
     */
    {
	int i;

	for (i = getdtablesize() - 1; i >= 0; i--)  /* Bad hack */
	    if ((!log_to_stderr || i != 2)
	    && i != ctl_fd)
		close(i);

	/* make sure that stdin, stdout, stderr are reserved */
	if (open("/dev/null", O_RDONLY) != 0)
	    lsw_abort();
	if (dup2(0, 1) != 1)
	    lsw_abort();
	if (!log_to_stderr && dup2(0, 2) != 2)
	    lsw_abort();
    }

    init_constants();
    pluto_init_log();
    pluto_init_nss(oco->confddir);

#ifdef FIPS_CHECK
	const char *package_files[]= { IPSECLIBDIR"/setup",
				        IPSECLIBDIR"/addconn",
				        IPSECLIBDIR"/auto",
				        IPSECLIBDIR"/barf",
				        IPSECLIBDIR"/eroute",
  				        IPSECLIBDIR"/ikeping",
				        IPSECLIBDIR"/readwriteconf",
					IPSECLIBDIR"/_keycensor",
					IPSECLIBDIR"/klipsdebug",
					IPSECLIBDIR"/look",
					IPSECLIBDIR"/newhostkey",
					IPSECLIBDIR"/pf_key",
					IPSECLIBDIR"/_pluto_adns",
					IPSECLIBDIR"/_plutorun",
					IPSECLIBDIR"/ranbits",
					IPSECLIBDIR"/_realsetup",
					IPSECLIBDIR"/rsasigkey",
					IPSECLIBDIR"/pluto",
					IPSECLIBDIR"/_secretcensor",
					IPSECLIBDIR"/secrets",
					IPSECLIBDIR"/showhostkey",
					IPSECLIBDIR"/spi",
					IPSECLIBDIR"/spigrp",
					IPSECLIBDIR"/_stackmanager",
					IPSECLIBDIR"/tncfg",
					IPSECLIBDIR"/_updown",
					IPSECLIBDIR"/_updown.klips",
					IPSECLIBDIR"/_updown.mast",
					IPSECLIBDIR"/_updown.netkey",
					IPSECLIBDIR"/verify",
					IPSECLIBDIR"/whack",
					IPSECSBINDIR"/ipsec",
					NULL
					};

       if (Pluto_IsFIPS() && !FIPSCHECK_verify_files(package_files)) {
             loglog(RC_LOG_SERIOUS, "FATAL: FIPS integrity verification test failed");
             exit_pluto(10);
        }
#else
	libreswan_log("FIPS integrity support [disabled]");
#endif

#ifdef HAVE_LIBCAP_NG
	libreswan_log("libcap-ng support [enabled]");
#else
	libreswan_log("libcap-ng support [disabled]");
#endif

#ifdef USE_LINUX_AUDIT
	libreswan_log("Linux audit support [enabled]");
	/* test and log if audit is enabled on the system */
	int audit_fd, rc;
	audit_fd = audit_open();
	if (audit_fd < 0) {
                if (errno == EINVAL || errno == EPROTONOSUPPORT ||
                    errno == EAFNOSUPPORT)
		{
		 loglog(RC_LOG_SERIOUS, "Warning: kernel has no audit support");
		} else {
		loglog(RC_LOG_SERIOUS, "FATAL (SOON): audit_open() failed : %s", strerror(errno));
		 /* temp disabled exit_pluto(10); */
		}
	}
	rc = audit_log_acct_message(audit_fd, AUDIT_USER_START, NULL,
		"starting pluto daemon", NULL, -1, NULL, NULL, NULL, 1);
	close(audit_fd);
	if (rc < 0) {
		loglog(RC_LOG_SERIOUS, "FATAL: audit_log_acct_message failed: %s", strerror(errno));
		 exit_pluto(10);
	}
#else
	libreswan_log("Linux audit support [disabled]");
#endif

    /* Note: some scripts may look for this exact message -- don't change
     * ipsec barf was one, but it no longer does.
     */
    {
	const char *vc = ipsec_version_code();
#ifdef PLUTO_SENDS_VENDORID
	const char *v = init_pluto_vendorid();
	libreswan_log("Starting Pluto (Libreswan Version %s%s; Vendor ID %s) pid:%u"
		     , vc, compile_time_interop_options, v, getpid());
#else
	libreswan_log("Starting Pluto (Libreswan Version %s%s) pid:%u"
		     , vc, compile_time_interop_options, getpid());
#endif
	if(Pluto_IsFIPS()) {
		libreswan_log("Pluto is running in FIPS mode");
	} else {
		libreswan_log("Pluto is NOT running in FIPS mode");
	}

	if((vc[0]=='c' && vc[1]=='v' && vc[2]=='s') ||
	   (vc[2]=='g' && vc[3]=='i' && vc[4]=='t')) {
	    /*
	     * when people build RPMs from CVS or GIT, make sure they
	     * get blamed appropriately, and that we get some way to
	     * identify who did it, and when they did it. Use string concat,
	     * so that strings the binary can or classic SCCS "what", will find
	     * stuff too.
	     */
	    libreswan_log("@(#) built on "__DATE__":" __TIME__ " by " BUILDER);
	}
#if defined(USE_1DES)
	libreswan_log("WARNING: 1DES is enabled");
#endif
    }

    if(coredir) {
	libreswan_log("core dump dir: %s", coredir);
    }
    if(pluto_shared_secrets_file) {
	libreswan_log("secrets file: %s", pluto_shared_secrets_file);
    }

#ifdef LEAK_DETECTIVE
	libreswan_log("LEAK_DETECTIVE support [enabled]");
#else
	libreswan_log("LEAK_DETECTIVE support [disabled]");
#endif

#ifdef HAVE_OCF
       {
        struct stat buf;
	errno=0;

	if( stat("/dev/crypto",&buf) != -1)
		libreswan_log("OCF support for IKE via /dev/crypto [enabled]");
	else
		libreswan_log("OCF support for IKE via /dev/crypto [failed:%s]", strerror(errno));
       }
#else
	libreswan_log("OCF support for IKE [disabled]");
#endif

   /* Check for SAREF support */
#ifdef KLIPS_MAST
#include <ipsec_saref.h>
    {
	int e, sk, saref;
	saref = 1;
	errno=0;

	sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	e = setsockopt(sk, IPPROTO_IP, IP_IPSEC_REFINFO, &saref, sizeof(saref));
	if (e == -1 ) {
		libreswan_log("SAref support [disabled]: %s" , strerror(errno));
	}
	else {
		libreswan_log("SAref support [enabled]");
	}
	errno=0;
	e = setsockopt(sk, IPPROTO_IP, IP_IPSEC_BINDREF, &saref, sizeof(saref));
	if (e == -1 ) {
		libreswan_log("SAbind support [disabled]: %s" , strerror(errno));
	}
	else {
		libreswan_log("SAbind support [enabled]");
	}


	close(sk);
    }
#endif

	libreswan_log("NSS crypto [enabled]");

#ifdef XAUTH_HAVE_PAM
	libreswan_log("XAUTH PAM support [enabled]");
#else
	libreswan_log("XAUTH PAM support [disabled]");
#endif

#ifdef HAVE_STATSD
	libreswan_log("HAVE_STATSD notification via /bin/libreswan-statsd enabled");
#else
	libreswan_log("HAVE_STATSD notification support [disabled]");
#endif


/** Log various impair-* functions if they were enabled */

    if(DBGP(IMPAIR_BUST_MI2))
	libreswan_log("Warning: IMPAIR_BUST_MI2 enabled");
    if(DBGP(IMPAIR_BUST_MR2))
	libreswan_log("Warning: IMPAIR_BUST_MR2 enabled");
    if(DBGP(IMPAIR_SA_CREATION))
	libreswan_log("Warning: IMPAIR_SA_CREATION enabled");
    if(DBGP(IMPAIR_JACOB_TWO_TWO))
	libreswan_log("Warning: IMPAIR_JACOB_TWO_TWO enabled");
    if(DBGP(IMPAIR_DIE_ONINFO))
	libreswan_log("Warning: IMPAIR_DIE_ONINFO enabled");
    if(DBGP(IMPAIR_MAJOR_VERSION_BUMP))
	libreswan_log("Warning: IMPAIR_MAJOR_VERSION_BUMP enabled");
    if(DBGP(IMPAIR_MINOR_VERSION_BUMP))
	libreswan_log("Warning: IMPAIR_MINOR_VERSION_BUMP enabled");
    if(DBGP(IMPAIR_RETRANSMITS))
	libreswan_log("Warning: IMPAIR_RETRANSMITS enabled");
    if(DBGP(IMPAIR_SEND_BOGUS_ISAKMP_FLAG))
	libreswan_log("Warning: IMPAIR_SEND_BOGUS_ISAKMP_FLAG enabled");
    if(DBGP(IMPAIR_DELAY_ADNS_KEY_ANSWER))
	libreswan_log("Warning: IMPAIR_DELAY_ADNS_KEY_ANSWER enabled");
    if(DBGP(IMPAIR_DELAY_ADNS_TXT_ANSWER))
	libreswan_log("Warning: IMPAIR_DELAY_ADNS_TXT_ANSWER enabled");

/** Initialize all of the various features */

#ifdef NAT_TRAVERSAL
    init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
#endif

    init_virtual_ip(virtual_private);
    /* obsoletd by nss code init_rnd_pool(); */
    init_timer();
    init_secret();
    init_states();
    init_connections();
    init_crypto();
    init_crypto_helpers(nhelpers);
    load_lswcrypto();
    init_demux();
    init_kernel();
    init_adns();
    init_id();

#ifdef TPM
    init_tpm();
#endif

#if defined(LIBCURL) || defined(LDAP_VER)
    init_fetch();
#endif

    /* loading X.509 CA certificates */
    load_authcerts("CA cert", oco->cacerts_dir, AUTH_CA);
#if 0
    /* unused */
    /* loading X.509 AA certificates */
    load_authcerts("AA cert", oco->aacerts_dir, AUTH_AA);
#endif

    /* loading X.509 CRLs */
    load_crls();
    /* loading attribute certificates (experimental) */
    load_acerts();

    /*Loading CA certs from NSS DB*/
    load_authcerts_from_nss("CA cert",  AUTH_CA);

#ifdef HAVE_LABELED_IPSEC
    init_avc();
#endif

    daily_log_event();
    call_server();
    return -1;	/* Shouldn't ever reach this */
}