Example #1
0
/* construct a string to name the bits on in a set
 * Result of bitnamesof may be in STATIC buffer -- NOT RE-ENTRANT!
 * Note: prettypolicy depends on internal details of bitnamesofb.
 * binamesofb is re-entrant since the caller provides the buffer.
 */
const char *bitnamesofb(const char *const table[], lset_t val,
			char *b, size_t blen)
{
	char *const roof = b + blen;
	char *p = b;
	lset_t bit;
	const char *const *tp;

	passert(blen != 0); /* need room for NUL */

	/* if nothing gets filled in, default to "none" rather than "" */
	(void) jam_str(p, (size_t)(roof - p), "none");

	for (tp = table, bit = 01; val != 0; bit <<= 1) {
		if (val & bit) {
			const char *n = *tp;

			if (p != b)
				p = jam_str(p, (size_t)(roof - p), "+");

			if (n == NULL || *n == '\0') {
				/* No name for this bit, so use hex.
				 * if snprintf returns a different value from strlen, trunation happened
				 */
				(void)snprintf(p, (size_t)(roof - p), "0x%" PRIxLSET,
					       bit);
				p += strlen(p);
			} else {
				p = jam_str(p, (size_t)(roof - p), n);
			}
			val -= bit;
		}
		/* Move on in the table, but not past end.
		 * This is a bit of a trick: while we are at stuck the end,
		 * the loop will print out the remaining bits in hex.
		 */
		if (*tp != NULL)
			tp++;
	}
	return b;
}
Example #2
0
/*
 * format a string for the log, with suitable prefixes.
 * A format starting with ~ indicates that this is a reprocessing
 * of the message, so prefixing and quoting is suppressed.
 */
static void fmt_log(char *buf, size_t buf_len,
		const char *fmt, va_list ap)
{
	bool reproc = *fmt == '~';
	char *p = buf;

	buf[0] = '\0';
	if (reproc) {
		fmt++;	/* ~ at start of format suppresses this prefix */
	} else if (progname != NULL && (strlen(progname) + 1 + 1) < buf_len) {
		/* start with name of connection */
		p = add_str(buf, buf_len, jam_str(buf, buf_len, progname), " ");
	}
	vsnprintf(p, buf_len - (p - buf), fmt, ap);
	if (!reproc)
		sanitize_string(buf, buf_len);
}
Example #3
0
/*
 * print which ESP algorithm has actually been selected, based upon which
 * ones are actually loaded.
 */
static void alg_info_snprint_esp(char *buf, size_t buflen,
				 struct alg_info_esp *alg_info)
{
	char *ptr = buf;
	int ret;
	struct esp_info *esp_info;
	int cnt;
	const char *sep = "";

	passert(buflen >= sizeof("none"));

	ptr = buf;
	jam_str(buf, buflen, "none");

