summaryrefslogtreecommitdiff
path: root/src/charon/plugins/stroke
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2009-06-23 11:25:24 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2009-06-23 11:25:24 +0000
commit41787e147279ff0695e9d759487266a60b80867b (patch)
tree8f28566c8fd7106c80d2536d2df540dbb4499cc5 /src/charon/plugins/stroke
parentc3e7f611ea8273c6b3909cb006ade4903a74aad0 (diff)
downloadvyos-strongswan-41787e147279ff0695e9d759487266a60b80867b.tar.gz
vyos-strongswan-41787e147279ff0695e9d759487266a60b80867b.zip
[svn-upgrade] Integrating new upstream version, strongswan (4.3.2)
Diffstat (limited to 'src/charon/plugins/stroke')
-rw-r--r--src/charon/plugins/stroke/Makefile.am5
-rw-r--r--src/charon/plugins/stroke/Makefile.in23
-rw-r--r--src/charon/plugins/stroke/stroke_attribute.c22
-rw-r--r--src/charon/plugins/stroke/stroke_attribute.h2
-rw-r--r--src/charon/plugins/stroke/stroke_ca.c8
-rw-r--r--src/charon/plugins/stroke/stroke_ca.h2
-rw-r--r--src/charon/plugins/stroke/stroke_config.c732
-rw-r--r--src/charon/plugins/stroke/stroke_config.h2
-rw-r--r--src/charon/plugins/stroke/stroke_control.c203
-rw-r--r--src/charon/plugins/stroke/stroke_control.h15
-rw-r--r--src/charon/plugins/stroke/stroke_cred.c81
-rw-r--r--src/charon/plugins/stroke/stroke_cred.h2
-rw-r--r--src/charon/plugins/stroke/stroke_list.c335
-rw-r--r--src/charon/plugins/stroke/stroke_list.h2
-rw-r--r--src/charon/plugins/stroke/stroke_plugin.c2
-rw-r--r--src/charon/plugins/stroke/stroke_plugin.h2
-rw-r--r--src/charon/plugins/stroke/stroke_shared_key.c2
-rw-r--r--src/charon/plugins/stroke/stroke_shared_key.h2
-rw-r--r--src/charon/plugins/stroke/stroke_socket.c48
-rw-r--r--src/charon/plugins/stroke/stroke_socket.h2
20 files changed, 808 insertions, 684 deletions
diff --git a/src/charon/plugins/stroke/Makefile.am b/src/charon/plugins/stroke/Makefile.am
index 7a341102b..fb58ba62b 100644
--- a/src/charon/plugins/stroke/Makefile.am
+++ b/src/charon/plugins/stroke/Makefile.am
@@ -1,7 +1,10 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon -I$(top_srcdir)/src/stroke
-AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_PIDDIR=\"${piddir}\"
+AM_CFLAGS = \
+-rdynamic \
+-DIPSEC_CONFDIR=\"${confdir}\" \
+-DIPSEC_PIDDIR=\"${piddir}\"
plugin_LTLIBRARIES = libstrongswan-stroke.la
diff --git a/src/charon/plugins/stroke/Makefile.in b/src/charon/plugins/stroke/Makefile.in
index 645ae2a48..f246286a0 100644
--- a/src/charon/plugins/stroke/Makefile.in
+++ b/src/charon/plugins/stroke/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -90,6 +90,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -112,6 +113,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -123,6 +127,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -136,6 +141,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -196,6 +203,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -207,12 +215,17 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon -I$(top_srcdir)/src/stroke
-AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_PIDDIR=\"${piddir}\"
+AM_CFLAGS = \
+-rdynamic \
+-DIPSEC_CONFDIR=\"${confdir}\" \
+-DIPSEC_PIDDIR=\"${piddir}\"
+
plugin_LTLIBRARIES = libstrongswan-stroke.la
libstrongswan_stroke_la_SOURCES = stroke_plugin.h stroke_plugin.c \
stroke_socket.h stroke_socket.c \
@@ -233,8 +246,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -336,7 +349,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/stroke/stroke_attribute.c b/src/charon/plugins/stroke/stroke_attribute.c
index f850b5320..a7925ce3e 100644
--- a/src/charon/plugins/stroke/stroke_attribute.c
+++ b/src/charon/plugins/stroke/stroke_attribute.c
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id$
*/
#include "stroke_attribute.h"
@@ -191,7 +189,7 @@ int host2offset(pool_t *pool, host_t *addr)
*/
static host_t* acquire_address(private_stroke_attribute_t *this,
char *name, identification_t *id,
- auth_info_t *auth, host_t *requested)
+ host_t *requested)
{
pool_t *pool;
uintptr_t offset = 0;
@@ -208,8 +206,9 @@ static host_t* acquire_address(private_stroke_attribute_t *this,
this->mutex->unlock(this->mutex);
return requested->clone(requested);
}
-
- if (requested->get_family(requested) !=
+
+ if (!requested->is_anyaddr(requested) &&
+ requested->get_family(requested) !=
pool->base->get_family(pool->base))
{
DBG1(DBG_CFG, "IP pool address family mismatch");
@@ -223,7 +222,7 @@ static host_t* acquire_address(private_stroke_attribute_t *this,
id = pool->ids->get(pool->ids, id);
if (id)
{
- DBG1(DBG_CFG, "reassigning offline lease to %D", id);
+ DBG1(DBG_CFG, "reassigning offline lease to '%Y'", id);
pool->online->put(pool->online, id, (void*)offset);
break;
}
@@ -233,7 +232,7 @@ static host_t* acquire_address(private_stroke_attribute_t *this,
offset = (uintptr_t)pool->online->get(pool->online, id);
if (offset && offset == host2offset(pool, requested))
{
- DBG1(DBG_CFG, "reassigning online lease to %D", id);
+ DBG1(DBG_CFG, "reassigning online lease to '%Y'", id);
break;
}
@@ -245,7 +244,7 @@ static host_t* acquire_address(private_stroke_attribute_t *this,
id = id->clone(id);
pool->ids->put(pool->ids, id, id);
pool->online->put(pool->online, id, (void*)offset);
- DBG1(DBG_CFG, "assigning new lease to %D", id);
+ DBG1(DBG_CFG, "assigning new lease to '%Y'", id);
break;
}
/* no more addresses, replace the first found offline lease */
@@ -257,7 +256,7 @@ static host_t* acquire_address(private_stroke_attribute_t *this,
{
/* destroy reference to old ID */
old_id = pool->ids->remove(pool->ids, old_id);
- DBG1(DBG_CFG, "reassigning existing offline lease of %D to %D",
+ DBG1(DBG_CFG, "reassigning existing offline lease by '%Y' to '%Y'",
old_id, id);
if (old_id)
{
@@ -305,7 +304,7 @@ static bool release_address(private_stroke_attribute_t *this,
id = pool->ids->get(pool->ids, id);
if (id)
{
- DBG1(DBG_CFG, "lease %H of %D went offline", address, id);
+ DBG1(DBG_CFG, "lease %H by '%Y' went offline", address, id);
pool->offline->put(pool->offline, id, (void*)offset);
found = TRUE;
}
@@ -530,8 +529,9 @@ stroke_attribute_t *stroke_attribute_create()
{
private_stroke_attribute_t *this = malloc_thing(private_stroke_attribute_t);
- this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *,auth_info_t *, host_t *))acquire_address;
+ this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *,host_t *))acquire_address;
this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *, identification_t*))release_address;
+ this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, identification_t *id))enumerator_create_empty;
this->public.add_pool = (void(*)(stroke_attribute_t*, stroke_msg_t *msg))add_pool;
this->public.del_pool = (void(*)(stroke_attribute_t*, stroke_msg_t *msg))del_pool;
this->public.create_pool_enumerator = (enumerator_t*(*)(stroke_attribute_t*))create_pool_enumerator;
diff --git a/src/charon/plugins/stroke/stroke_attribute.h b/src/charon/plugins/stroke/stroke_attribute.h
index 41ab6299b..fc273d1cb 100644
--- a/src/charon/plugins/stroke/stroke_attribute.h
+++ b/src/charon/plugins/stroke/stroke_attribute.h
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/stroke/stroke_ca.c b/src/charon/plugins/stroke/stroke_ca.c
index 54356436f..fab06e6c5 100644
--- a/src/charon/plugins/stroke/stroke_ca.c
+++ b/src/charon/plugins/stroke/stroke_ca.c
@@ -12,8 +12,6 @@
* 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.
- *
- * $Id$
*/
#include "stroke_ca.h"
@@ -398,14 +396,14 @@ static void list(private_stroke_ca_t *this, stroke_msg_t *msg, FILE *out)
first = FALSE;
}
fprintf(out, "\n");
- fprintf(out, " authname: \"%D\"\n", cert->get_subject(cert));
+ fprintf(out, " authname: \"%Y\"\n", cert->get_subject(cert));
/* list authkey and keyid */
if (public)
{
- fprintf(out, " authkey: %D\n",
+ fprintf(out, " authkey: %Y\n",
public->get_id(public, ID_PUBKEY_SHA1));
- fprintf(out, " keyid: %D\n",
+ fprintf(out, " keyid: %Y\n",
public->get_id(public, ID_PUBKEY_INFO_SHA1));
public->destroy(public);
}
diff --git a/src/charon/plugins/stroke/stroke_ca.h b/src/charon/plugins/stroke/stroke_ca.h
index ee759ff4e..c882d7b4e 100644
--- a/src/charon/plugins/stroke/stroke_ca.h
+++ b/src/charon/plugins/stroke/stroke_ca.h
@@ -12,8 +12,6 @@
* 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.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/stroke/stroke_config.c b/src/charon/plugins/stroke/stroke_config.c
index 59c58ca0d..028e71e71 100644
--- a/src/charon/plugins/stroke/stroke_config.c
+++ b/src/charon/plugins/stroke/stroke_config.c
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id$
*/
#include "stroke_config.h"
@@ -55,90 +53,21 @@ struct private_stroke_config_t {
};
/**
- * data to pass peer_filter
- */
-typedef struct {
- private_stroke_config_t *this;
- identification_t *me;
- identification_t *other;
-} peer_data_t;
-
-/**
- * destroy id enumerator data and unlock list
- */
-static void peer_data_destroy(peer_data_t *data)
-{
- data->this->mutex->unlock(data->this->mutex);
- free(data);
-}
-
-/**
- * filter function for peer configs
- */
-static bool peer_filter(peer_data_t *data, peer_cfg_t **in, peer_cfg_t **out)
-{
- bool match_me = FALSE, match_other = FALSE;
- identification_t *me, *other;
-
- me = (*in)->get_my_id(*in);
- other = (*in)->get_other_id(*in);
-
- /* own ID may have wildcards in data (no IDr payload) or in config */
- match_me = (!data->me || data->me->matches(data->me, me) ||
- me->matches(me, data->me));
- /* others ID has wildcards in config only */
- match_other = (!data->other || data->other->matches(data->other, other));
-
- if (match_me && match_other)
- {
- *out = *in;
- return TRUE;
- }
- return FALSE;
-}
-
-/**
* Implementation of backend_t.create_peer_cfg_enumerator.
*/
static enumerator_t* create_peer_cfg_enumerator(private_stroke_config_t *this,
identification_t *me,
identification_t *other)
{
- peer_data_t *data;
-
- data = malloc_thing(peer_data_t);
- data->this = this;
- data->me = me;
- data->other = other;
-
this->mutex->lock(this->mutex);
- return enumerator_create_filter(this->list->create_enumerator(this->list),
- (void*)peer_filter, data,
- (void*)peer_data_destroy);
-}
-
-/**
- * data to pass ike_filter
- */
-typedef struct {
- private_stroke_config_t *this;
- host_t *me;
- host_t *other;
-} ike_data_t;
-
-/**
- * destroy id enumerator data and unlock list
- */
-static void ike_data_destroy(ike_data_t *data)
-{
- data->this->mutex->unlock(data->this->mutex);
- free(data);
+ return enumerator_create_cleaner(this->list->create_enumerator(this->list),
+ (void*)this->mutex->unlock, this->mutex);
}
/**
* filter function for ike configs
*/
-static bool ike_filter(ike_data_t *data, peer_cfg_t **in, ike_cfg_t **out)
+static bool ike_filter(void *data, peer_cfg_t **in, ike_cfg_t **out)
{
*out = (*in)->get_ike_cfg(*in);
return TRUE;
@@ -150,17 +79,10 @@ static bool ike_filter(ike_data_t *data, peer_cfg_t **in, ike_cfg_t **out)
static enumerator_t* create_ike_cfg_enumerator(private_stroke_config_t *this,
host_t *me, host_t *other)
{
- ike_data_t *data;
-
- data = malloc_thing(ike_data_t);
- data->this = this;
- data->me = me;
- data->other = other;
-
this->mutex->lock(this->mutex);
return enumerator_create_filter(this->list->create_enumerator(this->list),
- (void*)ike_filter, data,
- (void*)ike_data_destroy);
+ (void*)ike_filter, this->mutex,
+ (void*)this->mutex->unlock);
}
/**
@@ -171,34 +93,34 @@ static peer_cfg_t *get_peer_cfg_by_name(private_stroke_config_t *this, char *nam
enumerator_t *e1, *e2;
peer_cfg_t *current, *found = NULL;
child_cfg_t *child;
-
+
this->mutex->lock(this->mutex);
e1 = this->list->create_enumerator(this->list);
while (e1->enumerate(e1, &current))
{
- /* compare peer_cfgs name first */
- if (streq(current->get_name(current), name))
- {
- found = current;
- found->get_ref(found);
- break;
- }
- /* compare all child_cfg names otherwise */
- e2 = current->create_child_cfg_enumerator(current);
- while (e2->enumerate(e2, &child))
- {
- if (streq(child->get_name(child), name))
- {
- found = current;
- found->get_ref(found);
- break;
- }
- }
- e2->destroy(e2);
- if (found)
- {
- break;
- }
+ /* compare peer_cfgs name first */
+ if (streq(current->get_name(current), name))
+ {
+ found = current;
+ found->get_ref(found);
+ break;
+ }
+ /* compare all child_cfg names otherwise */
+ e2 = current->create_child_cfg_enumerator(current);
+ while (e2->enumerate(e2, &child))
+ {
+ if (streq(child->get_name(child), name))
+ {
+ found = current;
+ found->get_ref(found);
+ break;
+ }
+ }
+ e2->destroy(e2);
+ if (found)
+ {
+ break;
+ }
}
e1->destroy(e1);
this->mutex->unlock(this->mutex);
@@ -206,22 +128,6 @@ static peer_cfg_t *get_peer_cfg_by_name(private_stroke_config_t *this, char *nam
}
/**
- * check if a certificate has an ID
- */
-static identification_t *update_peerid(certificate_t *cert, identification_t *id)
-{
- if (id->get_type(id) == ID_ANY || !cert->has_subject(cert, id))
- {
- DBG1(DBG_CFG, " peerid %D not confirmed by certificate, "
- "defaulting to subject DN", id);
- id->destroy(id);
- id = cert->get_subject(cert);
- return id->clone(id);
- }
- return id;
-}
-
-/**
* parse a proposal string, either into ike_cfg or child_cfg
*/
static void add_proposals(private_stroke_config_t *this, char *string,
@@ -332,45 +238,303 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg
add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg, NULL);
return ike_cfg;
}
+
/**
- * build a peer_cfg from a stroke msg
+ * Add CRL constraint to config
*/
-static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
- stroke_msg_t *msg, ike_cfg_t *ike_cfg,
- identification_t **my_issuer,
- identification_t **other_issuer)
+static void build_crl_policy(auth_cfg_t *cfg, bool local, int policy)
{
- identification_t *me, *other, *peer_id = NULL;
- peer_cfg_t *mediated_by = NULL;
- host_t *vip = NULL;
- certificate_t *cert;
- unique_policy_t unique;
- u_int32_t rekey = 0, reauth = 0, over, jitter;
+ /* CRL/OCSP policy, for remote config only */
+ if (!local)
+ {
+ switch (policy)
+ {
+ case CRL_STRICT_YES:
+ /* if yes, we require a GOOD validation */
+ cfg->add(cfg, AUTH_RULE_CRL_VALIDATION, VALIDATION_GOOD);
+ break;
+ case CRL_STRICT_IFURI:
+ /* for ifuri, a SKIPPED validation is sufficient */
+ cfg->add(cfg, AUTH_RULE_CRL_VALIDATION, VALIDATION_SKIPPED);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/**
+ * build authentication config
+ */
+static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
+ stroke_msg_t *msg, bool local, bool primary)
+{
+ identification_t *identity;
+ certificate_t *certificate;
+ char *auth, *id, *cert, *ca;
+ stroke_end_t *end, *other_end;
+ auth_cfg_t *cfg;
+ char eap_buf[32];
- me = identification_create_from_string(msg->add_conn.me.id ?
- msg->add_conn.me.id : msg->add_conn.me.address);
- if (!me)
+ /* select strings */
+ if (local)
{
- DBG1(DBG_CFG, "invalid ID: %s\n", msg->add_conn.me.id);
- return NULL;
+ end = &msg->add_conn.me;
+ other_end = &msg->add_conn.other;
}
- other = identification_create_from_string(msg->add_conn.other.id ?
- msg->add_conn.other.id : msg->add_conn.other.address);
- if (!other)
+ else
{
- DBG1(DBG_CFG, "invalid ID: %s\n", msg->add_conn.other.id);
- me->destroy(me);
- return NULL;
+ end = &msg->add_conn.other;
+ other_end = &msg->add_conn.me;
+ }
+ if (primary)
+ {
+ auth = end->auth;
+ id = end->id;
+ if (!id)
+ { /* leftid/rightid fallback to address */
+ id = end->address;
+ }
+ cert = end->cert;
+ ca = end->ca;
+ if (ca && streq(ca, "%same"))
+ {
+ ca = other_end->ca;
+ }
+ }
+ else
+ {
+ auth = end->auth2;
+ id = end->id2;
+ if (local && !id)
+ { /* leftid2 falls back to leftid */
+ id = end->id;
+ }
+ cert = end->cert2;
+ ca = end->ca2;
+ if (ca && streq(ca, "%same"))
+ {
+ ca = other_end->ca2;
+ }
+ }
+
+ if (!auth)
+ {
+ if (primary)
+ {
+ if (local)
+ { /* "leftauth" not defined, fall back to deprecated "authby" */
+ switch (msg->add_conn.auth_method)
+ {
+ default:
+ case AUTH_CLASS_PUBKEY:
+ auth = "pubkey";
+ break;
+ case AUTH_CLASS_PSK:
+ auth = "psk";
+ break;
+ case AUTH_CLASS_EAP:
+ auth = "eap";
+ break;
+ }
+ }
+ else
+ { /* "rightauth" not defined, fall back to deprecated "eap" */
+ if (msg->add_conn.eap_type)
+ {
+ if (msg->add_conn.eap_vendor)
+ {
+ snprintf(eap_buf, sizeof(eap_buf), "eap-%d-%d",
+ msg->add_conn.eap_type,
+ msg->add_conn.eap_vendor);
+ }
+ else
+ {
+ snprintf(eap_buf, sizeof(eap_buf), "eap-%d",
+ msg->add_conn.eap_type);
+ }
+ auth = eap_buf;
+ }
+ else
+ { /* not EAP => no constraints for this peer */
+ auth = "any";
+ }
+ }
+ }
+ else
+ { /* no second authentication round, fine */
+ return NULL;
+ }
}
+ cfg = auth_cfg_create();
+
+ /* add identity and peer certifcate */
+ identity = identification_create_from_string(id);
+ if (cert)
+ {
+ certificate = this->cred->load_peer(this->cred, cert);
+ if (certificate)
+ {
+ if (local)
+ {
+ this->ca->check_for_hash_and_url(this->ca, certificate);
+ }
+ cfg->add(cfg, AUTH_RULE_SUBJECT_CERT, certificate);
+ if (identity->get_type(identity) == ID_ANY ||
+ !certificate->has_subject(certificate, identity))
+ {
+ DBG1(DBG_CFG, " peerid %Y not confirmed by certificate, "
+ "defaulting to subject DN: %Y", identity,
+ certificate->get_subject(certificate));
+ identity->destroy(identity);
+ identity = certificate->get_subject(certificate);
+ identity = identity->clone(identity);
+ }
+ }
+ }
+ cfg->add(cfg, AUTH_RULE_IDENTITY, identity);
+
+ /* CA constraint */
+ if (ca)
+ {
+ identity = identification_create_from_string(ca);
+ certificate = charon->credentials->get_cert(charon->credentials,
+ CERT_X509, KEY_ANY, identity, TRUE);
+ identity->destroy(identity);
+ if (certificate)
+ {
+ cfg->add(cfg, AUTH_RULE_CA_CERT, certificate);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "CA certificate %s not found, discarding CA "
+ "constraint", ca);
+ }
+ }
+
+ /* AC groups */
+ if (end->groups)
+ {
+ enumerator_t *enumerator;
+ char *group;
+
+ enumerator = enumerator_create_token(end->groups, ",", " ");
+ while (enumerator->enumerate(enumerator, &group))
+ {
+ identity = identification_create_from_encoding(ID_IETF_ATTR_STRING,
+ chunk_create(group, strlen(group)));
+ cfg->add(cfg, AUTH_RULE_AC_GROUP, identity);
+ }
+ enumerator->destroy(enumerator);
+ }
+
+ /* authentication metod (class, actually) */
+ if (streq(auth, "pubkey") ||
+ streq(auth, "rsasig") || streq(auth, "rsa") ||
+ streq(auth, "ecdsasig") || streq(auth, "ecdsa"))
+ {
+ cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+ build_crl_policy(cfg, local, msg->add_conn.crl_policy);
+ }
+ else if (streq(auth, "psk") || streq(auth, "secret"))
+ {
+ cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
+ }
+ else if (strneq(auth, "eap", 3))
+ {
+ enumerator_t *enumerator;
+ char *str;
+ int i = 0, type = 0, vendor;
+
+ cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
+
+ /* parse EAP string, format: eap[-type[-vendor]] */
+ enumerator = enumerator_create_token(auth, "-", " ");
+ while (enumerator->enumerate(enumerator, &str))
+ {
+ switch (i)
+ {
+ case 1:
+ type = eap_type_from_string(str);
+ if (!type)
+ {
+ type = atoi(str);
+ if (!type)
+ {
+ DBG1(DBG_CFG, "unknown EAP method: %s", str);
+ break;
+ }
+ }
+ cfg->add(cfg, AUTH_RULE_EAP_TYPE, type);
+ break;
+ case 2:
+ if (type)
+ {
+ vendor = atoi(str);
+ if (vendor)
+ {
+ cfg->add(cfg, AUTH_RULE_EAP_VENDOR, vendor);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "unknown EAP vendor: %s", str);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ i++;
+ }
+ enumerator->destroy(enumerator);
+
+ if (msg->add_conn.eap_identity)
+ {
+ if (streq(msg->add_conn.eap_identity, "%identity"))
+ {
+ identity = identification_create_from_encoding(ID_ANY,
+ chunk_empty);
+ }
+ else
+ {
+ identity = identification_create_from_string(
+ msg->add_conn.eap_identity);
+ }
+ cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, identity);
+ }
+ }
+ else
+ {
+ if (!streq(auth, "any"))
+ {
+ DBG1(DBG_CFG, "authentication method %s unknown, fallback to any",
+ auth);
+ }
+ build_crl_policy(cfg, local, msg->add_conn.crl_policy);
+ }
+ return cfg;
+}
+
+/**
+ * build a peer_cfg from a stroke msg
+ */
+static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
+ stroke_msg_t *msg, ike_cfg_t *ike_cfg)
+{
+ identification_t *peer_id = NULL;
+ peer_cfg_t *mediated_by = NULL;
+ host_t *vip = NULL;
+ unique_policy_t unique;
+ u_int32_t rekey = 0, reauth = 0, over, jitter;
+ peer_cfg_t *peer_cfg;
+ auth_cfg_t *auth_cfg;
#ifdef ME
if (msg->add_conn.ikeme.mediation && msg->add_conn.ikeme.mediated_by)
{
DBG1(DBG_CFG, "a mediation connection cannot be a"
" mediated connection at the same time, aborting");
- me->destroy(me);
- other->destroy(other);
return NULL;
}
@@ -388,8 +552,6 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
{
DBG1(DBG_CFG, "mediation connection '%s' not found, aborting",
msg->add_conn.ikeme.mediated_by);
- me->destroy(me);
- other->destroy(other);
return NULL;
}
@@ -399,56 +561,19 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
"no mediation connection, aborting",
msg->add_conn.ikeme.mediated_by, msg->add_conn.name);
mediated_by->destroy(mediated_by);
- me->destroy(me);
- other->destroy(other);
return NULL;
}
- }
-
- if (msg->add_conn.ikeme.peerid)
- {
- peer_id = identification_create_from_string(msg->add_conn.ikeme.peerid);
- if (!peer_id)
- {
- DBG1(DBG_CFG, "invalid peer ID: %s\n", msg->add_conn.ikeme.peerid);
- mediated_by->destroy(mediated_by);
- me->destroy(me);
- other->destroy(other);
- return NULL;
- }
- }
- else
- {
- /* no peer ID supplied, assume right ID */
- peer_id = other->clone(other);
- }
-#endif /* ME */
-
- if (msg->add_conn.me.cert)
- {
- cert = this->cred->load_peer(this->cred, msg->add_conn.me.cert);
- if (cert)
+ if (msg->add_conn.ikeme.peerid)
{
- identification_t *issuer = cert->get_issuer(cert);
-
- *my_issuer = issuer->clone(issuer);
- this->ca->check_for_hash_and_url(this->ca, cert);
- me = update_peerid(cert, me);
- cert->destroy(cert);
+ peer_id = identification_create_from_string(msg->add_conn.ikeme.peerid);
}
- }
- if (msg->add_conn.other.cert)
- {
- cert = this->cred->load_peer(this->cred, msg->add_conn.other.cert);
- if (cert)
+ else if (msg->add_conn.other.id)
{
- identification_t *issuer = cert->get_issuer(cert);
-
- *other_issuer = issuer->clone(issuer);
- other = update_peerid(cert, other);
- cert->destroy(cert);
+ peer_id = identification_create_from_string(msg->add_conn.other.id);
}
}
+#endif /* ME */
+
jitter = msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100;
over = msg->add_conn.rekey.margin;
if (msg->add_conn.rekey.reauth)
@@ -512,179 +637,45 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
/* other.sourceip is managed in stroke_attributes. If it is set, we define
* the pool name as the connection name, which the attribute provider
* uses to serve pool addresses. */
- return peer_cfg_create(msg->add_conn.name,
- msg->add_conn.ikev2 ? 2 : 1, ike_cfg, me, other,
+ peer_cfg = peer_cfg_create(msg->add_conn.name,
+ msg->add_conn.ikev2 ? 2 : 1, ike_cfg,
msg->add_conn.me.sendcert, unique,
msg->add_conn.rekey.tries, rekey, reauth, jitter, over,
msg->add_conn.mobike, msg->add_conn.dpd.delay,
vip, msg->add_conn.other.sourceip_size ?
msg->add_conn.name : msg->add_conn.other.sourceip,
msg->add_conn.ikeme.mediation, mediated_by, peer_id);
-}
-
-/**
- * fill in auth_info from stroke message
- */
-static void build_auth_info(private_stroke_config_t *this,
- stroke_msg_t *msg, auth_info_t *auth,
- identification_t *my_ca,
- identification_t *other_ca)
-{
- identification_t *id;
- bool my_ca_same = FALSE;
- bool other_ca_same = FALSE;
- cert_validation_t valid;
-
- switch (msg->add_conn.crl_policy)
- {
- case CRL_STRICT_YES:
- valid = VALIDATION_GOOD;
- auth->add_item(auth, AUTHZ_CRL_VALIDATION, &valid);
- break;
- case CRL_STRICT_IFURI:
- valid = VALIDATION_SKIPPED;
- auth->add_item(auth, AUTHZ_CRL_VALIDATION, &valid);
- break;
- default:
- break;
- }
- if (msg->add_conn.me.ca)
+ /* build leftauth= */
+ auth_cfg = build_auth_cfg(this, msg, TRUE, TRUE);
+ if (auth_cfg)
{
- if (my_ca)
- {
- my_ca->destroy(my_ca);
- my_ca = NULL;
- }
- if (streq(msg->add_conn.me.ca, "%same"))
- {
- my_ca_same = TRUE;
- }
- else
- {
- my_ca = identification_create_from_string(msg->add_conn.me.ca);
- }
+ peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, TRUE);
}
-
- if (msg->add_conn.other.ca)
- {
- if (other_ca)
- {
- other_ca->destroy(other_ca);
- other_ca = NULL;
- }
- if (streq(msg->add_conn.other.ca, "%same"))
- {
- other_ca_same = TRUE;
- }
- else
- {
- other_ca = identification_create_from_string(msg->add_conn.other.ca);
- }
- }
-
- if (other_ca_same && my_ca)
- {
- other_ca = my_ca->clone(my_ca);
- }
- else if (my_ca_same && other_ca)
- {
- my_ca = other_ca->clone(other_ca);
- }
-
- if (other_ca)
- {
- DBG2(DBG_CFG, " other ca: %D", other_ca);
- certificate_t *cert = charon->credentials->get_cert(charon->credentials,
- CERT_X509, KEY_ANY, other_ca, TRUE);
- if (cert)
- {
- auth->add_item(auth, AUTHZ_CA_CERT, cert);
- cert->destroy(cert);
- }
- else
- {
- auth->add_item(auth, AUTHZ_CA_CERT_NAME, other_ca);
- }
- other_ca->destroy(other_ca);
+ else
+ { /* we require at least one config on our side */
+ peer_cfg->destroy(peer_cfg);
+ return NULL;
}
-
- if (my_ca)
+ /* build leftauth2= */
+ auth_cfg = build_auth_cfg(this, msg, TRUE, FALSE);
+ if (auth_cfg)
{
- DBG2(DBG_CFG, " my ca: %D", my_ca);
- certificate_t *cert = charon->credentials->get_cert(charon->credentials,
- CERT_X509, KEY_ANY, my_ca, TRUE);
- if (cert)
- {
- auth->add_item(auth, AUTHN_CA_CERT, cert);
- cert->destroy(cert);
- }
- else
- {
- auth->add_item(auth, AUTHN_CA_CERT_NAME, my_ca);
- }
- my_ca->destroy(my_ca);
+ peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, TRUE);
}
- auth->add_item(auth, AUTHN_AUTH_CLASS, &msg->add_conn.auth_method);
- if (msg->add_conn.eap_type)
+ /* build rightauth= */
+ auth_cfg = build_auth_cfg(this, msg, FALSE, TRUE);
+ if (auth_cfg)
{
- auth->add_item(auth, AUTHN_EAP_TYPE, &msg->add_conn.eap_type);
- if (msg->add_conn.eap_vendor)
- {
- auth->add_item(auth, AUTHN_EAP_VENDOR, &msg->add_conn.eap_vendor);
- }
+ peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, FALSE);
}
-
- if (msg->add_conn.eap_identity)
+ /* build rightauth2= */
+ auth_cfg = build_auth_cfg(this, msg, FALSE, FALSE);
+ if (auth_cfg)
{
- if (streq(msg->add_conn.eap_identity, "%identity"))
- {
- id = identification_create_from_encoding(ID_ANY, chunk_empty);
- }
- else
- {
- id = identification_create_from_encoding(ID_EAP, chunk_create(
- msg->add_conn.eap_identity,
- strlen(msg->add_conn.eap_identity)));
- }
- auth->add_item(auth, AUTHN_EAP_IDENTITY, id);
- id->destroy(id);
- }
-
- if (msg->add_conn.other.groups)
- {
- chunk_t line = { msg->add_conn.other.groups,
- strlen(msg->add_conn.other.groups) };
-
- while (eat_whitespace(&line))
- {
- chunk_t group;
-
- /* extract the next comma-separated group attribute */
- if (!extract_token(&group, ',', &line))
- {
- group = line;
- line.len = 0;
- }
-
- /* remove any trailing spaces */
- while (group.len > 0 && *(group.ptr + group.len - 1) == ' ')
- {
- group.len--;
- }
-
- /* add the group attribute to the list */
- if (group.len > 0)
- {
- identification_t *ac_group;
-
- ac_group = identification_create_from_encoding(
- ID_IETF_ATTR_STRING, group);
- auth->add_item(auth, AUTHZ_AC_GROUP, ac_group);
- ac_group->destroy(ac_group);
- }
- }
+ peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, FALSE);
}
+ return peer_cfg;
}
/**
@@ -799,7 +790,6 @@ static void add(private_stroke_config_t *this, stroke_msg_t *msg)
ike_cfg_t *ike_cfg, *existing_ike;
peer_cfg_t *peer_cfg, *existing;
child_cfg_t *child_cfg;
- identification_t *my_issuer = NULL, *other_issuer = NULL;
enumerator_t *enumerator;
bool use_existing = FALSE;
@@ -808,15 +798,13 @@ static void add(private_stroke_config_t *this, stroke_msg_t *msg)
{
return;
}
- peer_cfg = build_peer_cfg(this, msg, ike_cfg, &my_issuer, &other_issuer);
+ peer_cfg = build_peer_cfg(this, msg, ike_cfg);
if (!peer_cfg)
{
ike_cfg->destroy(ike_cfg);
return;
}
- build_auth_info(this, msg, peer_cfg->get_auth(peer_cfg),
- my_issuer, other_issuer);
enumerator = create_peer_cfg_enumerator(this, NULL, NULL);
while (enumerator->enumerate(enumerator, &existing))
{
@@ -850,9 +838,7 @@ static void add(private_stroke_config_t *this, stroke_msg_t *msg)
else
{
/* add config to backend */
- DBG1(DBG_CFG, "added configuration '%s': %s[%D]...%s[%D]", msg->add_conn.name,
- ike_cfg->get_my_addr(ike_cfg), peer_cfg->get_my_id(peer_cfg),
- ike_cfg->get_other_addr(ike_cfg), peer_cfg->get_other_id(peer_cfg));
+ DBG1(DBG_CFG, "added configuration '%s'", msg->add_conn.name);
this->mutex->lock(this->mutex);
this->list->insert_last(this->list, peer_cfg);
this->mutex->unlock(this->mutex);
@@ -867,34 +853,50 @@ static void del(private_stroke_config_t *this, stroke_msg_t *msg)
enumerator_t *enumerator, *children;
peer_cfg_t *peer;
child_cfg_t *child;
+ bool deleted = FALSE;
this->mutex->lock(this->mutex);
enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, (void**)&peer))
{
- /* remove peer config with such a name */
- if (streq(peer->get_name(peer), msg->del_conn.name))
- {
- this->list->remove_at(this->list, enumerator);
- peer->destroy(peer);
- continue;
- }
+ bool keep = FALSE;
+
/* remove any child with such a name */
children = peer->create_child_cfg_enumerator(peer);
while (children->enumerate(children, &child))
{
if (streq(child->get_name(child), msg->del_conn.name))
{
- peer->remove_child_cfg(peer, enumerator);
+ peer->remove_child_cfg(peer, children);
child->destroy(child);
+ deleted = TRUE;
+ }
+ else
+ {
+ keep = TRUE;
}
}
children->destroy(children);
+
+ /* if peer config matches, or has no children anymore, remove it */
+ if (!keep || streq(peer->get_name(peer), msg->del_conn.name))
+ {
+ this->list->remove_at(this->list, enumerator);
+ peer->destroy(peer);
+ deleted = TRUE;
+ }
}
enumerator->destroy(enumerator);
this->mutex->unlock(this->mutex);
- DBG1(DBG_CFG, "deleted connection '%s'", msg->del_conn.name);
+ if (deleted)
+ {
+ DBG1(DBG_CFG, "deleted connection '%s'", msg->del_conn.name);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "connection '%s' not found", msg->del_conn.name);
+ }
}
/**
diff --git a/src/charon/plugins/stroke/stroke_config.h b/src/charon/plugins/stroke/stroke_config.h
index 12eb11a8f..270795e4a 100644
--- a/src/charon/plugins/stroke/stroke_config.h
+++ b/src/charon/plugins/stroke/stroke_config.h
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/stroke/stroke_control.c b/src/charon/plugins/stroke/stroke_control.c
index 08d50519c..c572117a2 100644
--- a/src/charon/plugins/stroke/stroke_control.c
+++ b/src/charon/plugins/stroke/stroke_control.c
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id$
*/
#include "stroke_control.h"
@@ -145,11 +143,13 @@ static void terminate(private_stroke_control_t *this, stroke_msg_t *msg, FILE *o
{
char *string, *pos = NULL, *name = NULL;
u_int32_t id = 0;
- bool child;
+ bool child, all = FALSE;
int len;
ike_sa_t *ike_sa;
enumerator_t *enumerator;
+ linked_list_t *ike_list, *child_list;
stroke_log_info_t info;
+ uintptr_t del;
string = msg->terminate.name;
@@ -185,19 +185,44 @@ static void terminate(private_stroke_control_t *this, stroke_msg_t *msg, FILE *o
name = string;
}
else
- { /* is name[123] or name{23} */
- string[len-1] = '\0';
- id = atoi(pos + 1);
- if (id == 0)
- {
- DBG1(DBG_CFG, "error parsing string");
- return;
+ {
+ if (*(pos + 1) == '*')
+ { /* is name[*] */
+ all = TRUE;
+ *pos = '\0';
+ name = string;
+ }
+ else
+ { /* is name[123] or name{23} */
+ id = atoi(pos + 1);
+ if (id == 0)
+ {
+ DBG1(DBG_CFG, "error parsing string");
+ return;
+ }
}
}
info.out = out;
info.level = msg->output_verbosity;
+ if (id)
+ {
+ if (child)
+ {
+ charon->controller->terminate_child(charon->controller, id,
+ (controller_cb_t)stroke_log, &info);
+ }
+ else
+ {
+ charon->controller->terminate_ike(charon->controller, id,
+ (controller_cb_t)stroke_log, &info);
+ }
+ return;
+ }
+
+ ike_list = linked_list_create();
+ child_list = linked_list_create();
enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
while (enumerator->enumerate(enumerator, &ike_sa))
{
@@ -209,35 +234,58 @@ static void terminate(private_stroke_control_t *this, stroke_msg_t *msg, FILE *o
children = ike_sa->create_child_sa_iterator(ike_sa);
while (children->iterate(children, (void**)&child_sa))
{
- if ((name && streq(name, child_sa->get_name(child_sa))) ||
- (id && id == child_sa->get_reqid(child_sa)))
+ if (streq(name, child_sa->get_name(child_sa)))
{
- id = child_sa->get_reqid(child_sa);
- children->destroy(children);
- enumerator->destroy(enumerator);
-
- charon->controller->terminate_child(charon->controller, id,
- (controller_cb_t)stroke_log, &info);
- return;
+ child_list->insert_last(child_list,
+ (void*)(uintptr_t)child_sa->get_reqid(child_sa));
+ if (!all)
+ {
+ break;
+ }
}
}
children->destroy(children);
+ if (child_list->get_count(child_list) && !all)
+ {
+ break;
+ }
}
- else if ((name && streq(name, ike_sa->get_name(ike_sa))) ||
- (id && id == ike_sa->get_unique_id(ike_sa)))
+ else if (streq(name, ike_sa->get_name(ike_sa)))
{
- id = ike_sa->get_unique_id(ike_sa);
- /* unlock manager first */
- enumerator->destroy(enumerator);
-
- charon->controller->terminate_ike(charon->controller, id,
- (controller_cb_t)stroke_log, &info);
- return;
+ ike_list->insert_last(ike_list,
+ (void*)(uintptr_t)ike_sa->get_unique_id(ike_sa));
+ if (!all)
+ {
+ break;
+ }
}
-
}
enumerator->destroy(enumerator);
- DBG1(DBG_CFG, "no such SA found");
+
+ enumerator = child_list->create_enumerator(child_list);
+ while (enumerator->enumerate(enumerator, &del))
+ {
+ charon->controller->terminate_child(charon->controller, del,
+ (controller_cb_t)stroke_log, &info);
+ }
+ enumerator->destroy(enumerator);
+
+ enumerator = ike_list->create_enumerator(ike_list);
+ while (enumerator->enumerate(enumerator, &del))
+ {
+ charon->controller->terminate_ike(charon->controller, del,
+ (controller_cb_t)stroke_log, &info);
+ }
+ enumerator->destroy(enumerator);
+
+ if (child_list->get_count(child_list) == 0 &&
+ ike_list->get_count(ike_list) == 0)
+ {
+ DBG1(DBG_CFG, "no %s_SA named '%s' found",
+ child ? "CHILD" : "IKE", name);
+ }
+ ike_list->destroy(ike_list);
+ child_list->destroy(child_list);
}
/**
@@ -249,7 +297,7 @@ static void terminate_srcip(private_stroke_control_t *this,
enumerator_t *enumerator;
ike_sa_t *ike_sa;
host_t *start = NULL, *end = NULL, *vip;
- chunk_t chunk_start, chunk_end, chunk_vip;
+ chunk_t chunk_start, chunk_end = chunk_empty, chunk_vip;
if (msg->terminate_srcip.start)
{
@@ -310,13 +358,52 @@ static void terminate_srcip(private_stroke_control_t *this,
}
/**
+ * Implementation of stroke_control_t.purge_ike
+ */
+static void purge_ike(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
+{
+ enumerator_t *enumerator;
+ iterator_t *iterator;
+ ike_sa_t *ike_sa;
+ child_sa_t *child_sa;
+ linked_list_t *list;
+ uintptr_t del;
+ stroke_log_info_t info;
+
+ info.out = out;
+ info.level = msg->output_verbosity;
+
+ list = linked_list_create();
+ enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ while (enumerator->enumerate(enumerator, &ike_sa))
+ {
+ iterator = ike_sa->create_child_sa_iterator(ike_sa);
+ if (!iterator->iterate(iterator, (void**)&child_sa))
+ {
+ list->insert_last(list,
+ (void*)(uintptr_t)ike_sa->get_unique_id(ike_sa));
+ }
+ iterator->destroy(iterator);
+ }
+ enumerator->destroy(enumerator);
+
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &del))
+ {
+ charon->controller->terminate_ike(charon->controller, del,
+ (controller_cb_t)stroke_log, &info);
+ }
+ enumerator->destroy(enumerator);
+ list->destroy(list);
+}
+
+/**
* Implementation of stroke_control_t.route.
*/
static void route(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
{
peer_cfg_t *peer_cfg;
child_cfg_t *child_cfg;
- stroke_log_info_t info;
peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
msg->route.name);
@@ -339,10 +426,14 @@ static void route(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
return;
}
- info.out = out;
- info.level = msg->output_verbosity;
- charon->controller->route(charon->controller, peer_cfg, child_cfg,
- (controller_cb_t)stroke_log, &info);
+ if (charon->traps->install(charon->traps, peer_cfg, child_cfg))
+ {
+ fprintf(out, "configuration '%s' routed\n", msg->route.name);
+ }
+ else
+ {
+ fprintf(out, "routing configuration '%s' failed\n", msg->route.name);
+ }
peer_cfg->destroy(peer_cfg);
child_cfg->destroy(child_cfg);
}
@@ -352,41 +443,24 @@ static void route(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
*/
static void unroute(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
{
- char *name;
- ike_sa_t *ike_sa;
+ child_sa_t *child_sa;
enumerator_t *enumerator;
- stroke_log_info_t info;
+ u_int32_t id;
- name = msg->terminate.name;
-
- info.out = out;
- info.level = msg->output_verbosity;
-
- enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
- while (enumerator->enumerate(enumerator, &ike_sa))
+ enumerator = charon->traps->create_enumerator(charon->traps);
+ while (enumerator->enumerate(enumerator, NULL, &child_sa))
{
- child_sa_t *child_sa;
- iterator_t *children;
- u_int32_t id;
-
- children = ike_sa->create_child_sa_iterator(ike_sa);
- while (children->iterate(children, (void**)&child_sa))
+ if (streq(msg->unroute.name, child_sa->get_name(child_sa)))
{
- if (child_sa->get_state(child_sa) == CHILD_ROUTED &&
- streq(name, child_sa->get_name(child_sa)))
- {
- id = child_sa->get_reqid(child_sa);
- children->destroy(children);
- enumerator->destroy(enumerator);
- charon->controller->unroute(charon->controller, id,
- (controller_cb_t)stroke_log, &info);
- return;
- }
+ id = child_sa->get_reqid(child_sa);
+ enumerator->destroy(enumerator);
+ charon->traps->uninstall(charon->traps, id);
+ fprintf(out, "configuration '%s' unrouted\n", msg->unroute.name);
+ return;
}
- children->destroy(children);
}
enumerator->destroy(enumerator);
- DBG1(DBG_CFG, "no such SA found");
+ fprintf(out, "configuration '%s' not found\n", msg->unroute.name);
}
/**
@@ -407,6 +481,7 @@ stroke_control_t *stroke_control_create()
this->public.initiate = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))initiate;
this->public.terminate = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))terminate;
this->public.terminate_srcip = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))terminate_srcip;
+ this->public.purge_ike = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))purge_ike;
this->public.route = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))route;
this->public.unroute = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))unroute;
this->public.destroy = (void(*)(stroke_control_t*))destroy;
diff --git a/src/charon/plugins/stroke/stroke_control.h b/src/charon/plugins/stroke/stroke_control.h
index 26dc99b94..5a61a90a4 100644
--- a/src/charon/plugins/stroke/stroke_control.h
+++ b/src/charon/plugins/stroke/stroke_control.h
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id$
*/
/**
@@ -56,6 +54,13 @@ struct stroke_control_t {
void (*terminate_srcip)(stroke_control_t *this, stroke_msg_t *msg, FILE *out);
/**
+ * Delete IKE_SAs without a CHILD_SA.
+ *
+ * @param msg stroke message
+ */
+ void (*purge_ike)(stroke_control_t *this, stroke_msg_t *msg, FILE *out);
+
+ /**
* Route a connection.
*
* @param msg stroke message
@@ -70,9 +75,9 @@ struct stroke_control_t {
void (*unroute)(stroke_control_t *this, stroke_msg_t *msg, FILE *out);
/**
- * Destroy a stroke_control instance.
- */
- void (*destroy)(stroke_control_t *this);
+ * Destroy a stroke_control instance.
+ */
+ void (*destroy)(stroke_control_t *this);
};
/**
diff --git a/src/charon/plugins/stroke/stroke_cred.c b/src/charon/plugins/stroke/stroke_cred.c
index 434aec22b..dc73299b8 100644
--- a/src/charon/plugins/stroke/stroke_cred.c
+++ b/src/charon/plugins/stroke/stroke_cred.c
@@ -12,8 +12,6 @@
* 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.
- *
- * $Id$
*/
#include <sys/stat.h>
@@ -382,10 +380,18 @@ static certificate_t* load_ca(private_stroke_cred_t *this, char *filename)
cert = lib->creds->create(lib->creds,
CRED_CERTIFICATE, CERT_X509,
BUILD_FROM_FILE, path,
- BUILD_X509_FLAG, X509_CA,
BUILD_END);
if (cert)
{
+ x509_t *x509 = (x509_t*)cert;
+
+ if (!(x509->get_flags(x509) & X509_CA))
+ {
+ cert->destroy(cert);
+ DBG1(DBG_CFG, " ca certificate must have ca basic constraint set, "
+ "discarded");
+ return NULL;
+ }
return (certificate_t*)add_cert(this, cert);
}
return NULL;
@@ -524,11 +530,32 @@ static void load_certdir(private_stroke_cred_t *this, char *path,
switch (type)
{
case CERT_X509:
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_FROM_FILE, file,
- BUILD_X509_FLAG, flag,
- BUILD_END);
+ if (flag & X509_CA)
+ { /* for CA certificates, we strictly require CA
+ * basicconstraints to be set */
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, file, BUILD_END);
+ if (cert)
+ {
+ x509_t *x509 = (x509_t*)cert;
+
+ if (!(x509->get_flags(x509) & X509_CA))
+ {
+ DBG1(DBG_CFG, " ca certificate must have ca "
+ "basic constraint set, discarded");
+ cert->destroy(cert);
+ cert = NULL;
+ }
+ }
+ }
+ else
+ { /* for all other flags, we add them to the certificate. */
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, file,
+ BUILD_X509_FLAG, flag, BUILD_END);
+ }
if (cert)
{
add_cert(this, cert);
@@ -568,13 +595,13 @@ static void cache_cert(private_stroke_cred_t *this, certificate_t *cert)
{
if (cert->get_type(cert) == CERT_X509_CRL && this->cachecrl)
{
- /* CRLs get written to /etc/ipsec.d/crls/authkeyId.crl */
+ /* CRLs get written to /etc/ipsec.d/crls/<authkeyId>.crl */
crl_t *crl = (crl_t*)cert;
cert->get_ref(cert);
if (add_crl(this, crl))
{
- char buf[256];
+ char buf[BUF_LEN];
chunk_t chunk, hex;
identification_t *id;
@@ -585,14 +612,7 @@ static void cache_cert(private_stroke_cred_t *this, certificate_t *cert)
free(hex.ptr);
chunk = cert->get_encoding(cert);
- if (chunk_write(chunk, buf, 022, TRUE))
- {
- DBG1(DBG_CFG, " written crl to '%s'", buf);
- }
- else
- {
- DBG1(DBG_CFG, " writing crl to '%s' failed", buf);
- }
+ chunk_write(chunk, buf, "crl", 022, TRUE);
free(chunk.ptr);
}
}
@@ -905,26 +925,13 @@ static void load_secrets(private_stroke_cred_t *this)
continue;
}
- if (type == SHARED_EAP)
+ /* NULL terminate the ID string */
+ *(id.ptr + id.len) = '\0';
+ peer_id = identification_create_from_string(id.ptr);
+ if (peer_id->get_type(peer_id) == ID_ANY)
{
- /* we use a special EAP identity type for EAP secrets */
- peer_id = identification_create_from_encoding(ID_EAP, id);
- }
- else
- {
- /* NULL terminate the ID string */
- *(id.ptr + id.len) = '\0';
- peer_id = identification_create_from_string(id.ptr);
- if (peer_id == NULL)
- {
- DBG1(DBG_CFG, "line %d: malformed ID: %s", line_nr, id.ptr);
- goto error;
- }
- if (peer_id->get_type(peer_id) == ID_ANY)
- {
- peer_id->destroy(peer_id);
- continue;
- }
+ peer_id->destroy(peer_id);
+ continue;
}
shared_key->add_owner(shared_key, peer_id);
diff --git a/src/charon/plugins/stroke/stroke_cred.h b/src/charon/plugins/stroke/stroke_cred.h
index fc7121622..8bc042f13 100644
--- a/src/charon/plugins/stroke/stroke_cred.h
+++ b/src/charon/plugins/stroke/stroke_cred.h
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/stroke/stroke_list.c b/src/charon/plugins/stroke/stroke_list.c
index 94b3def3a..564a511a1 100644
--- a/src/charon/plugins/stroke/stroke_list.c
+++ b/src/charon/plugins/stroke/stroke_list.c
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id$
*/
#include "stroke_list.h"
@@ -55,23 +53,6 @@ struct private_stroke_list_t {
};
/**
- * get the authentication class of a config
- */
-auth_class_t get_auth_class(peer_cfg_t *config)
-{
- auth_class_t *class;
- auth_info_t *auth_info;
-
- auth_info = config->get_auth(config);
- if (auth_info->get_item(auth_info, AUTHN_AUTH_CLASS, (void**)&class))
- {
- return *class;
- }
- /* fallback to pubkey authentication */
- return AUTH_CLASS_PUBKEY;
-}
-
-/**
* log an IKE_SA to out
*/
static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
@@ -91,7 +72,7 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
fprintf(out, " %V ago", &now, &established);
}
- fprintf(out, ", %H[%D]...%H[%D]\n",
+ fprintf(out, ", %H[%Y]...%H[%Y]\n",
ike_sa->get_my_host(ike_sa), ike_sa->get_my_id(ike_sa),
ike_sa->get_other_host(ike_sa), ike_sa->get_other_id(ike_sa));
@@ -110,9 +91,11 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED)
{
time_t rekey, reauth;
+ peer_cfg_t *peer_cfg;
rekey = ike_sa->get_statistic(ike_sa, STAT_REKEY);
reauth = ike_sa->get_statistic(ike_sa, STAT_REAUTH);
+ peer_cfg = ike_sa->get_peer_cfg(ike_sa);
if (rekey)
{
@@ -120,9 +103,24 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
}
if (reauth)
{
- fprintf(out, ", %N reauthentication in %V", auth_class_names,
- get_auth_class(ike_sa->get_peer_cfg(ike_sa)),
- &reauth, &now);
+ bool first = TRUE;
+ enumerator_t *enumerator;
+ auth_cfg_t *auth;
+
+ fprintf(out, ", ");
+ enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, TRUE);
+ while (enumerator->enumerate(enumerator, &auth))
+ {
+ if (!first)
+ {
+ fprintf(out, "+");
+ }
+ first = FALSE;
+ fprintf(out, "%N", auth_class_names,
+ auth->get(auth, AUTH_RULE_AUTH_CLASS));
+ }
+ enumerator->destroy(enumerator);
+ fprintf(out, " reauthentication in %V", &reauth, &now);
}
if (!rekey && !reauth)
{
@@ -195,7 +193,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
fprintf(out, "%N", encryption_algorithm_names, encr_alg);
if (encr_size)
{
- fprintf(out, "-%d", encr_size);
+ fprintf(out, "_%u", encr_size);
}
}
if (int_alg != AUTH_UNDEFINED)
@@ -203,7 +201,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
fprintf(out, "/%N", integrity_algorithm_names, int_alg);
if (int_size)
{
- fprintf(out, "-%d", int_size);
+ fprintf(out, "_%u", int_size);
}
}
}
@@ -212,7 +210,14 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
rekey = child_sa->get_lifetime(child_sa, FALSE);
if (rekey)
{
- fprintf(out, "in %V", &now, &rekey);
+ if (now > rekey)
+ {
+ fprintf(out, "active");
+ }
+ else
+ {
+ fprintf(out, "in %V", &now, &rekey);
+ }
}
else
{
@@ -248,6 +253,107 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
}
/**
+ * Log a configs local or remote authentication config to out
+ */
+static void log_auth_cfgs(FILE *out, peer_cfg_t *peer_cfg, bool local)
+{
+ enumerator_t *enumerator, *rules;
+ auth_rule_t rule;
+ auth_cfg_t *auth;
+ auth_class_t auth_class;
+ identification_t *id;
+ certificate_t *cert;
+ cert_validation_t valid;
+ char *name;
+
+ name = peer_cfg->get_name(peer_cfg);
+
+ enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local);
+ while (enumerator->enumerate(enumerator, &auth))
+ {
+ fprintf(out, "%12s: %s [%Y] uses ", name, local ? "local: " : "remote:",
+ auth->get(auth, AUTH_RULE_IDENTITY));
+
+ auth_class = (uintptr_t)auth->get(auth, AUTH_RULE_AUTH_CLASS);
+ if (auth_class != AUTH_CLASS_EAP)
+ {
+ fprintf(out, "%N authentication\n", auth_class_names, auth_class);
+ }
+ else
+ {
+ if ((uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE) == EAP_NAK)
+ {
+ fprintf(out, "EAP authentication");
+ }
+ else
+ {
+ if ((uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR))
+ {
+ fprintf(out, "EAP_%d-%d authentication",
+ (uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE),
+ (uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR));
+ }
+ else
+ {
+ fprintf(out, "%N authentication", eap_type_names,
+ (uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE));
+ }
+ }
+ id = auth->get(auth, AUTH_RULE_EAP_IDENTITY);
+ if (id)
+ {
+ fprintf(out, " with EAP identity '%Y'", id);
+ }
+ fprintf(out, "\n");
+ }
+
+ cert = auth->get(auth, AUTH_RULE_CA_CERT);
+ if (cert)
+ {
+ fprintf(out, "%12s: ca: \"%Y\"\n", name, cert->get_subject(cert));
+ }
+
+ cert = auth->get(auth, AUTH_RULE_IM_CERT);
+ if (cert)
+ {
+ fprintf(out, "%12s: im-ca: \"%Y\"\n", name, cert->get_subject(cert));
+ }
+
+ cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+ if (cert)
+ {
+ fprintf(out, "%12s: cert: \"%Y\"\n", name,
+ cert->get_subject(cert));
+ }
+
+ valid = (uintptr_t)auth->get(auth, AUTH_RULE_OCSP_VALIDATION);
+ if (valid != VALIDATION_FAILED)
+ {
+ fprintf(out, "%12s: ocsp: status must be GOOD%s\n", name,
+ (valid == VALIDATION_SKIPPED) ? " or SKIPPED" : "");
+ }
+
+ valid = (uintptr_t)auth->get(auth, AUTH_RULE_CRL_VALIDATION);
+ if (valid != VALIDATION_FAILED)
+ {
+ fprintf(out, "%12s: crl: status must be GOOD%s\n", name,
+ (valid == VALIDATION_SKIPPED) ? " or SKIPPED" : "");
+ }
+
+ rules = auth->create_enumerator(auth);
+ while (rules->enumerate(rules, &rule, &id))
+ {
+ if (rule == AUTH_RULE_AC_GROUP)
+ {
+ fprintf(out, "%12s: group: %Y\n", name, id);
+ }
+ }
+ rules->destroy(rules);
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
* Implementation of stroke_list_t.status.
*/
static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bool all)
@@ -255,8 +361,9 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
enumerator_t *enumerator, *children;
ike_cfg_t *ike_cfg;
child_cfg_t *child_cfg;
+ child_sa_t *child_sa;
ike_sa_t *ike_sa;
- bool found = FALSE;
+ bool first, found = FALSE;
char *name = msg->status.name;
if (all)
@@ -266,10 +373,9 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
host_t *host;
u_int32_t dpd;
time_t now = time(NULL);
- bool first = TRUE;
u_int size, online, offline;
- fprintf(out, "Performance:\n");
+ fprintf(out, "Status of IKEv2 charon daemon (strongSwan "VERSION"):\n");
fprintf(out, " uptime: %V, since %T\n", &now, &this->uptime, &this->uptime, FALSE);
fprintf(out, " worker threads: %d idle of %d,",
charon->processor->get_idle_threads(charon->processor),
@@ -287,6 +393,7 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
enumerator->destroy(enumerator);
fprintf(out, "\n");
+ first = TRUE;
enumerator = this->attribute->create_pool_enumerator(this->attribute);
while (enumerator->enumerate(enumerator, &pool, &size, &online, &offline))
{
@@ -299,7 +406,7 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
first = FALSE;
fprintf(out, "Virtual IP pools (size/online/offline):\n");
}
- fprintf(out, " %s: %lu/%lu/%lu\n", pool, size, online, offline);
+ fprintf(out, " %s: %u/%u/%u\n", pool, size, online, offline);
}
enumerator->destroy(enumerator);
@@ -313,138 +420,42 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
enumerator->destroy(enumerator);
fprintf(out, "Connections:\n");
- enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends);
- while (enumerator->enumerate(enumerator, (void**)&peer_cfg))
+ enumerator = charon->backends->create_peer_cfg_enumerator(
+ charon->backends, NULL, NULL, NULL, NULL);
+ while (enumerator->enumerate(enumerator, &peer_cfg))
{
- void *ptr;
- certificate_t *cert;
- auth_item_t item;
- auth_info_t *auth;
- enumerator_t *auth_enumerator;
- identification_t *my_ca = NULL, *other_ca = NULL;
- identification_t *eap_identity = NULL;
- u_int32_t *eap_type = NULL;
- bool ac_groups = FALSE;
-
if (peer_cfg->get_ike_version(peer_cfg) != 2 ||
(name && !streq(name, peer_cfg->get_name(peer_cfg))))
{
continue;
}
- /* determine any required CAs, EAP type, EAP identity,
- * and the presence of AC groups
- */
- auth = peer_cfg->get_auth(peer_cfg);
- auth_enumerator = auth->create_item_enumerator(auth);
- while (auth_enumerator->enumerate(auth_enumerator, &item, &ptr))
- {
- switch (item)
- {
- case AUTHN_EAP_TYPE:
- eap_type = (u_int32_t *)ptr;
- break;
- case AUTHN_EAP_IDENTITY:
- eap_identity = (identification_t *)ptr;
- break;
- case AUTHN_CA_CERT:
- cert = (certificate_t *)ptr;
- my_ca = cert->get_subject(cert);
- break;
- case AUTHN_CA_CERT_NAME:
- my_ca = (identification_t *)ptr;
- break;
- case AUTHZ_CA_CERT:
- cert = (certificate_t *)ptr;
- other_ca = cert->get_subject(cert);
- break;
- case AUTHZ_CA_CERT_NAME:
- other_ca = (identification_t *)ptr;
- break;
- case AUTHZ_AC_GROUP:
- ac_groups = TRUE;
- break;
- default:
- break;
- }
- }
- auth_enumerator->destroy(auth_enumerator);
-
ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
- fprintf(out, "%12s: %s[%D]...%s[%D]\n", peer_cfg->get_name(peer_cfg),
- ike_cfg->get_my_addr(ike_cfg), peer_cfg->get_my_id(peer_cfg),
- ike_cfg->get_other_addr(ike_cfg), peer_cfg->get_other_id(peer_cfg));
- if (my_ca || other_ca)
- {
- fprintf(out, "%12s: CAs: ", peer_cfg->get_name(peer_cfg));
- if (my_ca)
- {
- fprintf(out, "\"%D\"...", my_ca);
- }
- else
- {
- fprintf(out, "%%any...");
- }
- if (other_ca)
- {
- fprintf(out, "\"%D\"\n", other_ca);
- }
- else
- {
- fprintf(out, "%%any\n");
- }
- }
-
- if (ac_groups)
- {
- bool first = TRUE;
-
- fprintf(out, "%12s: groups: ", peer_cfg->get_name(peer_cfg));
- auth_enumerator = auth->create_item_enumerator(auth);
- while (auth_enumerator->enumerate(auth_enumerator, &item, &ptr))
- {
- if (item == AUTHZ_AC_GROUP)
- {
- identification_t *group = (identification_t *)ptr;
-
- fprintf(out, "%s%D", first? "":", ", group);
- first = FALSE;
- }
- }
- auth_enumerator->destroy(auth_enumerator);
- fprintf(out, "\n");
- }
-
- fprintf(out, "%12s: %N ", peer_cfg->get_name(peer_cfg),
- auth_class_names, get_auth_class(peer_cfg));
- if (eap_type)
- {
- fprintf(out, "and %N ", eap_type_names, *eap_type);
- }
- fprintf(out, "authentication");
- if (eap_identity)
- {
- fprintf(out, ", EAP identity: '%D'", eap_identity);
- }
+ fprintf(out, "%12s: %s...%s", peer_cfg->get_name(peer_cfg),
+ ike_cfg->get_my_addr(ike_cfg), ike_cfg->get_other_addr(ike_cfg));
+
dpd = peer_cfg->get_dpd(peer_cfg);
if (dpd)
{
fprintf(out, ", dpddelay=%us", dpd);
}
fprintf(out, "\n");
-
+
+ log_auth_cfgs(out, peer_cfg, TRUE);
+ log_auth_cfgs(out, peer_cfg, FALSE);
+
children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
while (children->enumerate(children, &child_cfg))
{
linked_list_t *my_ts, *other_ts;
-
+
my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL);
other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL);
- fprintf(out, "%12s: %#R=== %#R", child_cfg->get_name(child_cfg),
+ fprintf(out, "%12s: child: %#R=== %#R", child_cfg->get_name(child_cfg),
my_ts, other_ts);
my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
-
+
if (dpd)
{
fprintf(out, ", dpdaction=%N", action_names,
@@ -456,13 +467,25 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
}
enumerator->destroy(enumerator);
}
+
+ first = TRUE;
+ enumerator = charon->traps->create_enumerator(charon->traps);
+ while (enumerator->enumerate(enumerator, NULL, &child_sa))
+ {
+ if (first)
+ {
+ fprintf(out, "Routed Connections:\n");
+ first = FALSE;
+ }
+ log_child_sa(out, child_sa, all);
+ }
+ enumerator->destroy(enumerator);
fprintf(out, "Security Associations:\n");
enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
while (enumerator->enumerate(enumerator, &ike_sa))
{
bool ike_printed = FALSE;
- child_sa_t *child_sa;
iterator_t *children = ike_sa->create_child_sa_iterator(ike_sa);
if (name == NULL || streq(name, ike_sa->get_name(ike_sa)))
@@ -588,8 +611,8 @@ static void stroke_list_pubkeys(linked_list_t *list, bool utc, FILE *out)
key_type_names, public->get_type(public),
public->get_keysize(public) * 8,
private ? ", has private key" : "");
- fprintf(out, " keyid: %D\n", keyid);
- fprintf(out, " subjkey: %D\n", id);
+ fprintf(out, " keyid: %Y\n", keyid);
+ fprintf(out, " subjkey: %Y\n", id);
DESTROY_IF(private);
public->destroy(public);
}
@@ -645,7 +668,7 @@ static void stroke_list_certs(linked_list_t *list, char *label,
{
fprintf(out, ", ");
}
- fprintf(out, "%D", altName);
+ fprintf(out, "%Y", altName);
}
if (!first_altName)
{
@@ -653,8 +676,8 @@ static void stroke_list_certs(linked_list_t *list, char *label,
}
enumerator->destroy(enumerator);
- fprintf(out, " subject: \"%D\"\n", cert->get_subject(cert));
- fprintf(out, " issuer: \"%D\"\n", cert->get_issuer(cert));
+ fprintf(out, " subject: \"%Y\"\n", cert->get_subject(cert));
+ fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert));
fprintf(out, " serial: %#B\n", &serial);
/* list validity */
@@ -699,8 +722,8 @@ static void stroke_list_certs(linked_list_t *list, char *label,
key_type_names, public->get_type(public),
public->get_keysize(public) * 8,
private ? ", has private key" : "");
- fprintf(out, " keyid: %D\n", keyid);
- fprintf(out, " subjkey: %D\n", id);
+ fprintf(out, " keyid: %Y\n", keyid);
+ fprintf(out, " subjkey: %Y\n", id);
DESTROY_IF(private);
public->destroy(public);
}
@@ -708,7 +731,7 @@ static void stroke_list_certs(linked_list_t *list, char *label,
/* list optional authorityKeyIdentifier */
if (authkey)
{
- fprintf(out, " authkey: %D\n", authkey);
+ fprintf(out, " authkey: %Y\n", authkey);
}
}
}
@@ -744,17 +767,17 @@ static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out)
if (entityName)
{
- fprintf(out, " holder: \"%D\"\n", entityName);
+ fprintf(out, " holder: \"%Y\"\n", entityName);
}
if (holderIssuer)
{
- fprintf(out, " hissuer: \"%D\"\n", holderIssuer);
+ fprintf(out, " hissuer: \"%Y\"\n", holderIssuer);
}
if (holderSerial.ptr)
{
fprintf(out, " hserial: %#B\n", &holderSerial);
}
- fprintf(out, " issuer: \"%D\"\n", cert->get_issuer(cert));
+ fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert));
fprintf(out, " serial: %#B\n", &serial);
/* list validity */
@@ -778,7 +801,7 @@ static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out)
/* list optional authorityKeyIdentifier */
if (authkey)
{
- fprintf(out, " authkey: %D\n", authkey);
+ fprintf(out, " authkey: %Y\n", authkey);
}
}
enumerator->destroy(enumerator);
@@ -808,7 +831,7 @@ static void stroke_list_crls(linked_list_t *list, bool utc, FILE *out)
}
fprintf(out, "\n");
- fprintf(out, " issuer: \"%D\"\n", cert->get_issuer(cert));
+ fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert));
/* list optional crlNumber */
if (serial.ptr)
@@ -851,7 +874,7 @@ static void stroke_list_crls(linked_list_t *list, bool utc, FILE *out)
/* list optional authorityKeyIdentifier */
if (authkey)
{
- fprintf(out, " authkey: %D\n", authkey);
+ fprintf(out, " authkey: %Y\n", authkey);
}
}
enumerator->destroy(enumerator);
@@ -876,7 +899,7 @@ static void stroke_list_ocsp(linked_list_t* list, bool utc, FILE *out)
first = FALSE;
}
- fprintf(out, " signer: \"%D\"\n", cert->get_issuer(cert));
+ fprintf(out, " signer: \"%Y\"\n", cert->get_issuer(cert));
}
enumerator->destroy(enumerator);
}
@@ -1019,7 +1042,7 @@ static void pool_leases(private_stroke_list_t *this, FILE *out, char *pool,
{
if (!address || address->ip_equals(address, lease))
{
- fprintf(out, " %15H %s '%D'\n",
+ fprintf(out, " %15H %s '%Y'\n",
lease, on ? "online" : "offline", id);
found++;
}
diff --git a/src/charon/plugins/stroke/stroke_list.h b/src/charon/plugins/stroke/stroke_list.h
index 73a6ff6e4..2430abfbb 100644
--- a/src/charon/plugins/stroke/stroke_list.h
+++ b/src/charon/plugins/stroke/stroke_list.h
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/stroke/stroke_plugin.c b/src/charon/plugins/stroke/stroke_plugin.c
index 6933fc074..22c1125a1 100644
--- a/src/charon/plugins/stroke/stroke_plugin.c
+++ b/src/charon/plugins/stroke/stroke_plugin.c
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id$
*/
#include "stroke_plugin.h"
diff --git a/src/charon/plugins/stroke/stroke_plugin.h b/src/charon/plugins/stroke/stroke_plugin.h
index b4c367c6e..6e9d556ad 100644
--- a/src/charon/plugins/stroke/stroke_plugin.h
+++ b/src/charon/plugins/stroke/stroke_plugin.h
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id: stroke.h 3589 2008-03-13 14:14:44Z martin $
*/
/**
diff --git a/src/charon/plugins/stroke/stroke_shared_key.c b/src/charon/plugins/stroke/stroke_shared_key.c
index 9c21eb830..8f53f509d 100644
--- a/src/charon/plugins/stroke/stroke_shared_key.c
+++ b/src/charon/plugins/stroke/stroke_shared_key.c
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id$
*/
#include "stroke_shared_key.h"
diff --git a/src/charon/plugins/stroke/stroke_shared_key.h b/src/charon/plugins/stroke/stroke_shared_key.h
index b456095ae..224062100 100644
--- a/src/charon/plugins/stroke/stroke_shared_key.h
+++ b/src/charon/plugins/stroke/stroke_shared_key.h
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/stroke/stroke_socket.c b/src/charon/plugins/stroke/stroke_socket.c
index 53edde031..f61171e22 100644
--- a/src/charon/plugins/stroke/stroke_socket.c
+++ b/src/charon/plugins/stroke/stroke_socket.c
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id$
*/
#include "stroke_socket.h"
@@ -143,18 +141,28 @@ static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
pop_string(msg, &end->address);
pop_string(msg, &end->subnets);
pop_string(msg, &end->sourceip);
+ pop_string(msg, &end->auth);
+ pop_string(msg, &end->auth2);
pop_string(msg, &end->id);
+ pop_string(msg, &end->id2);
pop_string(msg, &end->cert);
+ pop_string(msg, &end->cert2);
pop_string(msg, &end->ca);
+ pop_string(msg, &end->ca2);
pop_string(msg, &end->groups);
pop_string(msg, &end->updown);
DBG2(DBG_CFG, " %s=%s", label, end->address);
DBG2(DBG_CFG, " %ssubnet=%s", label, end->subnets);
DBG2(DBG_CFG, " %ssourceip=%s", label, end->sourceip);
+ DBG2(DBG_CFG, " %sauth=%s", label, end->auth);
+ DBG2(DBG_CFG, " %sauth2=%s", label, end->auth2);
DBG2(DBG_CFG, " %sid=%s", label, end->id);
+ DBG2(DBG_CFG, " %sid2=%s", label, end->id2);
DBG2(DBG_CFG, " %scert=%s", label, end->cert);
+ DBG2(DBG_CFG, " %scert2=%s", label, end->cert2);
DBG2(DBG_CFG, " %sca=%s", label, end->ca);
+ DBG2(DBG_CFG, " %sca2=%s", label, end->ca2);
DBG2(DBG_CFG, " %sgroups=%s", label, end->groups);
DBG2(DBG_CFG, " %supdown=%s", label, end->updown);
}
@@ -333,8 +341,15 @@ static void stroke_reread(private_stroke_socket_t *this,
static void stroke_purge(private_stroke_socket_t *this,
stroke_msg_t *msg, FILE *out)
{
- charon->credentials->flush_cache(charon->credentials,
- CERT_X509_OCSP_RESPONSE);
+ if (msg->purge.flags & PURGE_OCSP)
+ {
+ charon->credentials->flush_cache(charon->credentials,
+ CERT_X509_OCSP_RESPONSE);
+ }
+ if (msg->purge.flags & PURGE_IKE)
+ {
+ this->control->purge_ike(this->control, msg, out);
+ }
}
/**
@@ -351,16 +366,16 @@ static void stroke_leases(private_stroke_socket_t *this,
debug_t get_group_from_name(char *type)
{
- if (strcasecmp(type, "any") == 0) return DBG_ANY;
- else if (strcasecmp(type, "mgr") == 0) return DBG_MGR;
- else if (strcasecmp(type, "ike") == 0) return DBG_IKE;
- else if (strcasecmp(type, "chd") == 0) return DBG_CHD;
- else if (strcasecmp(type, "job") == 0) return DBG_JOB;
- else if (strcasecmp(type, "cfg") == 0) return DBG_CFG;
- else if (strcasecmp(type, "knl") == 0) return DBG_KNL;
- else if (strcasecmp(type, "net") == 0) return DBG_NET;
- else if (strcasecmp(type, "enc") == 0) return DBG_ENC;
- else if (strcasecmp(type, "lib") == 0) return DBG_LIB;
+ if (strcaseeq(type, "any")) return DBG_ANY;
+ else if (strcaseeq(type, "mgr")) return DBG_MGR;
+ else if (strcaseeq(type, "ike")) return DBG_IKE;
+ else if (strcaseeq(type, "chd")) return DBG_CHD;
+ else if (strcaseeq(type, "job")) return DBG_JOB;
+ else if (strcaseeq(type, "cfg")) return DBG_CFG;
+ else if (strcaseeq(type, "knl")) return DBG_KNL;
+ else if (strcaseeq(type, "net")) return DBG_NET;
+ else if (strcaseeq(type, "enc")) return DBG_ENC;
+ else if (strcaseeq(type, "lib")) return DBG_LIB;
else return -1;
}
@@ -561,8 +576,11 @@ static job_requeue_t receive(private_stroke_socket_t *this)
*/
static bool open_socket(private_stroke_socket_t *this)
{
- struct sockaddr_un socket_addr = { AF_UNIX, STROKE_SOCKET};
+ struct sockaddr_un socket_addr;
mode_t old;
+
+ socket_addr.sun_family = AF_UNIX;
+ strcpy(socket_addr.sun_path, STROKE_SOCKET);
/* set up unix socket */
this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
diff --git a/src/charon/plugins/stroke/stroke_socket.h b/src/charon/plugins/stroke/stroke_socket.h
index 7a772c56c..6073f5133 100644
--- a/src/charon/plugins/stroke/stroke_socket.h
+++ b/src/charon/plugins/stroke/stroke_socket.h
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id$
*/
/**