diff options
Diffstat (limited to 'src/swanctl')
27 files changed, 525 insertions, 143 deletions
diff --git a/src/swanctl/Makefile.am b/src/swanctl/Makefile.am index 385737ad4..b84d70587 100644 --- a/src/swanctl/Makefile.am +++ b/src/swanctl/Makefile.am @@ -10,12 +10,14 @@ swanctl_SOURCES = \ commands/list_conns.c \ commands/list_certs.c \ commands/list_pools.c \ - commands/load_conns.c \ - commands/load_creds.c \ - commands/load_pools.c \ + commands/load_all.c \ + commands/load_conns.c commands/load_conns.h \ + commands/load_creds.c commands/load_creds.h \ + commands/load_pools.c commands/load_pools.h \ commands/log.c \ commands/version.c \ commands/stats.c \ + commands/reload_settings.c \ swanctl.c swanctl.h swanctl_LDADD = \ @@ -44,7 +46,7 @@ CLEANFILES = $(man_MANS) swanctl.conf.5.main: swanctl.opt $(AM_V_GEN) \ - $(PYTHON) $(top_srcdir)/conf/format-options.py -n -f man $< > $(srcdir)/$@ + $(PYTHON) $(top_srcdir)/conf/format-options.py -n -f man swanctl.opt > $(srcdir)/$@ swanctl.conf.5: swanctl.conf.5.head swanctl.conf.5.main swanctl.conf.5.tail $(AM_V_GEN) \ @@ -54,7 +56,7 @@ maintainer-clean-local: cd $(srcdir) && rm -f swanctl.conf swanctl.conf.5.main install-data-local: swanctl.conf - test -e "$(DESTDIR)$(swanctldir)" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)" + test -e "$(DESTDIR)$(swanctldir)" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)" || true test -e "$(DESTDIR)$(swanctldir)/x509" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)/x509" || true test -e "$(DESTDIR)$(swanctldir)/x509ca" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)/x509ca" || true test -e "$(DESTDIR)$(swanctldir)/x509aa" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)/x509aa" || true diff --git a/src/swanctl/Makefile.in b/src/swanctl/Makefile.in index 149159770..649e6d8ae 100644 --- a/src/swanctl/Makefile.in +++ b/src/swanctl/Makefile.in @@ -108,10 +108,11 @@ am_swanctl_OBJECTS = command.$(OBJEXT) commands/initiate.$(OBJEXT) \ commands/terminate.$(OBJEXT) commands/install.$(OBJEXT) \ commands/list_sas.$(OBJEXT) commands/list_pols.$(OBJEXT) \ commands/list_conns.$(OBJEXT) commands/list_certs.$(OBJEXT) \ - commands/list_pools.$(OBJEXT) commands/load_conns.$(OBJEXT) \ - commands/load_creds.$(OBJEXT) commands/load_pools.$(OBJEXT) \ - commands/log.$(OBJEXT) commands/version.$(OBJEXT) \ - commands/stats.$(OBJEXT) swanctl.$(OBJEXT) + commands/list_pools.$(OBJEXT) commands/load_all.$(OBJEXT) \ + commands/load_conns.$(OBJEXT) commands/load_creds.$(OBJEXT) \ + commands/load_pools.$(OBJEXT) commands/log.$(OBJEXT) \ + commands/version.$(OBJEXT) commands/stats.$(OBJEXT) \ + commands/reload_settings.$(OBJEXT) swanctl.$(OBJEXT) swanctl_OBJECTS = $(am_swanctl_OBJECTS) swanctl_DEPENDENCIES = \ $(top_builddir)/src/libcharon/plugins/vici/libvici.la \ @@ -243,6 +244,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -303,6 +305,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -368,6 +371,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -415,6 +420,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ @@ -434,12 +443,14 @@ swanctl_SOURCES = \ commands/list_conns.c \ commands/list_certs.c \ commands/list_pools.c \ - commands/load_conns.c \ - commands/load_creds.c \ - commands/load_pools.c \ + commands/load_all.c \ + commands/load_conns.c commands/load_conns.h \ + commands/load_creds.c commands/load_creds.h \ + commands/load_pools.c commands/load_pools.h \ commands/log.c \ commands/version.c \ commands/stats.c \ + commands/reload_settings.c \ swanctl.c swanctl.h swanctl_LDADD = \ @@ -571,6 +582,8 @@ commands/list_certs.$(OBJEXT): commands/$(am__dirstamp) \ commands/$(DEPDIR)/$(am__dirstamp) commands/list_pools.$(OBJEXT): commands/$(am__dirstamp) \ commands/$(DEPDIR)/$(am__dirstamp) +commands/load_all.$(OBJEXT): commands/$(am__dirstamp) \ + commands/$(DEPDIR)/$(am__dirstamp) commands/load_conns.$(OBJEXT): commands/$(am__dirstamp) \ commands/$(DEPDIR)/$(am__dirstamp) commands/load_creds.$(OBJEXT): commands/$(am__dirstamp) \ @@ -583,6 +596,8 @@ commands/version.$(OBJEXT): commands/$(am__dirstamp) \ commands/$(DEPDIR)/$(am__dirstamp) commands/stats.$(OBJEXT): commands/$(am__dirstamp) \ commands/$(DEPDIR)/$(am__dirstamp) +commands/reload_settings.$(OBJEXT): commands/$(am__dirstamp) \ + commands/$(DEPDIR)/$(am__dirstamp) swanctl$(EXEEXT): $(swanctl_OBJECTS) $(swanctl_DEPENDENCIES) $(EXTRA_swanctl_DEPENDENCIES) @rm -f swanctl$(EXEEXT) @@ -604,10 +619,12 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/list_pols.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/list_pools.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/list_sas.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/load_all.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/load_conns.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/load_creds.Po@am__quote@ @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)/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@ @AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/version.Po@am__quote@ @@ -955,7 +972,7 @@ swanctl.o : $(top_builddir)/config.status swanctl.conf.5.main: swanctl.opt $(AM_V_GEN) \ - $(PYTHON) $(top_srcdir)/conf/format-options.py -n -f man $< > $(srcdir)/$@ + $(PYTHON) $(top_srcdir)/conf/format-options.py -n -f man swanctl.opt > $(srcdir)/$@ swanctl.conf.5: swanctl.conf.5.head swanctl.conf.5.main swanctl.conf.5.tail $(AM_V_GEN) \ @@ -965,7 +982,7 @@ maintainer-clean-local: cd $(srcdir) && rm -f swanctl.conf swanctl.conf.5.main install-data-local: swanctl.conf - test -e "$(DESTDIR)$(swanctldir)" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)" + test -e "$(DESTDIR)$(swanctldir)" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)" || true test -e "$(DESTDIR)$(swanctldir)/x509" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)/x509" || true test -e "$(DESTDIR)$(swanctldir)/x509ca" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)/x509ca" || true test -e "$(DESTDIR)$(swanctldir)/x509aa" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)/x509aa" || true diff --git a/src/swanctl/command.c b/src/swanctl/command.c index e488273bf..1c079ec3a 100644 --- a/src/swanctl/command.c +++ b/src/swanctl/command.c @@ -220,7 +220,7 @@ int command_usage(char *error, ...) { for (i = 0; i < MAX_COMMANDS && cmds[i].cmd; i++) { - fprintf(out, " swanctl --%-10s (-%c) %s\n", + fprintf(out, " swanctl --%-15s (-%c) %s\n", cmds[i].cmd, cmds[i].op, cmds[i].description); } } @@ -267,9 +267,10 @@ static int call_command(command_t *cmd) conn = vici_connect(uri); if (!conn) { + ret = errno; command_usage("connecting to '%s' URI failed: %s", uri ?: "default", strerror(errno)); - return errno; + return ret; } ret = cmd->call(conn); vici_disconnect(conn); diff --git a/src/swanctl/command.h b/src/swanctl/command.h index 8510fa44d..2d78a24da 100644 --- a/src/swanctl/command.h +++ b/src/swanctl/command.h @@ -27,7 +27,7 @@ /** * Maximum number of commands (+1). */ -#define MAX_COMMANDS 16 +#define MAX_COMMANDS 18 /** * Maximum number of options in a command (+3) diff --git a/src/swanctl/commands/initiate.c b/src/swanctl/commands/initiate.c index 080dc4131..eb7b6adbd 100644 --- a/src/swanctl/commands/initiate.c +++ b/src/swanctl/commands/initiate.c @@ -71,8 +71,9 @@ static int initiate(vici_conn_t *conn) if (vici_register(conn, "control-log", log_cb, &format) != 0) { + ret = errno; fprintf(stderr, "registering for log failed: %s\n", strerror(errno)); - return errno; + return ret; } req = vici_begin("initiate"); if (child) @@ -87,8 +88,9 @@ static int initiate(vici_conn_t *conn) res = vici_submit(req, conn); if (!res) { + ret = errno; fprintf(stderr, "initiate request failed: %s\n", strerror(errno)); - return errno; + return ret; } if (format & COMMAND_FORMAT_RAW) { diff --git a/src/swanctl/commands/install.c b/src/swanctl/commands/install.c index e8727d573..59c5c24ab 100644 --- a/src/swanctl/commands/install.c +++ b/src/swanctl/commands/install.c @@ -55,8 +55,9 @@ static int manage_policy(vici_conn_t *conn, char *label) res = vici_submit(req, conn); if (!res) { + ret = errno; fprintf(stderr, "%s request failed: %s\n", label, strerror(errno)); - return errno; + return ret; } if (format & COMMAND_FORMAT_RAW) { diff --git a/src/swanctl/commands/list_certs.c b/src/swanctl/commands/list_certs.c index bee5fda27..ecb65289a 100644 --- a/src/swanctl/commands/list_certs.c +++ b/src/swanctl/commands/list_certs.c @@ -590,6 +590,7 @@ static int list_certs(vici_conn_t *conn) vici_res_t *res; command_format_options_t format = COMMAND_FORMAT_NONE; char *arg, *subject = NULL, *type = NULL; + int ret; while (TRUE) { @@ -621,9 +622,10 @@ static int list_certs(vici_conn_t *conn) } if (vici_register(conn, "list-cert", list_cb, &format) != 0) { + ret = errno; fprintf(stderr, "registering for certificates failed: %s\n", strerror(errno)); - return errno; + return ret; } req = vici_begin("list-certs"); if (type) @@ -637,8 +639,9 @@ static int list_certs(vici_conn_t *conn) res = vici_submit(req, conn); if (!res) { + ret = errno; fprintf(stderr, "list-certs request failed: %s\n", strerror(errno)); - return errno; + return ret; } if (format & COMMAND_FORMAT_RAW) { diff --git a/src/swanctl/commands/list_conns.c b/src/swanctl/commands/list_conns.c index ec5da4bef..31ab9c40a 100644 --- a/src/swanctl/commands/list_conns.c +++ b/src/swanctl/commands/list_conns.c @@ -183,6 +183,7 @@ static int list_conns(vici_conn_t *conn) vici_res_t *res; command_format_options_t format = COMMAND_FORMAT_NONE; char *arg; + int ret; while (TRUE) { @@ -205,16 +206,18 @@ static int list_conns(vici_conn_t *conn) } if (vici_register(conn, "list-conn", list_cb, &format) != 0) { + ret = errno; fprintf(stderr, "registering for connections failed: %s\n", strerror(errno)); - return errno; + return ret; } req = vici_begin("list-conns"); res = vici_submit(req, conn); if (!res) { + ret = errno; fprintf(stderr, "list-conns request failed: %s\n", strerror(errno)); - return errno; + return ret; } if (format & COMMAND_FORMAT_RAW) { diff --git a/src/swanctl/commands/list_pols.c b/src/swanctl/commands/list_pols.c index 2317b2542..f2ae22172 100644 --- a/src/swanctl/commands/list_pols.c +++ b/src/swanctl/commands/list_pols.c @@ -116,6 +116,7 @@ static int list_pols(vici_conn_t *conn) bool trap = FALSE, drop = FALSE, pass = FALSE; command_format_options_t format = COMMAND_FORMAT_NONE; char *arg, *child = NULL; + int ret; while (TRUE) { @@ -154,9 +155,10 @@ static int list_pols(vici_conn_t *conn) } if (vici_register(conn, "list-policy", list_cb, &format) != 0) { + ret = errno; fprintf(stderr, "registering for policies failed: %s\n", strerror(errno)); - return errno; + return ret; } req = vici_begin("list-policies"); if (child) @@ -178,8 +180,9 @@ static int list_pols(vici_conn_t *conn) res = vici_submit(req, conn); if (!res) { + ret = errno; fprintf(stderr, "list-policies request failed: %s\n", strerror(errno)); - return errno; + return ret; } if (format & COMMAND_FORMAT_RAW) { diff --git a/src/swanctl/commands/list_pools.c b/src/swanctl/commands/list_pools.c index 17ea539a9..155771657 100644 --- a/src/swanctl/commands/list_pools.c +++ b/src/swanctl/commands/list_pools.c @@ -68,8 +68,9 @@ static int list_pools(vici_conn_t *conn) res = vici_submit(req, conn); if (!res) { + ret = errno; fprintf(stderr, "get-pools request failed: %s\n", strerror(errno)); - return errno; + return ret; } if (format & COMMAND_FORMAT_RAW) { diff --git a/src/swanctl/commands/list_sas.c b/src/swanctl/commands/list_sas.c index 80c279ce8..35e7469a9 100644 --- a/src/swanctl/commands/list_sas.c +++ b/src/swanctl/commands/list_sas.c @@ -283,7 +283,7 @@ static int list_sas(vici_conn_t *conn) bool noblock = FALSE; command_format_options_t format = COMMAND_FORMAT_NONE; char *arg, *ike = NULL; - int ike_id = 0; + int ike_id = 0, ret; while (TRUE) { @@ -315,8 +315,9 @@ static int list_sas(vici_conn_t *conn) } if (vici_register(conn, "list-sa", list_cb, &format) != 0) { + ret = errno; fprintf(stderr, "registering for SAs failed: %s\n", strerror(errno)); - return errno; + return ret; } req = vici_begin("list-sas"); if (ike) @@ -334,8 +335,9 @@ static int list_sas(vici_conn_t *conn) res = vici_submit(req, conn); if (!res) { + ret = errno; fprintf(stderr, "list-sas request failed: %s\n", strerror(errno)); - return errno; + return ret; } if (format & COMMAND_FORMAT_RAW) { diff --git a/src/swanctl/commands/load_all.c b/src/swanctl/commands/load_all.c new file mode 100644 index 000000000..f47fee5b4 --- /dev/null +++ b/src/swanctl/commands/load_all.c @@ -0,0 +1,103 @@ +/* + * 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 + * 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. + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <sys/stat.h> + +#include "command.h" +#include "swanctl.h" +#include "load_creds.h" +#include "load_pools.h" +#include "load_conns.h" + +static int load_all(vici_conn_t *conn) +{ + bool clear = FALSE, noprompt = FALSE; + command_format_options_t format = COMMAND_FORMAT_NONE; + settings_t *cfg; + int ret = 0; + char *arg; + + while (TRUE) + { + switch (command_getopt(&arg)) + { + case 'h': + return command_usage(NULL); + case 'c': + clear = TRUE; + continue; + case 'n': + noprompt = TRUE; + continue; + case 'P': + format |= COMMAND_FORMAT_PRETTY; + /* fall through to raw */ + case 'r': + format |= COMMAND_FORMAT_RAW; + continue; + case EOF: + break; + default: + return command_usage("invalid --load-all option"); + } + break; + } + + cfg = settings_create(SWANCTL_CONF); + if (!cfg) + { + fprintf(stderr, "parsing '%s' failed\n", SWANCTL_CONF); + return EINVAL; + } + + if (ret == 0) + { + ret = load_creds_cfg(conn, format, cfg, clear, noprompt); + } + if (ret == 0) + { + ret = load_pools_cfg(conn, format, cfg); + } + if (ret == 0) + { + ret = load_conns_cfg(conn, format, cfg); + } + + cfg->destroy(cfg); + + return ret; +} + +/** + * Register the command. + */ +static void __attribute__ ((constructor))reg() +{ + command_register((command_t) { + load_all, 'q', "load-all", "load credentials, pools and connections", + {"[--raw|--pretty] [--clear] [--noprompt]"}, + { + {"help", 'h', 0, "show usage information"}, + {"clear", 'c', 0, "clear previously loaded credentials"}, + {"noprompt", 'n', 0, "do not prompt for passwords"}, + {"raw", 'r', 0, "dump raw response message"}, + {"pretty", 'P', 0, "dump raw response message in pretty print"}, + } + }); +} diff --git a/src/swanctl/commands/load_conns.c b/src/swanctl/commands/load_conns.c index 7383f7a1e..de30d8eb4 100644 --- a/src/swanctl/commands/load_conns.c +++ b/src/swanctl/commands/load_conns.c @@ -20,6 +20,7 @@ #include "command.h" #include "swanctl.h" +#include "load_conns.h" /** * Check if we should handle a key as a list of comma separated values @@ -319,41 +320,16 @@ static bool unload_conn(vici_conn_t *conn, char *name, return ret; } -static int load_conns(vici_conn_t *conn) +/** + * See header. + */ +int load_conns_cfg(vici_conn_t *conn, command_format_options_t format, + settings_t *cfg) { u_int found = 0, loaded = 0, unloaded = 0; - command_format_options_t format = COMMAND_FORMAT_NONE; - char *arg, *section; + char *section; enumerator_t *enumerator; linked_list_t *conns; - settings_t *cfg; - - 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 EOF: - break; - default: - return command_usage("invalid --load-conns option"); - } - break; - } - - cfg = settings_create(SWANCTL_CONF); - if (!cfg) - { - fprintf(stderr, "parsing '%s' failed\n", SWANCTL_CONF); - return EINVAL; - } conns = list_conns(conn, format); @@ -369,8 +345,6 @@ static int load_conns(vici_conn_t *conn) } enumerator->destroy(enumerator); - cfg->destroy(cfg); - /* unload all connection in daemon, but not in file */ while (conns->remove_first(conns, (void**)§ion) == SUCCESS) { @@ -402,6 +376,47 @@ static int load_conns(vici_conn_t *conn) return EINVAL; } +static int load_conns(vici_conn_t *conn) +{ + command_format_options_t format = COMMAND_FORMAT_NONE; + settings_t *cfg; + char *arg; + int ret; + + 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 EOF: + break; + default: + return command_usage("invalid --load-conns option"); + } + break; + } + + cfg = settings_create(SWANCTL_CONF); + if (!cfg) + { + fprintf(stderr, "parsing '%s' failed\n", SWANCTL_CONF); + return EINVAL; + } + + ret = load_conns_cfg(conn, format, cfg); + + cfg->destroy(cfg); + + return ret; +} + /** * Register the command. */ diff --git a/src/swanctl/commands/load_conns.h b/src/swanctl/commands/load_conns.h new file mode 100644 index 000000000..1e7abdea4 --- /dev/null +++ b/src/swanctl/commands/load_conns.h @@ -0,0 +1,26 @@ +/* + * 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 + * 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" + +/** + * Load all connections from configuration file + * + * @param conn vici connection to load to + * @param format output format + * @param cfg configuration to load from + */ +int load_conns_cfg(vici_conn_t *conn, command_format_options_t format, + settings_t *cfg); diff --git a/src/swanctl/commands/load_creds.c b/src/swanctl/commands/load_creds.c index f77084c60..86ee3c179 100644 --- a/src/swanctl/commands/load_creds.c +++ b/src/swanctl/commands/load_creds.c @@ -21,6 +21,7 @@ #include "command.h" #include "swanctl.h" +#include "load_creds.h" #include <credentials/sets/mem_cred.h> #include <credentials/sets/callback_cred.h> @@ -484,13 +485,50 @@ static bool clear_creds(vici_conn_t *conn, command_format_options_t format) return TRUE; } +/** + * See header. + */ +int load_creds_cfg(vici_conn_t *conn, command_format_options_t format, + settings_t *cfg, bool clear, bool noprompt) +{ + enumerator_t *enumerator; + char *section; + + if (clear) + { + if (!clear_creds(conn, format)) + { + return ECONNREFUSED; + } + } + + load_certs(conn, format, "x509", SWANCTL_X509DIR); + load_certs(conn, format, "x509ca", SWANCTL_X509CADIR); + load_certs(conn, format, "x509aa", SWANCTL_X509AADIR); + load_certs(conn, format, "x509crl", SWANCTL_X509CRLDIR); + load_certs(conn, format, "x509ac", SWANCTL_X509ACDIR); + + load_keys(conn, format, noprompt, cfg, "rsa", SWANCTL_RSADIR); + load_keys(conn, format, noprompt, cfg, "ecdsa", SWANCTL_ECDSADIR); + load_keys(conn, format, noprompt, cfg, "any", SWANCTL_PKCS8DIR); + + enumerator = cfg->create_section_enumerator(cfg, "secrets"); + while (enumerator->enumerate(enumerator, §ion)) + { + load_secret(conn, cfg, section, format); + } + enumerator->destroy(enumerator); + + return 0; +} + static int load_creds(vici_conn_t *conn) { bool clear = FALSE, noprompt = FALSE; command_format_options_t format = COMMAND_FORMAT_NONE; - enumerator_t *enumerator; settings_t *cfg; - char *arg, *section; + char *arg; + int ret; while (TRUE) { @@ -518,14 +556,6 @@ static int load_creds(vici_conn_t *conn) break; } - if (clear) - { - if (!clear_creds(conn, format)) - { - return ECONNREFUSED; - } - } - cfg = settings_create(SWANCTL_CONF); if (!cfg) { @@ -533,26 +563,11 @@ static int load_creds(vici_conn_t *conn) return EINVAL; } - load_certs(conn, format, "x509", SWANCTL_X509DIR); - load_certs(conn, format, "x509ca", SWANCTL_X509CADIR); - load_certs(conn, format, "x509aa", SWANCTL_X509AADIR); - load_certs(conn, format, "x509crl", SWANCTL_X509CRLDIR); - load_certs(conn, format, "x509ac", SWANCTL_X509ACDIR); - - load_keys(conn, format, noprompt, cfg, "rsa", SWANCTL_RSADIR); - load_keys(conn, format, noprompt, cfg, "ecdsa", SWANCTL_ECDSADIR); - load_keys(conn, format, noprompt, cfg, "any", SWANCTL_PKCS8DIR); - - enumerator = cfg->create_section_enumerator(cfg, "secrets"); - while (enumerator->enumerate(enumerator, §ion)) - { - load_secret(conn, cfg, section, format); - } - enumerator->destroy(enumerator); + ret = load_creds_cfg(conn, format, cfg, clear, noprompt); cfg->destroy(cfg); - return 0; + return ret; } /** @@ -562,7 +577,7 @@ static void __attribute__ ((constructor))reg() { command_register((command_t) { load_creds, 's', "load-creds", "(re-)load credentials", - {"[--raw|--pretty]"}, + {"[--raw|--pretty] [--clear] [--noprompt]"}, { {"help", 'h', 0, "show usage information"}, {"clear", 'c', 0, "clear previously loaded credentials"}, diff --git a/src/swanctl/commands/load_creds.h b/src/swanctl/commands/load_creds.h new file mode 100644 index 000000000..7f689ad71 --- /dev/null +++ b/src/swanctl/commands/load_creds.h @@ -0,0 +1,28 @@ +/* + * 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 + * 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" + +/** + * Load all credentials from configuration file + * + * @param conn vici connection to load to + * @param format output format + * @param cfg configuration to load from + * @param clear TRUE to clear existing credentials + * @param noprompt TRUE to skip any password prompt + */ +int load_creds_cfg(vici_conn_t *conn, command_format_options_t format, + settings_t *cfg, bool clear, bool noprompt); diff --git a/src/swanctl/commands/load_pools.c b/src/swanctl/commands/load_pools.c index 0ec56cc43..d7fbd1341 100644 --- a/src/swanctl/commands/load_pools.c +++ b/src/swanctl/commands/load_pools.c @@ -20,6 +20,7 @@ #include "command.h" #include "swanctl.h" +#include "load_pools.h" /** * Add a vici list from a comma separated string value @@ -192,41 +193,16 @@ static bool unload_pool(vici_conn_t *conn, char *name, return ret; } -static int load_pools(vici_conn_t *conn) +/** + * See header. + */ +int load_pools_cfg(vici_conn_t *conn, command_format_options_t format, + settings_t *cfg) { - command_format_options_t format = COMMAND_FORMAT_NONE; u_int found = 0, loaded = 0, unloaded = 0; - char *arg, *section; + char *section; enumerator_t *enumerator; linked_list_t *pools; - settings_t *cfg; - - 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 EOF: - break; - default: - return command_usage("invalid --load-pools option"); - } - break; - } - - cfg = settings_create(SWANCTL_CONF); - if (!cfg) - { - fprintf(stderr, "parsing '%s' failed\n", SWANCTL_CONF); - return EINVAL; - } pools = list_pools(conn, format); @@ -242,8 +218,6 @@ static int load_pools(vici_conn_t *conn) } enumerator->destroy(enumerator); - cfg->destroy(cfg); - /* unload all pools in daemon, but not in file */ while (pools->remove_first(pools, (void**)§ion) == SUCCESS) { @@ -275,6 +249,47 @@ static int load_pools(vici_conn_t *conn) return EINVAL; } +static int load_pools(vici_conn_t *conn) +{ + command_format_options_t format = COMMAND_FORMAT_NONE; + settings_t *cfg; + char *arg; + int ret; + + 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 EOF: + break; + default: + return command_usage("invalid --load-pools option"); + } + break; + } + + cfg = settings_create(SWANCTL_CONF); + if (!cfg) + { + fprintf(stderr, "parsing '%s' failed\n", SWANCTL_CONF); + return EINVAL; + } + + ret = load_pools_cfg(conn, format, cfg); + + cfg->destroy(cfg); + + return ret; +} + /** * Register the command. */ @@ -282,7 +297,7 @@ static void __attribute__ ((constructor))reg() { command_register((command_t) { load_pools, 'a', "load-pools", "(re-)load pool configuration", - {"[--raw|--pretty"}, + {"[--raw|--pretty]"}, { {"help", 'h', 0, "show usage information"}, {"raw", 'r', 0, "dump raw response message"}, diff --git a/src/swanctl/commands/load_pools.h b/src/swanctl/commands/load_pools.h new file mode 100644 index 000000000..f424db9f1 --- /dev/null +++ b/src/swanctl/commands/load_pools.h @@ -0,0 +1,26 @@ +/* + * 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 + * 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" + +/** + * Load all pool definitions from configuration file + * + * @param conn vici connection to load to + * @param format output format + * @param cfg configuration to load from + */ +int load_pools_cfg(vici_conn_t *conn, command_format_options_t format, + settings_t *cfg); diff --git a/src/swanctl/commands/log.c b/src/swanctl/commands/log.c index 99ba328a7..d7082bfca 100644 --- a/src/swanctl/commands/log.c +++ b/src/swanctl/commands/log.c @@ -50,6 +50,7 @@ static int logcmd(vici_conn_t *conn) { command_format_options_t format = COMMAND_FORMAT_NONE; char *arg; + int ret; while (TRUE) { @@ -73,8 +74,9 @@ static int logcmd(vici_conn_t *conn) if (vici_register(conn, "log", log_cb, &format) != 0) { + ret = errno; fprintf(stderr, "registering for log failed: %s\n", strerror(errno)); - return errno; + return ret; } wait_sigint(); diff --git a/src/swanctl/commands/reload_settings.c b/src/swanctl/commands/reload_settings.c new file mode 100644 index 000000000..efad1300f --- /dev/null +++ b/src/swanctl/commands/reload_settings.c @@ -0,0 +1,88 @@ +/* + * 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 + * 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 reload_settings(vici_conn_t *conn) +{ + vici_req_t *req; + vici_res_t *res; + char *arg; + int ret = 0; + command_format_options_t format = COMMAND_FORMAT_NONE; + + 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 EOF: + break; + default: + return command_usage("invalid --reload-settings option"); + } + break; + } + + req = vici_begin("reload-settings"); + res = vici_submit(req, conn); + if (!res) + { + ret = errno; + fprintf(stderr, "reload-settings request failed: %s\n", strerror(errno)); + return ret; + } + if (format & COMMAND_FORMAT_RAW) + { + vici_dump(res, "reload-settings reply", + format & COMMAND_FORMAT_PRETTY, stdout); + } + else + { + if (!streq(vici_find_str(res, "no", "success"), "yes")) + { + fprintf(stderr, "reload-settings 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) { + reload_settings, 'r', "reload-settings", "reload daemon strongswan.conf", + {"[--raw|--pretty]"}, + { + {"help", 'h', 0, "show usage information"}, + {"raw", 'r', 0, "dump raw response message"}, + {"pretty", 'P', 0, "dump raw response message in pretty print"}, + } + }); +} diff --git a/src/swanctl/commands/stats.c b/src/swanctl/commands/stats.c index b5425f504..a28ca83ba 100644 --- a/src/swanctl/commands/stats.c +++ b/src/swanctl/commands/stats.c @@ -23,6 +23,7 @@ static int stats(vici_conn_t *conn) vici_res_t *res; char *arg; command_format_options_t format = COMMAND_FORMAT_NONE; + int ret; while (TRUE) { @@ -48,8 +49,9 @@ static int stats(vici_conn_t *conn) res = vici_submit(req, conn); if (!res) { + ret = errno; fprintf(stderr, "stats request failed: %s\n", strerror(errno)); - return errno; + return ret; } if (format & COMMAND_FORMAT_RAW) { diff --git a/src/swanctl/commands/terminate.c b/src/swanctl/commands/terminate.c index 689ba4d50..8b3233c89 100644 --- a/src/swanctl/commands/terminate.c +++ b/src/swanctl/commands/terminate.c @@ -80,8 +80,9 @@ static int terminate(vici_conn_t *conn) if (vici_register(conn, "control-log", log_cb, &format) != 0) { + ret = errno; fprintf(stderr, "registering for log failed: %s\n", strerror(errno)); - return errno; + return ret; } req = vici_begin("terminate"); if (child) @@ -108,8 +109,9 @@ static int terminate(vici_conn_t *conn) res = vici_submit(req, conn); if (!res) { + ret = errno; fprintf(stderr, "terminate request failed: %s\n", strerror(errno)); - return errno; + return ret; } if (format & COMMAND_FORMAT_RAW) { diff --git a/src/swanctl/commands/version.c b/src/swanctl/commands/version.c index 4f24a0fc2..0c499e4cc 100644 --- a/src/swanctl/commands/version.c +++ b/src/swanctl/commands/version.c @@ -24,6 +24,7 @@ static int version(vici_conn_t *conn) char *arg; bool daemon = FALSE; command_format_options_t format = COMMAND_FORMAT_NONE; + int ret; while (TRUE) { @@ -58,8 +59,9 @@ static int version(vici_conn_t *conn) res = vici_submit(req, conn); if (!res) { + ret = errno; fprintf(stderr, "version request failed: %s\n", strerror(errno)); - return errno; + return ret; } if (format & COMMAND_FORMAT_RAW) { diff --git a/src/swanctl/swanctl.8.in b/src/swanctl/swanctl.8.in index d7abae67a..543c10a67 100644 --- a/src/swanctl/swanctl.8.in +++ b/src/swanctl/swanctl.8.in @@ -62,6 +62,9 @@ list stored certificates .B "\-A, \-\-list\-pools" list loaded pool configurations .TP +.B "\-q, \-\-load\-all" +(re\-)load credentials, pools and connections +.TP .B "\-c, \-\-load\-conns" (re\-)load connection configuration .TP @@ -74,6 +77,12 @@ list loaded pool configurations .B "\-T, \-\-log" trace logging output .TP +.B "\-S, \-\-stats" +show daemon infos and statistics +.TP +.B "\-r, \-\-reload-settings" +reload strongswan.conf(5) configuration +.TP .B "\-v, \-\-version" show daemon version information .TP diff --git a/src/swanctl/swanctl.conf b/src/swanctl/swanctl.conf index 8cff81feb..0808cf58b 100644 --- a/src/swanctl/swanctl.conf +++ b/src/swanctl/swanctl.conf @@ -49,7 +49,7 @@ # Send certificate requests payloads (yes or no). # send_certreq = yes - # Send certificate payloads (yes, no or ifasked). + # Send certificate payloads (always, never or ifasked). # send_cert = ifasked # Number of retransmission sequences to perform during initial connect. @@ -113,7 +113,7 @@ # Comma separated list of CA certificates to accept for # authentication. - # cacert = + # cacerts = # Certificate revocation policy, (strict, ifuri or relaxed). # revocation = relaxed diff --git a/src/swanctl/swanctl.conf.5.main b/src/swanctl/swanctl.conf.5.main index 3d0b0e827..8943b62db 100644 --- a/src/swanctl/swanctl.conf.5.main +++ b/src/swanctl/swanctl.conf.5.main @@ -181,11 +181,12 @@ default of .RI "" "ifasked" "" the daemon sends certificate payloads only if certificate requests have been received. -.RI "" "no" "" -disables sending of certificate payloads, -.RI "" "yes" "" -always sends certificate payloads whenever certificate authentication is -used. +.RI "" "never" "" +disables sending of certificate payloads +altogether, +.RI "" "always" "" +causes certificate payloads to be sent unconditionally +whenever certificate authentication is used. .TP .BR connections.<conn>.keyingtries " [1]" @@ -221,6 +222,14 @@ To compare connections for uniqueness, the remote IKE identity is used. If EAP or XAuth authentication is involved, the EAP\-Identity or XAuth username is used to enforce the uniqueness policy instead. +On initiators this setting specifies whether an INITIAL_CONTACT notify is sent +during IKE_AUTH if no existing connection is found with the remote peer +(determined by the identities of the first authentication round). Only if set to +.RI "" "keep" "" +or +.RI "" "replace" "" +will the client send a notify. + .TP .BR connections.<conn>.reauth_time " [0s]" Time to schedule IKE reauthentication. IKE reauthentication recreates the @@ -409,7 +418,7 @@ directory, or an absolute path. .TP -.BR connections.<conn>.remote<suffix>.cacert " []" +.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 .RB "" "swanctl" "" diff --git a/src/swanctl/swanctl.opt b/src/swanctl/swanctl.opt index e136ffb5b..f1e47a9e4 100644 --- a/src/swanctl/swanctl.opt +++ b/src/swanctl/swanctl.opt @@ -161,13 +161,13 @@ connections.<conn>.send_certreq = yes of the initial IKE packets. connections.<conn>.send_cert = ifasked - Send certificate payloads (_yes_, _no_ or _ifasked_). + Send certificate payloads (_always_, _never_ or _ifasked_). Send certificate payloads when using certificate authentication. With the default of _ifasked_ the daemon sends certificate payloads only if - certificate requests have been received. _no_ disables sending of - certificate payloads, _yes_ always sends certificate payloads whenever - certificate authentication is used. + certificate requests have been received. _never_ disables sending of + certificate payloads altogether, _always_ causes certificate payloads to be + sent unconditionally whenever certificate authentication is used. connections.<conn>.keyingtries = 1 Number of retransmission sequences to perform during initial connect. @@ -194,6 +194,11 @@ connections.<conn>.unique = no EAP or XAuth authentication is involved, the EAP-Identity or XAuth username is used to enforce the uniqueness policy instead. + On initiators this setting specifies whether an INITIAL_CONTACT notify is + sent during IKE_AUTH if no existing connection is found with the remote + peer (determined by the identities of the first authentication round). + Only if set to _keep_ or _replace_ will the client send a notify. + connections.<conn>.reauth_time = 0s Time to schedule IKE reauthentication. @@ -349,7 +354,7 @@ 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>.cacert = +connections.<conn>.remote<suffix>.cacerts = Comma separated list of CA certificates to accept for authentication. Comma separated list of CA certificates to accept for authentication. |