diff options
Diffstat (limited to 'src/charon/plugins/stroke')
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, ¤t)) { - /* 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$ */ /** |