summaryrefslogtreecommitdiff
path: root/src/swanctl
diff options
context:
space:
mode:
Diffstat (limited to 'src/swanctl')
-rw-r--r--src/swanctl/Makefile.am1
-rw-r--r--src/swanctl/Makefile.in12
-rw-r--r--src/swanctl/command.h2
-rw-r--r--src/swanctl/commands/initiate.c12
-rw-r--r--src/swanctl/commands/install.c15
-rw-r--r--src/swanctl/commands/list_pools.c14
-rw-r--r--src/swanctl/commands/list_sas.c23
-rw-r--r--src/swanctl/commands/load_authorities.c8
-rw-r--r--src/swanctl/commands/load_conns.c67
-rw-r--r--src/swanctl/commands/load_creds.c377
-rw-r--r--src/swanctl/commands/rekey.c125
-rw-r--r--src/swanctl/swanctl.8.in3
-rw-r--r--src/swanctl/swanctl.conf123
-rw-r--r--src/swanctl/swanctl.conf.5.head.in3
-rw-r--r--src/swanctl/swanctl.conf.5.main253
-rw-r--r--src/swanctl/swanctl.opt223
16 files changed, 1109 insertions, 152 deletions
diff --git a/src/swanctl/Makefile.am b/src/swanctl/Makefile.am
index 9ca759ea3..2fc998262 100644
--- a/src/swanctl/Makefile.am
+++ b/src/swanctl/Makefile.am
@@ -4,6 +4,7 @@ swanctl_SOURCES = \
command.c command.h \
commands/initiate.c \
commands/terminate.c \
+ commands/rekey.c \
commands/redirect.c \
commands/install.c \
commands/list_sas.c \
diff --git a/src/swanctl/Makefile.in b/src/swanctl/Makefile.in
index ff9dca09d..7e2a1da6b 100644
--- a/src/swanctl/Makefile.in
+++ b/src/swanctl/Makefile.in
@@ -113,9 +113,9 @@ am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man5dir)" \
PROGRAMS = $(sbin_PROGRAMS)
am__dirstamp = $(am__leading_dot)dirstamp
am_swanctl_OBJECTS = command.$(OBJEXT) commands/initiate.$(OBJEXT) \
- commands/terminate.$(OBJEXT) commands/redirect.$(OBJEXT) \
- commands/install.$(OBJEXT) commands/list_sas.$(OBJEXT) \
- commands/list_pols.$(OBJEXT) \
+ commands/terminate.$(OBJEXT) commands/rekey.$(OBJEXT) \
+ commands/redirect.$(OBJEXT) commands/install.$(OBJEXT) \
+ commands/list_sas.$(OBJEXT) commands/list_pols.$(OBJEXT) \
commands/list_authorities.$(OBJEXT) \
commands/list_conns.$(OBJEXT) commands/list_certs.$(OBJEXT) \
commands/list_pools.$(OBJEXT) commands/list_algs.$(OBJEXT) \
@@ -377,7 +377,6 @@ exec_prefix = @exec_prefix@
fips_mode = @fips_mode@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
-h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -412,6 +411,7 @@ nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
nm_plugins = @nm_plugins@
oldincludedir = @oldincludedir@
+p_plugins = @p_plugins@
pcsclite_CFLAGS = @pcsclite_CFLAGS@
pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
@@ -465,6 +465,7 @@ swanctl_SOURCES = \
command.c command.h \
commands/initiate.c \
commands/terminate.c \
+ commands/rekey.c \
commands/redirect.c \
commands/install.c \
commands/list_sas.c \
@@ -603,6 +604,8 @@ commands/initiate.$(OBJEXT): commands/$(am__dirstamp) \
commands/$(DEPDIR)/$(am__dirstamp)
commands/terminate.$(OBJEXT): commands/$(am__dirstamp) \
commands/$(DEPDIR)/$(am__dirstamp)
+commands/rekey.$(OBJEXT): commands/$(am__dirstamp) \
+ commands/$(DEPDIR)/$(am__dirstamp)
commands/redirect.$(OBJEXT): commands/$(am__dirstamp) \
commands/$(DEPDIR)/$(am__dirstamp)
commands/install.$(OBJEXT): commands/$(am__dirstamp) \
@@ -672,6 +675,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/load_pools.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/log.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/redirect.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/rekey.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/reload_settings.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/stats.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/terminate.Po@am__quote@
diff --git a/src/swanctl/command.h b/src/swanctl/command.h
index 7b92ae91a..c17811498 100644
--- a/src/swanctl/command.h
+++ b/src/swanctl/command.h
@@ -27,7 +27,7 @@
/**
* Maximum number of commands (+1).
*/
-#define MAX_COMMANDS 24
+#define MAX_COMMANDS 25
/**
* Maximum number of options in a command (+3)
diff --git a/src/swanctl/commands/initiate.c b/src/swanctl/commands/initiate.c
index eb7b6adbd..8e452a6f6 100644
--- a/src/swanctl/commands/initiate.c
+++ b/src/swanctl/commands/initiate.c
@@ -37,7 +37,7 @@ static int initiate(vici_conn_t *conn)
vici_req_t *req;
vici_res_t *res;
command_format_options_t format = COMMAND_FORMAT_NONE;
- char *arg, *child = NULL;
+ char *arg, *child = NULL, *ike = NULL;
int ret = 0, timeout = 0, level = 1;
while (TRUE)
@@ -55,6 +55,9 @@ static int initiate(vici_conn_t *conn)
case 'c':
child = arg;
continue;
+ case 'i':
+ ike = arg;
+ continue;
case 't':
timeout = atoi(arg);
continue;
@@ -80,6 +83,10 @@ static int initiate(vici_conn_t *conn)
{
vici_add_key_valuef(req, "child", "%s", child);
}
+ if (ike)
+ {
+ vici_add_key_valuef(req, "ike", "%s", ike);
+ }
if (timeout)
{
vici_add_key_valuef(req, "timeout", "%d", timeout * 1000);
@@ -121,10 +128,11 @@ static void __attribute__ ((constructor))reg()
{
command_register((command_t) {
initiate, 'i', "initiate", "initiate a connection",
- {"--child <name> [--timeout <s>] [--raw|--pretty]"},
+ {"--child <name> [--ike <name>] [--timeout <s>] [--raw|--pretty]"},
{
{"help", 'h', 0, "show usage information"},
{"child", 'c', 1, "initate a CHILD_SA configuration"},
+ {"ike", 'i', 1, "name of the connection to which the child belongs"},
{"timeout", 't', 1, "timeout in seconds before detaching"},
{"raw", 'r', 0, "dump raw response message"},
{"pretty", 'P', 0, "dump raw response message in pretty print"},
diff --git a/src/swanctl/commands/install.c b/src/swanctl/commands/install.c
index 59c5c24ab..24a397b87 100644
--- a/src/swanctl/commands/install.c
+++ b/src/swanctl/commands/install.c
@@ -22,7 +22,7 @@ static int manage_policy(vici_conn_t *conn, char *label)
vici_req_t *req;
vici_res_t *res;
command_format_options_t format = COMMAND_FORMAT_NONE;
- char *arg, *child = NULL;
+ char *arg, *child = NULL, *ike = NULL;
int ret = 0;
while (TRUE)
@@ -40,6 +40,9 @@ static int manage_policy(vici_conn_t *conn, char *label)
case 'c':
child = arg;
continue;
+ case 'i':
+ ike = arg;
+ continue;
case EOF:
break;
default:
@@ -52,6 +55,10 @@ static int manage_policy(vici_conn_t *conn, char *label)
{
vici_add_key_valuef(req, "child", "%s", child);
}
+ if (ike)
+ {
+ vici_add_key_valuef(req, "ike", "%s", ike);
+ }
res = vici_submit(req, conn);
if (!res)
{
@@ -98,10 +105,11 @@ static void __attribute__ ((constructor))reg_uninstall()
{
command_register((command_t) {
uninstall, 'u', "uninstall", "uninstall a trap or shunt policy",
- {"--child <name> [--raw|--pretty]"},
+ {"--child <name> [--ike <name>] [--raw|--pretty]"},
{
{"help", 'h', 0, "show usage information"},
{"child", 'c', 1, "CHILD_SA configuration to uninstall"},
+ {"ike", 'i', 1, "name of the connection to which the child belongs"},
{"raw", 'r', 0, "dump raw response message"},
{"pretty", 'P', 0, "dump raw response message in pretty print"},
}
@@ -115,10 +123,11 @@ static void __attribute__ ((constructor))reg_install()
{
command_register((command_t) {
install, 'p', "install", "install a trap or shunt policy",
- {"--child <name> [--raw|--pretty]"},
+ {"--child <name> [--ike <name>] [--raw|--pretty]"},
{
{"help", 'h', 0, "show usage information"},
{"child", 'c', 1, "CHILD_SA configuration to install"},
+ {"ike", 'i', 1, "name of the connection to which the child belongs"},
{"raw", 'r', 0, "dump raw response message"},
{"pretty", 'P', 0, "dump raw response message in pretty print"},
}
diff --git a/src/swanctl/commands/list_pools.c b/src/swanctl/commands/list_pools.c
index 429107e17..a170adeba 100644
--- a/src/swanctl/commands/list_pools.c
+++ b/src/swanctl/commands/list_pools.c
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2015 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2015-2016 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2014 Martin Willi
* Copyright (C) 2014 revosec AG
@@ -58,7 +58,7 @@ static int list_pools(vici_conn_t *conn)
vici_req_t *req;
vici_res_t *res;
command_format_options_t format = COMMAND_FORMAT_NONE;
- char *arg;
+ char *arg, *name = NULL;
int ret = 0;
bool leases = FALSE;
@@ -77,6 +77,9 @@ static int list_pools(vici_conn_t *conn)
case 'l':
leases = TRUE;
continue;
+ case 'n':
+ name = arg;
+ continue;
case EOF:
break;
default:
@@ -90,6 +93,10 @@ static int list_pools(vici_conn_t *conn)
{
vici_add_key_valuef(req, "leases", "yes");
}
+ if (name)
+ {
+ vici_add_key_valuef(req, "name", "%s", name);
+ }
res = vici_submit(req, conn);
if (!res)
{
@@ -123,6 +130,7 @@ static void __attribute__ ((constructor))reg()
{"raw", 'r', 0, "dump raw response message"},
{"pretty", 'P', 0, "dump raw response message in pretty print"},
{"leases", 'l', 0, "list leases of each pool"},
+ {"name", 'n', 1, "filter pools by name"},
}
});
}
diff --git a/src/swanctl/commands/list_sas.c b/src/swanctl/commands/list_sas.c
index e5f251d17..28602fc65 100644
--- a/src/swanctl/commands/list_sas.c
+++ b/src/swanctl/commands/list_sas.c
@@ -112,8 +112,9 @@ CALLBACK(child_sas, int,
if (ret == 0)
{
printf(" %s: #%s, reqid %s, %s, %s%s, %s:",
- name, child->get(child, "uniqueid"), child->get(child, "reqid"),
- child->get(child, "state"), child->get(child, "mode"),
+ child->get(child, "name"), child->get(child, "uniqueid"),
+ child->get(child, "reqid"), child->get(child, "state"),
+ child->get(child, "mode"),
child->get(child, "encap") ? "-in-UDP" : "",
child->get(child, "protocol"));
@@ -165,6 +166,15 @@ CALLBACK(child_sas, int,
printf(" in %s%s%s", child->get(child, "spi-in"),
child->get(child, "cpi-in") ? "/" : "",
child->get(child, "cpi-in") ?: "");
+ if (child->get(child, "mark-in"))
+ {
+ printf(" (0x%s", child->get(child, "mark-in"));
+ if (child->get(child, "mark-mask-in"))
+ {
+ printf("/0x%s", child->get(child, "mark-mask-in"));
+ }
+ printf(")");
+ }
printf(", %6s bytes, %5s packets",
child->get(child, "bytes-in"), child->get(child, "packets-in"));
if (child->get(child, "use-in"))
@@ -176,6 +186,15 @@ CALLBACK(child_sas, int,
printf(" out %s%s%s", child->get(child, "spi-out"),
child->get(child, "cpi-out") ? "/" : "",
child->get(child, "cpi-out") ?: "");
+ if (child->get(child, "mark-out"))
+ {
+ printf(" (0x%s", child->get(child, "mark-out"));
+ if (child->get(child, "mark-mask-out"))
+ {
+ printf("/0x%s", child->get(child, "mark-mask-out"));
+ }
+ printf(")");
+ }
printf(", %6s bytes, %5s packets",
child->get(child, "bytes-out"), child->get(child, "packets-out"));
if (child->get(child, "use-out"))
diff --git a/src/swanctl/commands/load_authorities.c b/src/swanctl/commands/load_authorities.c
index 352a185e8..8947866f5 100644
--- a/src/swanctl/commands/load_authorities.c
+++ b/src/swanctl/commands/load_authorities.c
@@ -86,18 +86,18 @@ static bool add_key_values(vici_req_t *req, settings_t *cfg, char *section)
enumerator = cfg->create_key_value_enumerator(cfg, section);
while (enumerator->enumerate(enumerator, &key, &value))
{
- /* pool subnet is encoded as key/value, all other attributes as list */
if (streq(key, "cacert"))
{
ret = add_file_key_value(req, key, value);
}
- else if (streq(key, "cert_uri_base"))
+ else if (streq(key, "crl_uris") ||
+ streq(key, "ocsp_uris"))
{
- vici_add_key_valuef(req, key, "%s", value);
+ add_list_key(req, key, value);
}
else
{
- add_list_key(req, key, value);
+ vici_add_key_valuef(req, key, "%s", value);
}
if (!ret)
{
diff --git a/src/swanctl/commands/load_conns.c b/src/swanctl/commands/load_conns.c
index 2e443a94a..0518ef54f 100644
--- a/src/swanctl/commands/load_conns.c
+++ b/src/swanctl/commands/load_conns.c
@@ -38,6 +38,7 @@ static bool is_list_key(char *key)
"vips",
"pools",
"groups",
+ "cert_policy",
};
int i;
@@ -97,7 +98,7 @@ static void add_list_key(vici_req_t *req, char *key, char *value)
static bool add_file_list_key(vici_req_t *req, char *key, char *value)
{
enumerator_t *enumerator;
- chunk_t *map;
+ chunk_t *map, blob;
char *token, buf[PATH_MAX];
bool ret = TRUE;
@@ -105,41 +106,51 @@ static bool add_file_list_key(vici_req_t *req, char *key, char *value)
enumerator = enumerator_create_token(value, ",", " ");
while (enumerator->enumerate(enumerator, &token))
{
- if (!path_absolute(token))
+ if (strcasepfx(token, "0x") || strcasepfx(token, "0s"))
{
- if (streq(key, "certs"))
+ blob = chunk_from_str(token + 2);
+ blob = strcasepfx(token, "0x") ? chunk_from_hex(blob, NULL)
+ : chunk_from_base64(blob, NULL);
+ vici_add_list_item(req, blob.ptr, blob.len);
+ chunk_free(&blob);
+ }
+ else
+ {
+ if (!path_absolute(token))
{
- snprintf(buf, sizeof(buf), "%s%s%s",
- SWANCTL_X509DIR, DIRECTORY_SEPARATOR, token);
- token = buf;
+ if (streq(key, "certs"))
+ {
+ snprintf(buf, sizeof(buf), "%s%s%s",
+ SWANCTL_X509DIR, DIRECTORY_SEPARATOR, token);
+ token = buf;
+ }
+ else if (streq(key, "cacerts"))
+ {
+ snprintf(buf, sizeof(buf), "%s%s%s",
+ SWANCTL_X509CADIR, DIRECTORY_SEPARATOR, token);
+ token = buf;
+ }
+ else if (streq(key, "pubkeys"))
+ {
+ snprintf(buf, sizeof(buf), "%s%s%s",
+ SWANCTL_PUBKEYDIR, DIRECTORY_SEPARATOR, token);
+ token = buf;
+ }
}
- else if (streq(key, "cacerts"))
+ map = chunk_map(token, FALSE);
+ if (map)
{
- snprintf(buf, sizeof(buf), "%s%s%s",
- SWANCTL_X509CADIR, DIRECTORY_SEPARATOR, token);
- token = buf;
+ vici_add_list_item(req, map->ptr, map->len);
+ chunk_unmap(map);
}
- else if (streq(key, "pubkeys"))
+ else
{
- snprintf(buf, sizeof(buf), "%s%s%s",
- SWANCTL_PUBKEYDIR, DIRECTORY_SEPARATOR, token);
- token = buf;
+ fprintf(stderr, "loading %s certificate '%s' failed: %s\n",
+ key, token, strerror(errno));
+ ret = FALSE;
+ break;
}
}
-
- map = chunk_map(token, FALSE);
- if (map)
- {
- vici_add_list_item(req, map->ptr, map->len);
- chunk_unmap(map);
- }
- else
- {
- fprintf(stderr, "loading %s certificate '%s' failed: %s\n",
- key, token, strerror(errno));
- ret = FALSE;
- break;
- }
}
enumerator->destroy(enumerator);
vici_end_list(req);
diff --git a/src/swanctl/commands/load_creds.c b/src/swanctl/commands/load_creds.c
index 6278f66b4..848d8512c 100644
--- a/src/swanctl/commands/load_creds.c
+++ b/src/swanctl/commands/load_creds.c
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2014 Martin Willi
- * Copyright (C) 2014 revosec AG
- *
* Copyright (C) 2016 Tobias Brunner
* Copyright (C) 2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
@@ -30,15 +30,35 @@
#include <credentials/sets/mem_cred.h>
#include <credentials/sets/callback_cred.h>
#include <credentials/containers/pkcs12.h>
+#include <collections/hashtable.h>
#include <vici_cert_info.h>
+#define HASH_SIZE_SHA1_HEX (2 * HASH_SIZE_SHA1)
+
+/**
+ * Context used to track loaded secrets
+ */
+typedef struct {
+ /** vici connection */
+ vici_conn_t *conn;
+ /** format options */
+ command_format_options_t format;
+ /** read setting */
+ settings_t *cfg;
+ /** don't prompt user for password */
+ bool noprompt;
+ /** list of key ids of loaded private keys */
+ hashtable_t *keys;
+ /** list of unique ids of loaded shared keys */
+ hashtable_t *shared;
+} load_ctx_t;
+
/**
* Load a single certificate over vici
*/
-static bool load_cert(vici_conn_t *conn, command_format_options_t format,
- char *dir, certificate_type_t type, x509_flag_t flag,
- chunk_t data)
+static bool load_cert(load_ctx_t *ctx, char *dir, certificate_type_t type,
+ x509_flag_t flag, chunk_t data)
{
vici_req_t *req;
vici_res_t *res;
@@ -53,15 +73,15 @@ static bool load_cert(vici_conn_t *conn, command_format_options_t format,
}
vici_add_key_value(req, "data", data.ptr, data.len);
- res = vici_submit(req, conn);
+ res = vici_submit(req, ctx->conn);
if (!res)
{
fprintf(stderr, "load-cert request failed: %s\n", strerror(errno));
return FALSE;
}
- if (format & COMMAND_FORMAT_RAW)
+ if (ctx->format & COMMAND_FORMAT_RAW)
{
- vici_dump(res, "load-cert reply", format & COMMAND_FORMAT_PRETTY,
+ vici_dump(res, "load-cert reply", ctx->format & COMMAND_FORMAT_PRETTY,
stdout);
}
else if (!streq(vici_find_str(res, "no", "success"), "yes"))
@@ -81,8 +101,7 @@ static bool load_cert(vici_conn_t *conn, command_format_options_t format,
/**
* Load certficiates from a directory
*/
-static void load_certs(vici_conn_t *conn, command_format_options_t format,
- char *type_str, char *dir)
+static void load_certs(load_ctx_t *ctx, char *type_str, char *dir)
{
enumerator_t *enumerator;
certificate_type_t type;
@@ -103,7 +122,7 @@ static void load_certs(vici_conn_t *conn, command_format_options_t format,
map = chunk_map(path, FALSE);
if (map)
{
- load_cert(conn, format, path, type, flag, *map);
+ load_cert(ctx, path, type, flag, *map);
chunk_unmap(map);
}
else
@@ -120,8 +139,7 @@ static void load_certs(vici_conn_t *conn, command_format_options_t format,
/**
* Load a single private key over vici
*/
-static bool load_key(vici_conn_t *conn, command_format_options_t format,
- char *dir, char *type, chunk_t data)
+static bool load_key(load_ctx_t *ctx, char *dir, char *type, chunk_t data)
{
vici_req_t *req;
vici_res_t *res;
@@ -140,15 +158,15 @@ static bool load_key(vici_conn_t *conn, command_format_options_t format,
}
vici_add_key_value(req, "data", data.ptr, data.len);
- res = vici_submit(req, conn);
+ res = vici_submit(req, ctx->conn);
if (!res)
{
fprintf(stderr, "load-key request failed: %s\n", strerror(errno));
return FALSE;
}
- if (format & COMMAND_FORMAT_RAW)
+ if (ctx->format & COMMAND_FORMAT_RAW)
{
- vici_dump(res, "load-key reply", format & COMMAND_FORMAT_PRETTY,
+ vici_dump(res, "load-key reply", ctx->format & COMMAND_FORMAT_PRETTY,
stdout);
}
else if (!streq(vici_find_str(res, "no", "success"), "yes"))
@@ -168,11 +186,12 @@ static bool load_key(vici_conn_t *conn, command_format_options_t format,
/**
* Load a private key of any type to vici
*/
-static bool load_key_anytype(vici_conn_t *conn, command_format_options_t format,
- char *path, private_key_t *private)
+static bool load_key_anytype(load_ctx_t *ctx, char *path,
+ private_key_t *private)
{
bool loaded = FALSE;
- chunk_t encoding;
+ chunk_t encoding, keyid;
+ char hex[HASH_SIZE_SHA1_HEX + 1];
if (!private->get_encoding(private, PRIVKEY_ASN1_DER, &encoding))
{
@@ -182,18 +201,25 @@ static bool load_key_anytype(vici_conn_t *conn, command_format_options_t format,
switch (private->get_type(private))
{
case KEY_RSA:
- loaded = load_key(conn, format, path, "rsa", encoding);
+ loaded = load_key(ctx, path, "rsa", encoding);
break;
case KEY_ECDSA:
- loaded = load_key(conn, format, path, "ecdsa", encoding);
+ loaded = load_key(ctx, path, "ecdsa", encoding);
break;
case KEY_BLISS:
- loaded = load_key(conn, format, path, "bliss", encoding);
+ loaded = load_key(ctx, path, "bliss", encoding);
break;
default:
fprintf(stderr, "unsupported key type in '%s'\n", path);
break;
}
+
+ if (loaded &&
+ private->get_fingerprint(private, KEYID_PUBKEY_SHA1, &keyid) &&
+ snprintf(hex, sizeof(hex), "%+B", &keyid) == HASH_SIZE_SHA1_HEX)
+ {
+ free(ctx->keys->remove(ctx->keys, hex));
+ }
chunk_clear(&encoding);
return loaded;
}
@@ -312,7 +338,7 @@ static void* decrypt(char *name, char *type, chunk_t encoding)
/**
* Try to parse a potentially encrypted credential using configured secret
*/
-static void* decrypt_with_config(settings_t *cfg, char *name, char *type,
+static void* decrypt_with_config(load_ctx_t *ctx, char *name, char *type,
chunk_t encoding)
{
credential_type_t credtype;
@@ -329,16 +355,16 @@ static void* decrypt_with_config(settings_t *cfg, char *name, char *type,
}
/* load all secrets for this key type */
- enumerator = cfg->create_section_enumerator(cfg, "secrets");
+ enumerator = ctx->cfg->create_section_enumerator(ctx->cfg, "secrets");
while (enumerator->enumerate(enumerator, &section))
{
if (strpfx(section, type))
{
- file = cfg->get_str(cfg, "secrets.%s.file", NULL, section);
+ file = ctx->cfg->get_str(ctx->cfg, "secrets.%s.file", NULL, section);
if (file && strcaseeq(file, name))
{
snprintf(buf, sizeof(buf), "secrets.%s", section);
- secrets = cfg->create_key_value_enumerator(cfg, buf);
+ secrets = ctx->cfg->create_key_value_enumerator(ctx->cfg, buf);
while (secrets->enumerate(secrets, &key, &value))
{
if (strpfx(key, "secret"))
@@ -382,22 +408,20 @@ static void* decrypt_with_config(settings_t *cfg, char *name, char *type,
/**
* Try to decrypt and load a private key
*/
-static bool load_encrypted_key(vici_conn_t *conn,
- command_format_options_t format, settings_t *cfg,
- char *rel, char *path, char *type, bool noprompt,
- chunk_t data)
+static bool load_encrypted_key(load_ctx_t *ctx, char *rel, char *path,
+ char *type, chunk_t data)
{
private_key_t *private;
bool loaded = FALSE;
- private = decrypt_with_config(cfg, rel, type, data);
- if (!private && !noprompt)
+ private = decrypt_with_config(ctx, rel, type, data);
+ if (!private && !ctx->noprompt)
{
private = decrypt(rel, type, data);
}
if (private)
{
- loaded = load_key_anytype(conn, format, path, private);
+ loaded = load_key_anytype(ctx, path, private);
private->destroy(private);
}
return loaded;
@@ -406,8 +430,7 @@ static bool load_encrypted_key(vici_conn_t *conn,
/**
* Load private keys from a directory
*/
-static void load_keys(vici_conn_t *conn, command_format_options_t format,
- bool noprompt, settings_t *cfg, char *type, char *dir)
+static void load_keys(load_ctx_t *ctx, char *type, char *dir)
{
enumerator_t *enumerator;
struct stat st;
@@ -424,10 +447,9 @@ static void load_keys(vici_conn_t *conn, command_format_options_t format,
map = chunk_map(path, FALSE);
if (map)
{
- if (!load_encrypted_key(conn, format, cfg, rel, path, type,
- noprompt, *map))
+ if (!load_encrypted_key(ctx, rel, path, type, *map))
{
- load_key(conn, format, path, type, *map);
+ load_key(ctx, path, type, *map);
}
chunk_unmap(map);
}
@@ -445,8 +467,7 @@ static void load_keys(vici_conn_t *conn, command_format_options_t format,
/**
* Load credentials from a PKCS#12 container over vici
*/
-static bool load_pkcs12(vici_conn_t *conn, command_format_options_t format,
- char *path, pkcs12_t *p12)
+static bool load_pkcs12(load_ctx_t *ctx, char *path, pkcs12_t *p12)
{
enumerator_t *enumerator;
certificate_t *cert;
@@ -460,8 +481,7 @@ static bool load_pkcs12(vici_conn_t *conn, command_format_options_t format,
loaded = FALSE;
if (cert->get_encoding(cert, CERT_ASN1_DER, &encoding))
{
- loaded = load_cert(conn, format, path, CERT_X509, X509_NONE,
- encoding);
+ loaded = load_cert(ctx, path, CERT_X509, X509_NONE, encoding);
if (loaded)
{
fprintf(stderr, " %Y\n", cert->get_subject(cert));
@@ -478,7 +498,7 @@ static bool load_pkcs12(vici_conn_t *conn, command_format_options_t format,
enumerator = p12->create_key_enumerator(p12);
while (loaded && enumerator->enumerate(enumerator, &private))
{
- loaded = load_key_anytype(conn, format, path, private);
+ loaded = load_key_anytype(ctx, path, private);
}
enumerator->destroy(enumerator);
@@ -488,15 +508,14 @@ static bool load_pkcs12(vici_conn_t *conn, command_format_options_t format,
/**
* Try to decrypt and load credentials from a container
*/
-static bool load_encrypted_container(vici_conn_t *conn,
- command_format_options_t format, settings_t *cfg, char *rel,
- char *path, char *type, bool noprompt, chunk_t data)
+static bool load_encrypted_container(load_ctx_t *ctx, char *rel, char *path,
+ char *type, chunk_t data)
{
container_t *container;
bool loaded = FALSE;
- container = decrypt_with_config(cfg, rel, type, data);
- if (!container && !noprompt)
+ container = decrypt_with_config(ctx, rel, type, data);
+ if (!container && !ctx->noprompt)
{
container = decrypt(rel, type, data);
}
@@ -505,7 +524,7 @@ static bool load_encrypted_container(vici_conn_t *conn,
switch (container->get_type(container))
{
case CONTAINER_PKCS12:
- loaded = load_pkcs12(conn, format, path, (pkcs12_t*)container);
+ loaded = load_pkcs12(ctx, path, (pkcs12_t*)container);
break;
default:
break;
@@ -518,8 +537,7 @@ static bool load_encrypted_container(vici_conn_t *conn,
/**
* Load credential containers from a directory
*/
-static void load_containers(vici_conn_t *conn, command_format_options_t format,
- bool noprompt, settings_t *cfg, char *type, char *dir)
+static void load_containers(load_ctx_t *ctx, char *type, char *dir)
{
enumerator_t *enumerator;
struct stat st;
@@ -536,8 +554,7 @@ static void load_containers(vici_conn_t *conn, command_format_options_t format,
map = chunk_map(path, FALSE);
if (map)
{
- load_encrypted_container(conn, format, cfg, rel, path,
- type, noprompt, *map);
+ load_encrypted_container(ctx, rel, path, type, *map);
chunk_unmap(map);
}
else
@@ -552,10 +569,96 @@ static void load_containers(vici_conn_t *conn, command_format_options_t format,
}
/**
+ * Load a single private key on a token over vici
+ */
+static bool load_token(load_ctx_t *ctx, char *name, char *pin)
+{
+ vici_req_t *req;
+ vici_res_t *res;
+ enumerator_t *enumerator;
+ char *key, *value, *id;
+ bool ret = TRUE;
+
+ req = vici_begin("load-token");
+
+ enumerator = ctx->cfg->create_key_value_enumerator(ctx->cfg, "secrets.%s",
+ name);
+ while (enumerator->enumerate(enumerator, &key, &value))
+ {
+ vici_add_key_valuef(req, key, "%s", value);
+ }
+ enumerator->destroy(enumerator);
+
+ if (pin)
+ {
+ vici_add_key_valuef(req, "pin", "%s", pin);
+ }
+ res = vici_submit(req, ctx->conn);
+ if (!res)
+ {
+ fprintf(stderr, "load-token request failed: %s\n", strerror(errno));
+ return FALSE;
+ }
+ if (ctx->format & COMMAND_FORMAT_RAW)
+ {
+ vici_dump(res, "load-token reply", ctx->format & COMMAND_FORMAT_PRETTY,
+ stdout);
+ }
+ else if (!streq(vici_find_str(res, "no", "success"), "yes"))
+ {
+ fprintf(stderr, "loading '%s' failed: %s\n",
+ name, vici_find_str(res, "", "errmsg"));
+ ret = FALSE;
+ }
+ else
+ {
+ id = vici_find_str(res, "", "id");
+ printf("loaded key %s from token [keyid: %s]\n", name, id);
+ free(ctx->keys->remove(ctx->keys, id));
+ }
+ vici_free_res(res);
+ return ret;
+}
+
+/**
+ * Load keys from tokens
+ */
+static void load_tokens(load_ctx_t *ctx)
+{
+ enumerator_t *enumerator;
+ char *section, *pin = NULL, prompt[128];
+
+ enumerator = ctx->cfg->create_section_enumerator(ctx->cfg, "secrets");
+ while (enumerator->enumerate(enumerator, &section))
+ {
+ if (strpfx(section, "token"))
+ {
+ if (!ctx->noprompt &&
+ !ctx->cfg->get_str(ctx->cfg, "secrets.%s.pin", NULL, section))
+ {
+#ifdef HAVE_GETPASS
+ snprintf(prompt, sizeof(prompt), "PIN for %s: ", section);
+ pin = strdupnull(getpass(prompt));
+#endif
+ }
+ load_token(ctx, section, pin);
+ if (pin)
+ {
+ memwipe(pin, strlen(pin));
+ free(pin);
+ pin = NULL;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+
+
+/**
* Load a single secret over VICI
*/
-static bool load_secret(vici_conn_t *conn, settings_t *cfg,
- char *section, command_format_options_t format)
+static bool load_secret(load_ctx_t *ctx, char *section)
{
enumerator_t *enumerator;
vici_req_t *req;
@@ -567,6 +670,7 @@ static bool load_secret(vici_conn_t *conn, settings_t *cfg,
char *types[] = {
"eap",
"xauth",
+ "ntlm",
"ike",
"private",
"rsa",
@@ -574,6 +678,7 @@ static bool load_secret(vici_conn_t *conn, settings_t *cfg,
"bliss",
"pkcs8",
"pkcs12",
+ "token",
};
for (i = 0; i < countof(types); i++)
@@ -589,12 +694,13 @@ static bool load_secret(vici_conn_t *conn, settings_t *cfg,
fprintf(stderr, "ignoring unsupported secret '%s'\n", section);
return FALSE;
}
- if (!streq(type, "eap") && !streq(type, "xauth") && !streq(type, "ike"))
+ if (!streq(type, "eap") && !streq(type, "xauth") && !streq(type, "ntlm") &&
+ !streq(type, "ike"))
{ /* skip non-shared secrets */
return TRUE;
}
- value = cfg->get_str(cfg, "secrets.%s.secret", NULL, section);
+ value = ctx->cfg->get_str(ctx->cfg, "secrets.%s.secret", NULL, section);
if (!value)
{
fprintf(stderr, "missing secret in '%s', ignored\n", section);
@@ -615,13 +721,14 @@ static bool load_secret(vici_conn_t *conn, settings_t *cfg,
req = vici_begin("load-shared");
+ vici_add_key_valuef(req, "id", "%s", section);
vici_add_key_valuef(req, "type", "%s", type);
vici_add_key_value(req, "data", data.ptr, data.len);
chunk_clear(&data);
vici_begin_list(req, "owners");
snprintf(buf, sizeof(buf), "secrets.%s", section);
- enumerator = cfg->create_key_value_enumerator(cfg, buf);
+ enumerator = ctx->cfg->create_key_value_enumerator(ctx->cfg, buf);
while (enumerator->enumerate(enumerator, &key, &value))
{
if (strpfx(key, "id"))
@@ -632,15 +739,15 @@ static bool load_secret(vici_conn_t *conn, settings_t *cfg,
enumerator->destroy(enumerator);
vici_end_list(req);
- res = vici_submit(req, conn);
+ res = vici_submit(req, ctx->conn);
if (!res)
{
fprintf(stderr, "load-shared request failed: %s\n", strerror(errno));
return FALSE;
}
- if (format & COMMAND_FORMAT_RAW)
+ if (ctx->format & COMMAND_FORMAT_RAW)
{
- vici_dump(res, "load-shared reply", format & COMMAND_FORMAT_PRETTY,
+ vici_dump(res, "load-shared reply", ctx->format & COMMAND_FORMAT_PRETTY,
stdout);
}
else if (!streq(vici_find_str(res, "no", "success"), "yes"))
@@ -653,10 +760,111 @@ static bool load_secret(vici_conn_t *conn, settings_t *cfg,
{
printf("loaded %s secret '%s'\n", type, section);
}
+ if (ret)
+ {
+ free(ctx->shared->remove(ctx->shared, section));
+ }
vici_free_res(res);
return ret;
}
+CALLBACK(get_id, int,
+ hashtable_t *ht, vici_res_t *res, char *name, void *value, int len)
+{
+ if (streq(name, "keys"))
+ {
+ char *str;
+
+ if (asprintf(&str, "%.*s", len, value) != -1)
+ {
+ free(ht->put(ht, str, str));
+ }
+ }
+ return 0;
+}
+
+/**
+ * Get a list of currently loaded private and shared keys
+ */
+static void get_creds(load_ctx_t *ctx)
+{
+ vici_res_t *res;
+
+ res = vici_submit(vici_begin("get-keys"), ctx->conn);
+ if (res)
+ {
+ if (ctx->format & COMMAND_FORMAT_RAW)
+ {
+ vici_dump(res, "get-keys reply", ctx->format & COMMAND_FORMAT_PRETTY,
+ stdout);
+ }
+ vici_parse_cb(res, NULL, NULL, get_id, ctx->keys);
+ vici_free_res(res);
+ }
+ res = vici_submit(vici_begin("get-shared"), ctx->conn);
+ if (res)
+ {
+ if (ctx->format & COMMAND_FORMAT_RAW)
+ {
+ vici_dump(res, "get-shared reply", ctx->format & COMMAND_FORMAT_PRETTY,
+ stdout);
+ }
+ vici_parse_cb(res, NULL, NULL, get_id, ctx->shared);
+ vici_free_res(res);
+ }
+}
+
+/**
+ * Remove a given key
+ */
+static bool unload_key(load_ctx_t *ctx, char *command, char *id)
+{
+ vici_req_t *req;
+ vici_res_t *res;
+ char buf[BUF_LEN];
+ bool ret = TRUE;
+
+ req = vici_begin(command);
+
+ vici_add_key_valuef(req, "id", "%s", id);
+
+ res = vici_submit(req, ctx->conn);
+ if (!res)
+ {
+ fprintf(stderr, "%s request failed: %s\n", command, strerror(errno));
+ return FALSE;
+ }
+ if (ctx->format & COMMAND_FORMAT_RAW)
+ {
+ snprintf(buf, sizeof(buf), "%s reply", command);
+ vici_dump(res, buf, ctx->format & COMMAND_FORMAT_PRETTY, stdout);
+ }
+ else if (!streq(vici_find_str(res, "no", "success"), "yes"))
+ {
+ fprintf(stderr, "unloading key '%s' failed: %s\n",
+ id, vici_find_str(res, "", "errmsg"));
+ ret = FALSE;
+ }
+ vici_free_res(res);
+ return ret;
+}
+
+/**
+ * Remove all keys in the given hashtable using the given command
+ */
+static void unload_keys(load_ctx_t *ctx, hashtable_t *ht, char *command)
+{
+ enumerator_t *enumerator;
+ char *id;
+
+ enumerator = ht->create_enumerator(ht);
+ while (enumerator->enumerate(enumerator, &id, NULL))
+ {
+ unload_key(ctx, command, id);
+ }
+ enumerator->destroy(enumerator);
+}
+
/**
* Clear all currently loaded credentials
*/
@@ -687,6 +895,14 @@ int load_creds_cfg(vici_conn_t *conn, command_format_options_t format,
{
enumerator_t *enumerator;
char *section;
+ load_ctx_t ctx = {
+ .conn = conn,
+ .format = format,
+ .noprompt = noprompt,
+ .cfg = cfg,
+ .keys = hashtable_create(hashtable_hash_str, hashtable_equals_str, 8),
+ .shared = hashtable_create(hashtable_hash_str, hashtable_equals_str, 8),
+ };
if (clear)
{
@@ -696,29 +912,38 @@ int load_creds_cfg(vici_conn_t *conn, command_format_options_t format,
}
}
- load_certs(conn, format, "x509", SWANCTL_X509DIR);
- load_certs(conn, format, "x509ca", SWANCTL_X509CADIR);
- load_certs(conn, format, "x509ocsp", SWANCTL_X509OCSPDIR);
- load_certs(conn, format, "x509aa", SWANCTL_X509AADIR);
- load_certs(conn, format, "x509ac", SWANCTL_X509ACDIR);
- load_certs(conn, format, "x509crl", SWANCTL_X509CRLDIR);
- load_certs(conn, format, "pubkey", SWANCTL_PUBKEYDIR);
+ get_creds(&ctx);
+
+ load_certs(&ctx, "x509", SWANCTL_X509DIR);
+ load_certs(&ctx, "x509ca", SWANCTL_X509CADIR);
+ load_certs(&ctx, "x509ocsp", SWANCTL_X509OCSPDIR);
+ load_certs(&ctx, "x509aa", SWANCTL_X509AADIR);
+ load_certs(&ctx, "x509ac", SWANCTL_X509ACDIR);
+ load_certs(&ctx, "x509crl", SWANCTL_X509CRLDIR);
+ load_certs(&ctx, "pubkey", SWANCTL_PUBKEYDIR);
- load_keys(conn, format, noprompt, cfg, "private", SWANCTL_PRIVATEDIR);
- load_keys(conn, format, noprompt, cfg, "rsa", SWANCTL_RSADIR);
- load_keys(conn, format, noprompt, cfg, "ecdsa", SWANCTL_ECDSADIR);
- load_keys(conn, format, noprompt, cfg, "bliss", SWANCTL_BLISSDIR);
- load_keys(conn, format, noprompt, cfg, "pkcs8", SWANCTL_PKCS8DIR);
+ load_keys(&ctx, "private", SWANCTL_PRIVATEDIR);
+ load_keys(&ctx, "rsa", SWANCTL_RSADIR);
+ load_keys(&ctx, "ecdsa", SWANCTL_ECDSADIR);
+ load_keys(&ctx, "bliss", SWANCTL_BLISSDIR);
+ load_keys(&ctx, "pkcs8", SWANCTL_PKCS8DIR);
- load_containers(conn, format, noprompt, cfg, "pkcs12", SWANCTL_PKCS12DIR);
+ load_containers(&ctx, "pkcs12", SWANCTL_PKCS12DIR);
+
+ load_tokens(&ctx);
enumerator = cfg->create_section_enumerator(cfg, "secrets");
while (enumerator->enumerate(enumerator, &section))
{
- load_secret(conn, cfg, section, format);
+ load_secret(&ctx, section);
}
enumerator->destroy(enumerator);
+ unload_keys(&ctx, ctx.keys, "unload-key");
+ unload_keys(&ctx, ctx.shared, "unload-shared");
+
+ ctx.keys->destroy_function(ctx.keys, (void*)free);
+ ctx.shared->destroy_function(ctx.shared, (void*)free);
return 0;
}
diff --git a/src/swanctl/commands/rekey.c b/src/swanctl/commands/rekey.c
new file mode 100644
index 000000000..47a313657
--- /dev/null
+++ b/src/swanctl/commands/rekey.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2017 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "command.h"
+
+#include <errno.h>
+
+static int rekey(vici_conn_t *conn)
+{
+ vici_req_t *req;
+ vici_res_t *res;
+ command_format_options_t format = COMMAND_FORMAT_NONE;
+ char *arg, *child = NULL, *ike = NULL;
+ int ret = 0, child_id = 0, ike_id = 0;
+
+ while (TRUE)
+ {
+ switch (command_getopt(&arg))
+ {
+ case 'h':
+ return command_usage(NULL);
+ case 'P':
+ format |= COMMAND_FORMAT_PRETTY;
+ /* fall through to raw */
+ case 'r':
+ format |= COMMAND_FORMAT_RAW;
+ continue;
+ case 'c':
+ child = arg;
+ continue;
+ case 'i':
+ ike = arg;
+ continue;
+ case 'C':
+ child_id = atoi(arg);
+ continue;
+ case 'I':
+ ike_id = atoi(arg);
+ continue;
+ case EOF:
+ break;
+ default:
+ return command_usage("invalid --rekey option");
+ }
+ break;
+ }
+
+ req = vici_begin("rekey");
+ if (child)
+ {
+ vici_add_key_valuef(req, "child", "%s", child);
+ }
+ if (ike)
+ {
+ vici_add_key_valuef(req, "ike", "%s", ike);
+ }
+ if (child_id)
+ {
+ vici_add_key_valuef(req, "child-id", "%d", child_id);
+ }
+ if (ike_id)
+ {
+ vici_add_key_valuef(req, "ike-id", "%d", ike_id);
+ }
+ res = vici_submit(req, conn);
+ if (!res)
+ {
+ ret = errno;
+ fprintf(stderr, "rekey request failed: %s\n", strerror(errno));
+ return ret;
+ }
+ if (format & COMMAND_FORMAT_RAW)
+ {
+ vici_dump(res, "rekey reply", format & COMMAND_FORMAT_PRETTY,
+ stdout);
+ }
+ else
+ {
+ if (streq(vici_find_str(res, "no", "success"), "yes"))
+ {
+ printf("rekey completed successfully\n");
+ }
+ else
+ {
+ fprintf(stderr, "rekey failed: %s\n",
+ vici_find_str(res, "", "errmsg"));
+ ret = 1;
+ }
+ }
+ vici_free_res(res);
+ return ret;
+}
+
+/**
+ * Register the command.
+ */
+static void __attribute__ ((constructor))reg()
+{
+ command_register((command_t) {
+ rekey, 'R', "rekey", "rekey an SA",
+ {"--child <name> | --ike <name | --child-id <id> | --ike-id <id>",
+ "[--raw|--pretty]"},
+ {
+ {"help", 'h', 0, "show usage information"},
+ {"child", 'c', 1, "rekey by CHILD_SA name"},
+ {"ike", 'i', 1, "rekey by IKE_SA name"},
+ {"child-id", 'C', 1, "rekey by CHILD_SA unique identifier"},
+ {"ike-id", 'I', 1, "rekey by IKE_SA unique identifier"},
+ {"raw", 'r', 0, "dump raw response message"},
+ {"pretty", 'P', 0, "dump raw response message in pretty print"},
+ }
+ });
+}
diff --git a/src/swanctl/swanctl.8.in b/src/swanctl/swanctl.8.in
index 9c5a5a03d..391fe486f 100644
--- a/src/swanctl/swanctl.8.in
+++ b/src/swanctl/swanctl.8.in
@@ -40,6 +40,9 @@ initiate a connection
.B "\-t, \-\-terminate"
terminate a connection
.TP
+.B "\-R, \-\-rekey"
+rekey an SA
+.TP
.B "\-d, \-\-redirect"
redirect an IKE_SA
.TP
diff --git a/src/swanctl/swanctl.conf b/src/swanctl/swanctl.conf
index eb46005e1..789b128fd 100644
--- a/src/swanctl/swanctl.conf
+++ b/src/swanctl/swanctl.conf
@@ -31,6 +31,10 @@
# Set the Mode Config mode to use.
# pull = yes
+ # Differentiated Services Field Codepoint to set on outgoing IKE packets
+ # (six binary digits).
+ # dscp = 000000
+
# Enforce UDP encapsulation by faking NAT-D payloads.
# encap = no
@@ -73,6 +77,15 @@
# Comma separated list of named IP pools.
# pools =
+ # Whether this connection is a mediation connection.
+ # mediation = no
+
+ # The name of the connection to mediate this connection through.
+ # mediated_by =
+
+ # Identity under which the peer is registered at the mediation server.
+ # mediation_peer =
+
# Section for a local authentication round.
# local<suffix> {
@@ -85,6 +98,9 @@
# authentication.
# certs =
+ # Section for a certificate candidate to use for authentication.
+ # cert<suffix> =
+
# Comma separated list of raw public key candidates to use for
# authentication.
# pubkeys =
@@ -106,6 +122,22 @@
# Client XAuth username used in the XAuth exchange.
# xauth_id = id
+ # cert<suffix> {
+
+ # Absolute path to the certificate to load.
+ # file =
+
+ # Hex-encoded CKA_ID of the certificate on a token.
+ # handle =
+
+ # Optional slot number of the token that stores the certificate.
+ # slot =
+
+ # Optional PKCS#11 module name.
+ # module =
+
+ # }
+
# }
# Section for a remote authentication round.
@@ -122,13 +154,22 @@
# Authorization group memberships to require.
# groups =
+ # Certificate policy OIDs the peer's certificate must have.
+ # cert_policy =
+
# Comma separated list of certificate to accept for authentication.
# certs =
+ # Section for a certificate to accept for authentication.
+ # cert<suffix> =
+
# Comma separated list of CA certificates to accept for
# authentication.
# cacerts =
+ # Section for a CA certificate to accept for authentication.
+ # cacert<suffix> =
+
# Comma separated list of raw public keys to accept for
# authentication.
# pubkeys =
@@ -140,6 +181,39 @@
# or eap[-method]).
# auth = pubkey
+ # cert<suffix> {
+
+ # Absolute path to the certificate to load.
+ # file =
+
+ # Hex-encoded CKA_ID of the certificate on a token.
+ # handle =
+
+ # Optional slot number of the token that stores the certificate.
+ # slot =
+
+ # Optional PKCS#11 module name.
+ # module =
+
+ # }
+
+ # cacert<suffix> {
+
+ # Absolute path to the certificate to load.
+ # file =
+
+ # Hex-encoded CKA_ID of the CA certificate on a token.
+ # handle =
+
+ # Optional slot number of the token that stores the CA
+ # certificate.
+ # slot =
+
+ # Optional PKCS#11 module name.
+ # module =
+
+ # }
+
# }
# children {
@@ -194,8 +268,8 @@
# Hostaccess variable to pass to updown script.
# hostaccess = yes
- # IPsec Mode to establish (tunnel, transport, beet, pass or
- # drop).
+ # IPsec Mode to establish (tunnel, transport, transport_proxy,
+ # beet, pass or drop).
# mode = tunnel
# Whether to install IPsec policies or not.
@@ -270,6 +344,17 @@
# }
+ # NTLM secret section for a specific secret.
+ # ntlm<suffix> {
+
+ # Value of the NTLM secret.
+ # secret =
+
+ # Identity the NTLM secret belongs to.
+ # id<suffix> =
+
+ # }
+
# IKE preshared secret section for a specific secret.
# ike<suffix> {
@@ -340,6 +425,24 @@
# }
+ # Definition for a private key that's stored on a token/smartcard.
+ # token<suffix> {
+
+ # Hex-encoded CKA_ID of the private key on the token.
+ # handle =
+
+ # Optional slot number to access the token.
+ # slot =
+
+ # Optional PKCS#11 module name to access the token.
+ # module =
+
+ # Optional PIN required to access the key on the token. If none is
+ # provided the user is prompted during an interactive --load-creds call.
+ # pin =
+
+ # }
+
# }
# Section defining named pools.
@@ -367,10 +470,22 @@
# CA certificate belonging to the certification authority.
# cacert =
- # Comma-separated list of CRL distribution points
+ # Absolute path to the certificate to load.
+ # file =
+
+ # Hex-encoded CKA_ID of the CA certificate on a token.
+ # handle =
+
+ # Optional slot number of the token that stores the CA certificate.
+ # slot =
+
+ # Optional PKCS#11 module name.
+ # module =
+
+ # Comma-separated list of CRL distribution points.
# crl_uris =
- # Comma-separated list of OCSP URIs
+ # Comma-separated list of OCSP URIs.
# ocsp_uris =
# Defines the base URI for the Hash and URL feature supported by IKEv2.
diff --git a/src/swanctl/swanctl.conf.5.head.in b/src/swanctl/swanctl.conf.5.head.in
index 84f734eb9..5742d2593 100644
--- a/src/swanctl/swanctl.conf.5.head.in
+++ b/src/swanctl/swanctl.conf.5.head.in
@@ -6,7 +6,8 @@ swanctl.conf is the configuration file used by the
.BR swanctl (8)
tool to load configurations and credentials into the strongSwan IKE daemon.
-For a description of the basic file syntax refer to
+For a description of the basic file syntax, including how to split the
+configuration in multiple files by including other files, refer to
.BR strongswan.conf (5).
.SH TIME FORMATS
diff --git a/src/swanctl/swanctl.conf.5.main b/src/swanctl/swanctl.conf.5.main
index 697bd406a..6e1e9adfb 100644
--- a/src/swanctl/swanctl.conf.5.main
+++ b/src/swanctl/swanctl.conf.5.main
@@ -35,6 +35,9 @@ As initiator, the first non\-range/non\-subnet is used to initiate the connectio
from. As responder, the local destination address must match at least to one of
the specified addresses, subnets or ranges.
+If FQDNs are assigned they are resolved every time a configuration lookup is
+done. If DNS resolution times out, the lookup is delayed for that time.
+
.TP
.BR connections.<conn>.remote_addrs " [%any]"
Remote address(es) to use for IKE communication, comma separated. Takes single
@@ -44,6 +47,9 @@ As initiator, the first non\-range/non\-subnet is used to initiate the connectio
to. As responder, the initiator source address must match at least to one of the
specified addresses, subnets or ranges.
+If FQDNs are assigned they are resolved every time a configuration lookup is
+done. If DNS resolution times out, the lookup is delayed for that time.
+
To initiate a connection, at least one specific address or DNS name must be
specified.
@@ -118,6 +124,12 @@ Push mode is currently supported for IKEv1, but not in IKEv2. It is used by a
few implementations only, pull mode is recommended.
.TP
+.BR connections.<conn>.dscp " [000000]"
+Differentiated Services Field Codepoint to set on outgoing IKE packets for this
+connection. The value is a six digit binary encoded string specifying the
+Codepoint to set, as defined in RFC 2474.
+
+.TP
.BR connections.<conn>.encap " [no]"
To enforce UDP encapsulation of ESP packets, the IKE daemon can fake the NAT
detection payloads. This makes the peer believe that NAT takes place on the
@@ -303,6 +315,30 @@ either the
section or an external pool.
.TP
+.BR connections.<conn>.mediation " [no]"
+Whether this connection is a mediation connection, that is, whether this
+connection is used to mediate other connections using the IKEv2 Mediation
+Extension. Mediation connections create no CHILD_SA.
+
+.TP
+.BR connections.<conn>.mediated_by " []"
+The name of the connection to mediate this connection through. If given, the
+connection will be mediated through the named mediation connection. The
+mediation connection must have
+.RB "" "mediation" ""
+enabled.
+
+.TP
+.BR connections.<conn>.mediation_peer " []"
+Identity under which the peer is registered at the mediation server, that is,
+the IKE identity the other end of this connection uses as its local identity on
+its connection to the mediation server. This is the identity we request the
+mediation server to mediate us with. Only relevant on connections that set
+.RB "" "mediated_by" "."
+If it is not given, the remote IKE identity of the first
+authentication round of this connection will be used.
+
+.TP
.B connections.<conn>.local<suffix>
.br
Section for a local authentication round. A local authentication round defines
@@ -334,6 +370,37 @@ certificate request payloads. If no appropriate CA can be located, the first
certificate is used.
.TP
+.BR connections.<conn>.local<suffix>.cert<suffix> " []"
+Section for a certificate candidate to use for authentication. Certificates in
+.RI "" "certs" ""
+are transmitted as binary blobs, these sections offer more flexibility.
+
+.TP
+.BR connections.<conn>.local<suffix>.cert<suffix>.file " []"
+Absolute path to the certificate to load. Passed as\-is to the daemon, so it must
+be readable by it.
+
+Configure either this or
+.RI "" "handle" ","
+but not both, in one section.
+
+.TP
+.BR connections.<conn>.local<suffix>.cert<suffix>.handle " []"
+Hex\-encoded CKA_ID of the certificate on a token.
+
+Configure either this or
+.RI "" "file" ","
+but not both, in one section.
+
+.TP
+.BR connections.<conn>.local<suffix>.cert<suffix>.slot " []"
+Optional slot number of the token that stores the certificate.
+
+.TP
+.BR connections.<conn>.local<suffix>.cert<suffix>.module " []"
+Optional PKCS#11 module name.
+
+.TP
.BR connections.<conn>.local<suffix>.pubkeys " []"
Comma separated list of raw public key candidates to use for authentication. The
public keys may use a relative path from the
@@ -498,6 +565,11 @@ certified by different means, for example by appropriate Attribute Certificates
or by an AAA backend involved in the authentication.
.TP
+.BR connections.<conn>.remote<suffix>.cert_policy " []"
+Comma separated list of certificate policy OIDs the peer's certificate must
+have. OIDs are specified using the numerical dotted representation.
+
+.TP
.BR connections.<conn>.remote<suffix>.certs " []"
Comma separated list of certificates to accept for authentication. The
certificates may use a relative path from the
@@ -507,6 +579,37 @@ directory or an
absolute path.
.TP
+.BR connections.<conn>.remote<suffix>.cert<suffix> " []"
+Section for a certificate to accept for authentication. Certificates in
+.RI "" "certs" ""
+are transmitted as binary blobs, these sections offer more flexibility.
+
+.TP
+.BR connections.<conn>.remote<suffix>.cert<suffix>.file " []"
+Absolute path to the certificate to load. Passed as\-is to the daemon, so it must
+be readable by it.
+
+Configure either this or
+.RI "" "handle" ","
+but not both, in one section.
+
+.TP
+.BR connections.<conn>.remote<suffix>.cert<suffix>.handle " []"
+Hex\-encoded CKA_ID of the certificate on a token.
+
+Configure either this or
+.RI "" "file" ","
+but not both, in one section.
+
+.TP
+.BR connections.<conn>.remote<suffix>.cert<suffix>.slot " []"
+Optional slot number of the token that stores the certificate.
+
+.TP
+.BR connections.<conn>.remote<suffix>.cert<suffix>.module " []"
+Optional PKCS#11 module name.
+
+.TP
.BR connections.<conn>.remote<suffix>.cacerts " []"
Comma separated list of CA certificates to accept for authentication. The
certificates may use a relative path from the
@@ -516,6 +619,38 @@ directory or
an absolute path.
.TP
+.BR connections.<conn>.remote<suffix>.cacert<suffix> " []"
+Section for a CA certificate to accept for authentication. Certificates in
+.RI "" "cacerts" ""
+are transmitted as binary blobs, these sections offer more
+flexibility.
+
+.TP
+.BR connections.<conn>.remote<suffix>.cacert<suffix>.file " []"
+Absolute path to the certificate to load. Passed as\-is to the daemon, so it must
+be readable by it.
+
+Configure either this or
+.RI "" "handle" ","
+but not both, in one section.
+
+.TP
+.BR connections.<conn>.remote<suffix>.cacert<suffix>.handle " []"
+Hex\-encoded CKA_ID of the CA certificate on a token.
+
+Configure either this or
+.RI "" "file" ","
+but not both, in one section.
+
+.TP
+.BR connections.<conn>.remote<suffix>.cacert<suffix>.slot " []"
+Optional slot number of the token that stores the CA certificate.
+
+.TP
+.BR connections.<conn>.remote<suffix>.cacert<suffix>.module " []"
+Optional PKCS#11 module name.
+
+.TP
.BR connections.<conn>.remote<suffix>.pubkeys " []"
Comma separated list of raw public keys to accept for authentication. The public
keys may use a relative path from the
@@ -673,9 +808,16 @@ for RFC 4301
OPAQUE selectors. Port ranges may be specified as well, none of the kernel
backends currently support port ranges, though.
-Unless the Unity extension is used, IKEv1 supports the first specified selector
-only. IKEv1 uses very similar traffic selector narrowing as it is supported in
-the IKEv2 protocol.
+When IKEv1 is used only the first selector is interpreted, except if the Cisco
+Unity extension plugin is used. This is due to a limitation of the IKEv1
+protocol, which only allows a single pair of selectors per CHILD_SA. So to
+tunnel traffic matched by several pairs of selectors when using IKEv1 several
+children (CHILD_SAs) have to be defined that cover the selectors.
+
+The IKE daemon uses traffic selector narrowing for IKEv1, the same way it is
+standardized and implemented for IKEv2. However, this may lead to problems with
+other implementations. To avoid that, configure identical selectors in such
+scenarios.
.TP
.BR connections.<conn>.children.<child>.remote_ts " [dynamic]"
@@ -803,10 +945,12 @@ negotiates the CHILD_SA in IPsec
Tunnel Mode, whereas
.RI "" "transport" ""
uses IPsec Transport Mode.
+.RI "" "transport_proxy" ""
+signifying the special Mobile IPv6 Transport Proxy Mode.
.RI "" "beet" ""
-is the Bound
-End to End Tunnel mixture mode, working with fixed inner addresses without the
-need to include them in each packet.
+is the Bound End
+to End Tunnel mixture mode, working with fixed inner addresses without the need
+to include them in each packet.
Both
.RI "" "transport" ""
@@ -1011,6 +1155,33 @@ secrets under both section prefixes are used for both EAP and XAuth
authentication.
.TP
+.B secrets.ntlm<suffix>
+.br
+NTLM secret section for a specific secret. Each NTLM secret is defined in a
+unique section having the
+.RI "" "ntlm" ""
+prefix. NTLM secrets may only be used for
+EAP\-MSCHAPv2 authentication.
+
+.TP
+.BR secrets.ntlm<suffix>.secret " []"
+Value of the NTLM secret, which is the NT Hash of the actual secret, that is,
+MD4(UTF\-16LE(secret)). The resulting 16\-byte value may either be given as a hex
+encoded string with a
+.RI "" "0x" ""
+prefix or as a Base64 encoded string with a
+.RI "" "0s" ""
+prefix.
+
+.TP
+.BR secrets.ntlm<suffix>.id<suffix> " []"
+Identity the NTLM secret belongs to. Multiple unique identities may be
+specified, each having an
+.RI "" "id" ""
+prefix, if a secret is shared between multiple
+users.
+
+.TP
.B secrets.ike<suffix>
.br
IKE preshared secret section for a specific secret. Each IKE PSK is defined in a
@@ -1121,6 +1292,28 @@ folder for which this passphrase should be used.
Value of decryption passphrase for PKCS#12 container.
.TP
+.B secrets.token<suffix>
+.br
+Definition for a private key that's stored on a token/smartcard.
+
+.TP
+.BR secrets.token<suffix>.handle " []"
+Hex\-encoded CKA_ID of the private key on the token.
+
+.TP
+.BR secrets.token<suffix>.slot " []"
+Optional slot number to access the token.
+
+.TP
+.BR secrets.token<suffix>.module " []"
+Optional PKCS#11 module name to access the token.
+
+.TP
+.BR secrets.token<suffix>.pin " []"
+Optional PIN required to access the key on the token. If none is provided the
+user is prompted during an interactive \-\-load\-creds call.
+
+.TP
.B pools
.br
Section defining named pools. Named pools may be referenced by connections with
@@ -1172,19 +1365,57 @@ Section defining a certification authority with a unique name.
.TP
.BR authorities.<name>.cacert " []"
-The certificates may use a relative path from the
+CA certificate belonging to the certification authority. The certificates may
+use a relative path from the
.RB "" "swanctl" ""
.RI "" "x509ca" ""
-directory
-or an absolute path.
+directory or an absolute path.
+
+Configure one of
+.RI "" "cacert" ","
+.RI "" "file" ","
+or
+.RI "" "handle" ""
+per section.
+
+.TP
+.BR authorities.<name>.file " []"
+Absolute path to the certificate to load. Passed as\-is to the daemon, so it must
+be readable by it.
+
+Configure one of
+.RI "" "cacert" ","
+.RI "" "file" ","
+or
+.RI "" "handle" ""
+per section.
+
+.TP
+.BR authorities.<name>.handle " []"
+Hex\-encoded CKA_ID of the CA certificate on a token.
+
+Configure one of
+.RI "" "cacert" ","
+.RI "" "file" ","
+or
+.RI "" "handle" ""
+per section.
+
+.TP
+.BR authorities.<name>.slot " []"
+Optional slot number of the token that stores the CA certificate.
+
+.TP
+.BR authorities.<name>.module " []"
+Optional PKCS#11 module name.
.TP
.BR authorities.<name>.crl_uris " []"
-Comma\-separated list of CRL distribution points (ldap, http, or file URI)
+Comma\-separated list of CRL distribution points (ldap, http, or file URI).
.TP
.BR authorities.<name>.ocsp_uris " []"
-Comma\-separated list of OCSP URIs
+Comma\-separated list of OCSP URIs.
.TP
.BR authorities.<name>.cert_uri_base " []"
diff --git a/src/swanctl/swanctl.opt b/src/swanctl/swanctl.opt
index a7d6d9fc3..bdd92177f 100644
--- a/src/swanctl/swanctl.opt
+++ b/src/swanctl/swanctl.opt
@@ -28,6 +28,9 @@ connections.<conn>.local_addrs = %any
connection from. As responder, the local destination address must match at
least to one of the specified addresses, subnets or ranges.
+ If FQDNs are assigned they are resolved every time a configuration lookup
+ is done. If DNS resolution times out, the lookup is delayed for that time.
+
connections.<conn>.remote_addrs = %any
Remote address(es) to use for IKE communication, comma separated.
@@ -38,6 +41,9 @@ connections.<conn>.remote_addrs = %any
connection to. As responder, the initiator source address must match at
least to one of the specified addresses, subnets or ranges.
+ If FQDNs are assigned they are resolved every time a configuration lookup
+ is done. If DNS resolution times out, the lookup is delayed for that time.
+
To initiate a connection, at least one specific address or DNS name must
be specified.
@@ -102,6 +108,14 @@ connections.<conn>.pull = yes
Push mode is currently supported for IKEv1, but not in IKEv2. It is used
by a few implementations only, pull mode is recommended.
+connections.<conn>.dscp = 000000
+ Differentiated Services Field Codepoint to set on outgoing IKE packets (six
+ binary digits).
+
+ Differentiated Services Field Codepoint to set on outgoing IKE packets for
+ this connection. The value is a six digit binary encoded string specifying
+ the Codepoint to set, as defined in RFC 2474.
+
connections.<conn>.encap = no
Enforce UDP encapsulation by faking NAT-D payloads.
@@ -256,6 +270,30 @@ connections.<conn>.pools =
other configuration attributes from. Each name references a pool by name
from either the **pools** section or an external pool.
+connections.<conn>.mediation = no
+ Whether this connection is a mediation connection.
+
+ Whether this connection is a mediation connection, that is, whether this
+ connection is used to mediate other connections using the IKEv2 Mediation
+ Extension. Mediation connections create no CHILD_SA.
+
+connections.<conn>.mediated_by =
+ The name of the connection to mediate this connection through.
+
+ The name of the connection to mediate this connection through. If given, the
+ connection will be mediated through the named mediation connection.
+ The mediation connection must have **mediation** enabled.
+
+connections.<conn>.mediation_peer =
+ Identity under which the peer is registered at the mediation server.
+
+ Identity under which the peer is registered at the mediation server, that
+ is, the IKE identity the other end of this connection uses as its local
+ identity on its connection to the mediation server. This is the identity we
+ request the mediation server to mediate us with. Only relevant on
+ connections that set **mediated_by**. If it is not given, the remote IKE
+ identity of the first authentication round of this connection will be used.
+
connections.<conn>.local<suffix> {}
Section for a local authentication round.
@@ -284,6 +322,34 @@ connections.<conn>.local<suffix>.certs =
certificate request payloads. If no appropriate CA can be located, the
first certificate is used.
+connections.<conn>.local<suffix>.cert<suffix> =
+ Section for a certificate candidate to use for authentication.
+
+ Section for a certificate candidate to use for authentication. Certificates
+ in _certs_ are transmitted as binary blobs, these sections offer more
+ flexibility.
+
+connections.<conn>.local<suffix>.cert<suffix>.file =
+ Absolute path to the certificate to load.
+
+ Absolute path to the certificate to load. Passed as-is to the daemon, so it
+ must be readable by it.
+
+ Configure either this or _handle_, but not both, in one section.
+
+connections.<conn>.local<suffix>.cert<suffix>.handle =
+ Hex-encoded CKA_ID of the certificate on a token.
+
+ Hex-encoded CKA_ID of the certificate on a token.
+
+ Configure either this or _file_, but not both, in one section.
+
+connections.<conn>.local<suffix>.cert<suffix>.slot =
+ Optional slot number of the token that stores the certificate.
+
+connections.<conn>.local<suffix>.cert<suffix>.module =
+ Optional PKCS#11 module name.
+
connections.<conn>.local<suffix>.pubkeys =
Comma separated list of raw public key candidates to use for authentication.
@@ -398,6 +464,12 @@ connections.<conn>.remote<suffix>.groups =
can be certified by different means, for example by appropriate Attribute
Certificates or by an AAA backend involved in the authentication.
+connections.<conn>.remote<suffix>.cert_policy =
+ Certificate policy OIDs the peer's certificate must have.
+
+ Comma separated list of certificate policy OIDs the peer's certificate must
+ have. OIDs are specified using the numerical dotted representation.
+
connections.<conn>.remote<suffix>.certs =
Comma separated list of certificate to accept for authentication.
@@ -405,6 +477,34 @@ connections.<conn>.remote<suffix>.certs =
The certificates may use a relative path from the **swanctl** _x509_
directory or an absolute path.
+connections.<conn>.remote<suffix>.cert<suffix> =
+ Section for a certificate to accept for authentication.
+
+ Section for a certificate to accept for authentication. Certificates
+ in _certs_ are transmitted as binary blobs, these sections offer more
+ flexibility.
+
+connections.<conn>.remote<suffix>.cert<suffix>.file =
+ Absolute path to the certificate to load.
+
+ Absolute path to the certificate to load. Passed as-is to the daemon, so it
+ must be readable by it.
+
+ Configure either this or _handle_, but not both, in one section.
+
+connections.<conn>.remote<suffix>.cert<suffix>.handle =
+ Hex-encoded CKA_ID of the certificate on a token.
+
+ Hex-encoded CKA_ID of the certificate on a token.
+
+ Configure either this or _file_, but not both, in one section.
+
+connections.<conn>.remote<suffix>.cert<suffix>.slot =
+ Optional slot number of the token that stores the certificate.
+
+connections.<conn>.remote<suffix>.cert<suffix>.module =
+ Optional PKCS#11 module name.
+
connections.<conn>.remote<suffix>.cacerts =
Comma separated list of CA certificates to accept for authentication.
@@ -412,6 +512,34 @@ connections.<conn>.remote<suffix>.cacerts =
The certificates may use a relative path from the **swanctl** _x509ca_
directory or an absolute path.
+connections.<conn>.remote<suffix>.cacert<suffix> =
+ Section for a CA certificate to accept for authentication.
+
+ Section for a CA certificate to accept for authentication. Certificates
+ in _cacerts_ are transmitted as binary blobs, these sections offer more
+ flexibility.
+
+connections.<conn>.remote<suffix>.cacert<suffix>.file =
+ Absolute path to the certificate to load.
+
+ Absolute path to the certificate to load. Passed as-is to the daemon, so it
+ must be readable by it.
+
+ Configure either this or _handle_, but not both, in one section.
+
+connections.<conn>.remote<suffix>.cacert<suffix>.handle =
+ Hex-encoded CKA_ID of the CA certificate on a token.
+
+ Hex-encoded CKA_ID of the CA certificate on a token.
+
+ Configure either this or _file_, but not both, in one section.
+
+connections.<conn>.remote<suffix>.cacert<suffix>.slot =
+ Optional slot number of the token that stores the CA certificate.
+
+connections.<conn>.remote<suffix>.cacert<suffix>.module =
+ Optional PKCS#11 module name.
+
connections.<conn>.remote<suffix>.pubkeys =
Comma separated list of raw public keys to accept for authentication.
@@ -536,9 +664,16 @@ connections.<conn>.children.<child>.local_ts = dynamic
value _opaque_ for RFC 4301 OPAQUE selectors. Port ranges may be specified
as well, none of the kernel backends currently support port ranges, though.
- Unless the Unity extension is used, IKEv1 supports the first specified
- selector only. IKEv1 uses very similar traffic selector narrowing as it is
- supported in the IKEv2 protocol.
+ When IKEv1 is used only the first selector is interpreted, except if
+ the Cisco Unity extension plugin is used. This is due to a limitation of the
+ IKEv1 protocol, which only allows a single pair of selectors per CHILD_SA.
+ So to tunnel traffic matched by several pairs of selectors when using IKEv1
+ several children (CHILD_SAs) have to be defined that cover the selectors.
+
+ The IKE daemon uses traffic selector narrowing for IKEv1, the same way it is
+ standardized and implemented for IKEv2. However, this may lead to problems
+ with other implementations. To avoid that, configure identical selectors in
+ such scenarios.
connections.<conn>.children.<child>.remote_ts = dynamic
Remote selectors to include in CHILD_SA.
@@ -640,11 +775,13 @@ connections.<conn>.children.<child>.hostaccess = yes
Hostaccess variable to pass to **updown** script.
connections.<conn>.children.<child>.mode = tunnel
- IPsec Mode to establish (_tunnel_, _transport_, _beet_, _pass_ or _drop_).
+ IPsec Mode to establish (_tunnel_, _transport_, _transport_proxy_, _beet_,
+ _pass_ or _drop_).
IPsec Mode to establish CHILD_SA with. _tunnel_ negotiates the CHILD_SA
- in IPsec Tunnel Mode, whereas _transport_ uses IPsec Transport Mode. _beet_
- is the Bound End to End Tunnel mixture mode, working with fixed inner
+ in IPsec Tunnel Mode, whereas _transport_ uses IPsec Transport Mode.
+ _transport_proxy_ signifying the special Mobile IPv6 Transport Proxy Mode.
+ _beet_ is the Bound End to End Tunnel mixture mode, working with fixed inner
addresses without the need to include them in each packet.
Both _transport_ and _beet_ modes are subject to mode negotiation; _tunnel_
@@ -815,6 +952,28 @@ secrets.eap<suffix>.id<suffix> =
be specified, each having an _id_ prefix, if a secret is shared between
multiple users.
+secrets.ntlm<suffix> { # }
+ NTLM secret section for a specific secret.
+
+ NTLM secret section for a specific secret. Each NTLM secret is defined in
+ a unique section having the _ntlm_ prefix. NTLM secrets may only be used for
+ EAP-MSCHAPv2 authentication.
+
+secrets.ntlm<suffix>.secret =
+ Value of the NTLM secret.
+
+ Value of the NTLM secret, which is the NT Hash of the actual secret, that
+ is, MD4(UTF-16LE(secret)). The resulting 16-byte value may either be given
+ as a hex encoded string with a _0x_ prefix or as a Base64 encoded string
+ with a _0s_ prefix.
+
+secrets.ntlm<suffix>.id<suffix> =
+ Identity the NTLM secret belongs to.
+
+ Identity the NTLM secret belongs to. Multiple unique identities may
+ be specified, each having an _id_ prefix, if a secret is shared between
+ multiple users.
+
secrets.ike<suffix> { # }
IKE preshared secret section for a specific secret.
@@ -880,6 +1039,22 @@ secrets.pkcs12<suffix>.file =
secrets.pkcs12<suffix>.secret
Value of decryption passphrase for PKCS#12 container.
+secrets.token<suffix> { # }
+ Definition for a private key that's stored on a token/smartcard.
+
+secrets.token<suffix>.handle =
+ Hex-encoded CKA_ID of the private key on the token.
+
+secrets.token<suffix>.slot =
+ Optional slot number to access the token.
+
+secrets.token<suffix>.module =
+ Optional PKCS#11 module name to access the token.
+
+secrets.token<suffix>.pin =
+ Optional PIN required to access the key on the token. If none is provided
+ the user is prompted during an interactive --load-creds call.
+
pools { # }
Section defining named pools.
@@ -916,18 +1091,40 @@ authorities.<name> { # }
authorities.<name>.cacert =
CA certificate belonging to the certification authority.
- The certificates may use a relative path from the **swanctl** _x509ca_
- directory or an absolute path.
+ CA certificate belonging to the certification authority. The certificates
+ may use a relative path from the **swanctl** _x509ca_ directory or an
+ absolute path.
+
+ Configure one of _cacert_, _file_, or _handle_ per section.
+
+authorities.<name>.file =
+ Absolute path to the certificate to load.
+
+ Absolute path to the certificate to load. Passed as-is to the daemon, so it
+ must be readable by it.
+
+ Configure one of _cacert_, _file_, or _handle_ per section.
+
+authorities.<name>.handle =
+ Hex-encoded CKA_ID of the CA certificate on a token.
+
+ Hex-encoded CKA_ID of the CA certificate on a token.
+
+ Configure one of _cacert_, _file_, or _handle_ per section.
+
+authorities.<name>.slot =
+ Optional slot number of the token that stores the CA certificate.
+
+authorities.<name>.module =
+ Optional PKCS#11 module name.
authorities.<name>.crl_uris =
- Comma-separated list of CRL distribution points
+ Comma-separated list of CRL distribution points.
- Comma-separated list of CRL distribution points (ldap, http, or file URI)
+ Comma-separated list of CRL distribution points (ldap, http, or file URI).
authorities.<name>.ocsp_uris =
- Comma-separated list of OCSP URIs
-
- Comma-separated list of OCSP URIs
+ Comma-separated list of OCSP URIs.
authorities.<name>.cert_uri_base =
Defines the base URI for the Hash and URL feature supported by IKEv2.