	ALG_INFO_ESP_FOREACH(alg_info, esp_info, cnt) {
		err_t ugh = check_kernel_encrypt_alg(esp_info->transid, 0);

		if (ugh != NULL) {
			DBG_log("esp algid=%d not available: %s",
				esp_info->transid, ugh);
			continue;
		}

		if (!kernel_alg_esp_auth_ok(esp_info->auth, NULL)) {
			DBG_log("auth algid=%d not available",
				esp_info->auth);
			continue;
		}

		ret = snprint_esp_info(ptr, buflen, sep, esp_info);

		if (ret < 0 || (size_t)ret >= buflen) {
			DBG_log("alg_info_snprint_esp: buffer too short for snprintf");
			break;
		}
		ptr += ret;
		buflen -= ret;
		sep = ", ";
	}
Example #4
0
int main(int argc, char *argv[])
{
	int opt = 0;
	int autoall = 0;
	int configsetup = 0;
	int checkconfig = 0;
	char *export = "export"; /* display export before the foo=bar or not */
	int listroute = 0, liststart = 0, listignore = 0, listadd = 0,
		listall = 0, dolist = 0, liststack = 0;
	struct starter_config *cfg = NULL;
	err_t err = NULL;
	char *confdir = NULL;
	char *configfile = NULL;
	char *varprefix = "";
	int exit_status = 0;
	struct starter_conn *conn = NULL;
	char *ctlbase = NULL;
	bool resolvip = TRUE; /* default to looking up names */

#if 0
	/* efence settings */
	extern int EF_PROTECT_BELOW;
	extern int EF_PROTECT_FREE;

	EF_PROTECT_BELOW = 1;
	EF_PROTECT_FREE = 1;
#endif

	progname = argv[0];
	rootdir[0] = '\0';

	tool_init_log();

	while ((opt = getopt_long(argc, argv, "", longopts, 0)) != EOF) {
		switch (opt) {
		case 'h':
			/* usage: */
			usage();
			break;

		case 'a':
			autoall = 1;
			break;

		case 'D':
			verbose++;
			lex_verbosity++;
			break;

		case 'T':
			configsetup++;
			break;

		case 'K':
			checkconfig++;
			break;

		case 'N':
			export = "";
			break;

		case 'C':
			configfile = clone_str(optarg, "config file name");
			break;

		case 'c':
			ctlbase = clone_str(optarg, "control base");
			break;

		case 'L':
			listadd = 1;
			dolist = 1;
			break;

		case 'r':
			listroute = 1;
			dolist = 1;
			break;

		case 's':
			liststart = 1;
			dolist = 1;
			break;

		case 'S':
			liststack = 1;
			dolist = 1;
			break;

		case 'i':
			listignore = 1;
			dolist = 1;
			break;

		case 'A':
			listall = 1;
			dolist = 1;
			break;

		case 'P':
			varprefix = optarg;
			break;

		case 'R':
			printf("setting rootdir=%s\n", optarg);
			jam_str(rootdir, sizeof(rootdir), optarg);
			break;

		case 'd':
		case 'n':
			printf("Warning: options --defaultroute and --defaultroutenexthop are obsolete and were ignored\n");
			break;

		default:
			usage();
		}
	}

	/* if nothing to add, then complain */
	if (optind == argc && !autoall && !dolist && !configsetup &&
		!checkconfig)
		usage();

	if (verbose > 3) {
		yydebug = 1;
	}

	/* find config file */
	if (confdir == NULL)
		confdir = IPSEC_CONFDIR;

	if (configfile == NULL) {
		/* ??? see code clone in programs/readwriteconf/readwriteconf.c */
		configfile = alloc_bytes(strlen(confdir) +
					 sizeof("/ipsec.conf"),
					 "conf file");

		/* calculate default value for configfile */
		strcpy(configfile, confdir);	/* safe: see allocation above */
		if (configfile[0] != '\0' && configfile[strlen(configfile) - 1] != '/')
			strcat(configfile, "/");	/* safe: see allocation above */
		strcat(configfile, "ipsec.conf");	/* safe: see allocation above */
	}

	if (verbose)
		printf("opening file: %s\n", configfile);

	starter_use_log(verbose != 0, TRUE, verbose == 0);

	err = NULL;	/* reset to no error */

	if (configsetup || checkconfig || dolist) {
		/* skip if we have no use for them... causes delays */
		resolvip = FALSE;
	}

	cfg = confread_load(configfile, &err, resolvip, ctlbase, configsetup);

	if (cfg == NULL) {
		fprintf(stderr, "cannot load config '%s': %s\n",
			configfile, err);
		exit(3);
	} else if (checkconfig) {
		confread_free(cfg);
		exit(0);
	}

	if (autoall) {
		if (verbose)
			printf("loading all conns according to their auto= settings\n");


		/*
		 * Load all conns marked as auto=add or better.
		 * First, do the auto=route and auto=add conns to quickly
		 * get routes in place, then do auto=start as these can be
		 * slower.
		 * This mimics behaviour of the old _plutoload
		 */
		if (verbose)
			printf("  Pass #1: Loading auto=add, auto=route and auto=start connections\n");


		for (conn = cfg->conns.tqh_first;
			conn != NULL;
			conn = conn->link.tqe_next) {
			if (conn->desired_state == STARTUP_ADD ||
				conn->desired_state == STARTUP_ONDEMAND ||
				conn->desired_state == STARTUP_START) {
				if (verbose)
					printf(" %s", conn->name);
				starter_whack_add_conn(cfg, conn);
			}
		}

		/*
		 * We loaded all connections. Now tell pluto to listen,
		 * then route the conns and resolve default route.
		 */
		starter_whack_listen(cfg);

		if (verbose)
			printf("  Pass #2: Routing auto=route and auto=start connections\n");

		for (conn = cfg->conns.tqh_first;
			conn != NULL;
			conn = conn->link.tqe_next) {
			if (conn->desired_state == STARTUP_ADD ||
				conn->desired_state == STARTUP_ONDEMAND ||
				conn->desired_state == STARTUP_START) {
				if (verbose)
					printf(" %s", conn->name);
				resolve_defaultroute(conn);
				if (conn->desired_state == STARTUP_ONDEMAND ||
				    conn->desired_state == STARTUP_START) {
					starter_whack_route_conn(cfg, conn);
				}
			}
		}

		if (verbose)
			printf("  Pass #3: Initiating auto=start connections\n");

		for (conn = cfg->conns.tqh_first;
			conn != NULL;
			conn = conn->link.tqe_next) {
			if (conn->desired_state == STARTUP_START) {
				if (verbose)
					printf(" %s", conn->name);
				starter_whack_initiate_conn(cfg, conn);
			}
		}

		if (verbose)
			printf("\n");
	} else {
		/* load named conns, regardless of their state */
		int connum;

		if (verbose)
			printf("loading named conns:");
		for (connum = optind; connum < argc; connum++) {
			char *connname = argv[connum];

			if (verbose)
				printf(" %s", connname);
			for (conn = cfg->conns.tqh_first;
				conn != NULL;
				conn = conn->link.tqe_next) {
				if (streq(conn->name, connname)) {
					if (conn->state == STATE_ADDED) {
						printf("\nconn %s already added\n",
							conn->name);
					} else if (conn->state ==
						STATE_FAILED) {
						printf("\nconn %s did not load properly\n",
							conn->name);
					} else {
						resolve_defaultroute(conn);
						exit_status =
							starter_whack_add_conn(
								cfg,
								conn);
						conn->state = STATE_ADDED;
					}
					break;
				}
			}

			if (conn == NULL) {
				/*
				 * only if we don't find it, do we now look
				 * for aliases
				 */
				for (conn = cfg->conns.tqh_first;
					conn != NULL;
					conn = conn->link.tqe_next) {
					if (conn->strings_set[KSF_CONNALIAS] &&
						lsw_alias_cmp(connname,
							conn->
							strings[KSF_CONNALIAS]
							)) {

						if (conn->state ==
							STATE_ADDED) {
							printf("\nalias: %s conn %s already added\n",
								connname,
								conn->name);
						} else if (conn->state ==
							STATE_FAILED) {
							printf("\nalias: %s conn %s did not load properly\n",
								connname,
								conn->name);
						} else {
							resolve_defaultroute(
								conn);
							exit_status =
								starter_whack_add_conn(
									cfg,
									conn);
							conn->state =
								STATE_ADDED;
						}
						break;
					}
				}
			}

			if (conn == NULL) {
				exit_status++;
				if (!verbose) {
					printf("conn '%s': not found (tried aliases)\n",
						connname);
				} else {
					printf(" (notfound)\n");
				}
			}
		}
	}

	if (listall) {
		if (verbose)
			printf("listing all conns\n");
		for (conn = cfg->conns.tqh_first;
			conn != NULL;
			conn = conn->link.tqe_next)
			printf("%s ", conn->name);
		printf("\n");
	} else {

		if (listadd) {
			if (verbose)
				printf("listing all conns marked as auto=add\n");


			/* list all conns marked as auto=add */
			for (conn = cfg->conns.tqh_first;
				conn != NULL;
				conn = conn->link.tqe_next) {
				if (conn->desired_state == STARTUP_ADD)
					printf("%s ", conn->name);
			}
		}
		if (listroute) {
			if (verbose)
				printf("listing all conns marked as auto=route and auto=start\n");


			/*
			 * list all conns marked as auto=route or start or
			 * better
			 */
			for (conn = cfg->conns.tqh_first;
				conn != NULL;
				conn = conn->link.tqe_next) {
				if (conn->desired_state == STARTUP_START ||
					conn->desired_state == STARTUP_ONDEMAND)
					printf("%s ", conn->name);
			}
		}

		if (liststart && !listroute) {
			if (verbose)
				printf("listing all conns marked as auto=start\n");


			/* list all conns marked as auto=start */
			for (conn = cfg->conns.tqh_first;
				conn != NULL;
				conn = conn->link.tqe_next) {
				if (conn->desired_state == STARTUP_START)
					printf("%s ", conn->name);
			}
		}

		if (listignore) {
			if (verbose)
				printf("listing all conns marked as auto=ignore\n");


			/* list all conns marked as auto=start */
			for (conn = cfg->conns.tqh_first;
				conn != NULL;
				conn = conn->link.tqe_next) {
				if (conn->desired_state == STARTUP_IGNORE)
					printf("%s ", conn->name);
			}
			printf("\n");
		}
	}

	if (liststack) {
		const struct keyword_def *kd;

		for (kd = ipsec_conf_keywords_v2; kd->keyname != NULL; kd++) {
			if (strstr(kd->keyname, "protostack")) {
				if (cfg->setup.strings[kd->field])
					printf("%s\n",
						cfg->setup.strings[kd->field]);
				else
					/* implicit default */
					printf("netkey\n");
			}

		}
		confread_free(cfg);
		exit(0);
	}

	if (configsetup) {
		const struct keyword_def *kd;

		printf("%s %sconfreadstatus=''\n", export, varprefix);
		for (kd = ipsec_conf_keywords_v2; kd->keyname != NULL; kd++) {
			if ((kd->validity & kv_config) == 0)
				continue;

			switch (kd->type) {
			case kt_string:
			case kt_filename:
			case kt_dirname:
			case kt_loose_enum:
				if (cfg->setup.strings[kd->field]) {
					printf("%s %s%s='%s'\n",
						export, varprefix, kd->keyname,
						cfg->setup.strings[kd->field]);
				}
				break;

			case kt_bool:
				printf("%s %s%s='%s'\n", export, varprefix,
					kd->keyname,
					cfg->setup.options[kd->field] ?
					"yes" : "no");
				break;

			case kt_list:
				printf("%s %s%s='",
					export, varprefix, kd->keyname);
				confwrite_list(stdout, "",
					cfg->setup.options[kd->field],
					kd);
				printf("'\n");
				break;

			case kt_obsolete:
				printf("# obsolete option '%s%s' ignored\n",
					varprefix, kd->keyname);
				break;

			default:
				if (cfg->setup.options[kd->field] ||
					cfg->setup.options_set[kd->field]) {
					printf("%s %s%s='%d'\n",
						export, varprefix, kd->keyname,
						cfg->setup.options[kd->field]);
				}
				break;
			}
		}
Example #5
0
int main(int argc, char *argv[])
{
	int opt = 0;
	struct starter_config *cfg = NULL;
	err_t err = NULL;
	char *confdir = NULL;
	char *configfile = NULL;
	struct starter_conn *conn = NULL;

	progname = argv[0];
	rootdir[0] = '\0';
	rootdir2[0] = '\0';

	tool_init_log();

	while ((opt = getopt_long(argc, argv, "", longopts, 0)) != EOF) {
		switch (opt) {
		case 'h':
			/* usage: */
			usage();
			break;

		case 'D':
			verbose++;
			lex_verbosity++;
			break;

		case 'C':
			configfile = clone_str(optarg, "config file name");
			break;

		case 'R':
			printf("#setting rootdir=%s\n", optarg);
			jam_str(rootdir, sizeof(rootdir), optarg);
			break;

		case 'S':
			printf("#setting rootdir2=%s\n", optarg);
			jam_str(rootdir2, sizeof(rootdir2), optarg);
			break;
		case '?':
			exit(5);
		default:
			fprintf(stderr, "%s: getopt returned %d\n", progname, opt);
			exit(6);
		}
	}

	if (optind != argc) {
		fprintf(stderr,"%s: unexpected arguments\n",
			progname);
		exit(4);
	}

	/* find config file */
	if (confdir == NULL)
		confdir = IPSEC_CONFDIR;

	if (configfile == NULL) {
		/* ??? see code clone in programs/addconn/addconn.c */
		configfile = alloc_bytes(strlen(confdir) +
					 sizeof("/ipsec.conf"),
					 "conf file");

		/* calculate default value for configfile */
		strcpy(configfile, confdir);	/* safe: see allocation above */
		if (configfile[0] != '\0' && configfile[strlen(configfile) - 1] != '/')
			strcat(configfile, "/");	/* safe: see allocation above */
		strcat(configfile, "ipsec.conf");	/* safe: see allocation above */
	}

	if (verbose > 3) {
		yydebug = 1;
	}

	if (verbose)
		printf("opening file: %s\n", configfile);

	starter_use_log(verbose != 0, TRUE, verbose == 0);

	cfg = confread_load(configfile, &err, FALSE, NULL, FALSE);

	if (cfg == NULL) {
		fprintf(stderr, "%s: config file \"%s\" cannot be loaded: %s\n",
			progname, configfile, err);
		exit(3);
	}

	/* load all conns marked as auto=add or better */
	for (conn = cfg->conns.tqh_first;
	     conn != NULL;
	     conn = conn->link.tqe_next)
		printf("#conn %s loaded\n", conn->name);

	confwrite(cfg, stdout);
	confread_free(cfg);
	exit(0);
}