summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/stroke
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2013-02-07 13:27:27 +0100
committerYves-Alexis Perez <corsac@debian.org>2013-02-07 13:27:27 +0100
commit7585facf05d927eb6df3929ce09ed5e60d905437 (patch)
treee4d14b4dc180db20356b6b01ce0112f3a2d7897e /src/libcharon/plugins/stroke
parentc1343b3278cdf99533b7902744d15969f9d6fdc1 (diff)
downloadvyos-strongswan-7585facf05d927eb6df3929ce09ed5e60d905437.tar.gz
vyos-strongswan-7585facf05d927eb6df3929ce09ed5e60d905437.zip
Imported Upstream version 5.0.2
Diffstat (limited to 'src/libcharon/plugins/stroke')
-rw-r--r--src/libcharon/plugins/stroke/Makefile.am1
-rw-r--r--src/libcharon/plugins/stroke/Makefile.in37
-rw-r--r--src/libcharon/plugins/stroke/stroke_attribute.c2
-rw-r--r--src/libcharon/plugins/stroke/stroke_ca.c2
-rw-r--r--src/libcharon/plugins/stroke/stroke_config.c51
-rw-r--r--src/libcharon/plugins/stroke/stroke_counter.c254
-rw-r--r--src/libcharon/plugins/stroke/stroke_counter.h104
-rw-r--r--src/libcharon/plugins/stroke/stroke_cred.c241
-rw-r--r--src/libcharon/plugins/stroke/stroke_cred.h2
-rw-r--r--src/libcharon/plugins/stroke/stroke_handler.c2
-rw-r--r--src/libcharon/plugins/stroke/stroke_list.c2
-rw-r--r--src/libcharon/plugins/stroke/stroke_socket.c35
12 files changed, 582 insertions, 151 deletions
diff --git a/src/libcharon/plugins/stroke/Makefile.am b/src/libcharon/plugins/stroke/Makefile.am
index cebcd984f..39b3e79d2 100644
--- a/src/libcharon/plugins/stroke/Makefile.am
+++ b/src/libcharon/plugins/stroke/Makefile.am
@@ -22,6 +22,7 @@ libstrongswan_stroke_la_SOURCES = \
stroke_ca.h stroke_ca.c \
stroke_attribute.h stroke_attribute.c \
stroke_handler.h stroke_handler.c \
+ stroke_counter.h stroke_counter.c \
stroke_list.h stroke_list.c
libstrongswan_stroke_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/stroke/Makefile.in b/src/libcharon/plugins/stroke/Makefile.in
index f0db20c42..38924708a 100644
--- a/src/libcharon/plugins/stroke/Makefile.in
+++ b/src/libcharon/plugins/stroke/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -73,12 +73,19 @@ am__nobase_list = $(am__nobase_strip_setup); \
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
libstrongswan_stroke_la_LIBADD =
am_libstrongswan_stroke_la_OBJECTS = stroke_plugin.lo stroke_socket.lo \
stroke_config.lo stroke_control.lo stroke_cred.lo stroke_ca.lo \
- stroke_attribute.lo stroke_handler.lo stroke_list.lo
+ stroke_attribute.lo stroke_handler.lo stroke_counter.lo \
+ stroke_list.lo
libstrongswan_stroke_la_OBJECTS = \
$(am_libstrongswan_stroke_la_OBJECTS)
libstrongswan_stroke_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -124,6 +131,7 @@ CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -151,6 +159,7 @@ LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
MYSQLCFLAG = @MYSQLCFLAG@
MYSQLCONFIG = @MYSQLCONFIG@
@@ -178,6 +187,7 @@ RANLIB = @RANLIB@
RTLIB = @RTLIB@
RUBY = @RUBY@
RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -190,6 +200,7 @@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
@@ -243,7 +254,6 @@ libexecdir = @libexecdir@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
maemo_CFLAGS = @maemo_CFLAGS@
maemo_LIBS = @maemo_LIBS@
manager_plugins = @manager_plugins@
@@ -309,6 +319,7 @@ libstrongswan_stroke_la_SOURCES = \
stroke_ca.h stroke_ca.c \
stroke_attribute.h stroke_attribute.c \
stroke_handler.h stroke_handler.c \
+ stroke_counter.h stroke_counter.c \
stroke_list.h stroke_list.c
libstrongswan_stroke_la_LDFLAGS = -module -avoid-version
@@ -386,7 +397,7 @@ clean-pluginLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
-libstrongswan-stroke.la: $(libstrongswan_stroke_la_OBJECTS) $(libstrongswan_stroke_la_DEPENDENCIES)
+libstrongswan-stroke.la: $(libstrongswan_stroke_la_OBJECTS) $(libstrongswan_stroke_la_DEPENDENCIES) $(EXTRA_libstrongswan_stroke_la_DEPENDENCIES)
$(libstrongswan_stroke_la_LINK) $(am_libstrongswan_stroke_la_rpath) $(libstrongswan_stroke_la_OBJECTS) $(libstrongswan_stroke_la_LIBADD) $(LIBS)
mostlyclean-compile:
@@ -399,6 +410,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_ca.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_config.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_control.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_counter.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_cred.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_handler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_list.Plo@am__quote@
@@ -531,10 +543,15 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
mostlyclean-generic:
clean-generic:
diff --git a/src/libcharon/plugins/stroke/stroke_attribute.c b/src/libcharon/plugins/stroke/stroke_attribute.c
index 85fb94e9e..0f3c38986 100644
--- a/src/libcharon/plugins/stroke/stroke_attribute.c
+++ b/src/libcharon/plugins/stroke/stroke_attribute.c
@@ -17,7 +17,7 @@
#include "stroke_attribute.h"
#include <daemon.h>
-#include <utils/linked_list.h>
+#include <collections/linked_list.h>
#include <threading/rwlock.h>
typedef struct private_stroke_attribute_t private_stroke_attribute_t;
diff --git a/src/libcharon/plugins/stroke/stroke_ca.c b/src/libcharon/plugins/stroke/stroke_ca.c
index 763b4cc0f..f8026875f 100644
--- a/src/libcharon/plugins/stroke/stroke_ca.c
+++ b/src/libcharon/plugins/stroke/stroke_ca.c
@@ -18,7 +18,7 @@
#include "stroke_cred.h"
#include <threading/rwlock.h>
-#include <utils/linked_list.h>
+#include <collections/linked_list.h>
#include <crypto/hashers/hasher.h>
#include <daemon.h>
diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c
index e43672b18..9f6124dc9 100644
--- a/src/libcharon/plugins/stroke/stroke_config.c
+++ b/src/libcharon/plugins/stroke/stroke_config.c
@@ -225,14 +225,16 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg
ikeport = msg->add_conn.me.ikeport;
ikeport = (ikeport == IKEV2_UDP_PORT) ?
charon->socket->get_port(charon->socket, FALSE) : ikeport;
- ike_cfg = ike_cfg_create(msg->add_conn.other.sendcert != CERT_NEVER_SEND,
+ ike_cfg = ike_cfg_create(msg->add_conn.version,
+ msg->add_conn.other.sendcert != CERT_NEVER_SEND,
msg->add_conn.force_encap,
msg->add_conn.me.address,
msg->add_conn.me.allow_any,
ikeport,
msg->add_conn.other.address,
msg->add_conn.other.allow_any,
- msg->add_conn.other.ikeport);
+ msg->add_conn.other.ikeport,
+ msg->add_conn.fragmentation);
add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg, NULL);
return ike_cfg;
}
@@ -412,7 +414,7 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
ca = other_end->ca2;
}
}
- if (id && *id == '%' && !streq(id, "%any"))
+ if (id && *id == '%' && !streq(id, "%any") && !streq(id, "%any6"))
{ /* has only an effect on rightid/2 */
loose = !local;
id++;
@@ -441,7 +443,7 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
cfg = auth_cfg_create();
- /* add identity and peer certifcate */
+ /* add identity and peer certificate */
identity = identification_create_from_string(id);
if (cert)
{
@@ -707,8 +709,7 @@ 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. */
- peer_cfg = peer_cfg_create(msg->add_conn.name,
- msg->add_conn.version, ike_cfg,
+ peer_cfg = peer_cfg_create(msg->add_conn.name, ike_cfg,
msg->add_conn.me.sendcert, unique,
msg->add_conn.rekey.tries, rekey, reauth, jitter, over,
msg->add_conn.mobike, msg->add_conn.aggressive,
@@ -881,10 +882,10 @@ static void add_ts(private_stroke_config_t *this,
}
else
{
- host_t *net;
-
if (!end->subnets)
{
+ host_t *net;
+
net = host_create_from_string(end->address, 0);
if (net)
{
@@ -895,39 +896,24 @@ static void add_ts(private_stroke_config_t *this,
}
else
{
- char *del, *start, *bits;
+ enumerator_t *enumerator;
+ char *subnet;
- start = end->subnets;
- do
+ enumerator = enumerator_create_token(end->subnets, ",", " ");
+ while (enumerator->enumerate(enumerator, &subnet))
{
- int intbits = 0;
-
- del = strchr(start, ',');
- if (del)
- {
- *del = '\0';
- }
- bits = strchr(start, '/');
- if (bits)
+ ts = traffic_selector_create_from_cidr(subnet,
+ end->protocol, end->port);
+ if (ts)
{
- *bits = '\0';
- intbits = atoi(bits + 1);
- }
-
- net = host_create_from_string(start, 0);
- if (net)
- {
- ts = traffic_selector_create_from_subnet(net, intbits,
- end->protocol, end->port);
child_cfg->add_traffic_selector(child_cfg, local, ts);
}
else
{
- DBG1(DBG_CFG, "invalid subnet: %s, skipped", start);
+ DBG1(DBG_CFG, "invalid subnet: %s, skipped", subnet);
}
- start = del + 1;
}
- while (del);
+ enumerator->destroy(enumerator);
}
}
}
@@ -1326,4 +1312,3 @@ stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred,
return &this->public;
}
-
diff --git a/src/libcharon/plugins/stroke/stroke_counter.c b/src/libcharon/plugins/stroke/stroke_counter.c
new file mode 100644
index 000000000..56eda945a
--- /dev/null
+++ b/src/libcharon/plugins/stroke/stroke_counter.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "stroke_counter.h"
+
+#include <threading/spinlock.h>
+
+ENUM(stroke_counter_type_names,
+ COUNTER_INIT_IKE_SA_REKEY, COUNTER_OUT_INFORMATIONAL_RSP,
+ "ikeInitRekey",
+ "ikeRspRekey",
+ "ikeChildSaRekey",
+ "ikeInInvalid",
+ "ikeInInvalidSpi",
+ "ikeInInitReq",
+ "ikeInInitRsp",
+ "ikeOutInitReq",
+ "ikeOutInitRsp",
+ "ikeInAuthReq",
+ "ikeInAuthRsp",
+ "ikeOutAuthReq",
+ "ikeOutAuthRsp",
+ "ikeInCrChildReq",
+ "ikeInCrChildRsp",
+ "ikeOutCrChildReq",
+ "ikeOutCrChildRsp",
+ "ikeInInfoReq",
+ "ikeInInfoRsp",
+ "ikeOutInfoReq",
+ "ikeOutInfoRsp",
+);
+
+typedef struct private_stroke_counter_t private_stroke_counter_t;
+
+/**
+ * Private data of an stroke_counter_t object.
+ */
+struct private_stroke_counter_t {
+
+ /**
+ * Public stroke_counter_t interface.
+ */
+ stroke_counter_t public;
+
+ /**
+ * Counter values
+ */
+ u_int64_t counter[COUNTER_MAX];
+
+ /**
+ * Lock for counter values
+ */
+ spinlock_t *lock;
+};
+
+METHOD(listener_t, alert, bool,
+ private_stroke_counter_t *this, ike_sa_t *ike_sa,
+ alert_t alert, va_list args)
+{
+ stroke_counter_type_t type;
+
+ switch (alert)
+ {
+ case ALERT_INVALID_IKE_SPI:
+ type = COUNTER_IN_INVALID_IKE_SPI;
+ break;
+ case ALERT_PARSE_ERROR_HEADER:
+ case ALERT_PARSE_ERROR_BODY:
+ type = COUNTER_IN_INVALID;
+ break;
+ default:
+ return TRUE;
+ }
+
+ this->lock->lock(this->lock);
+ this->counter[type]++;
+ this->lock->unlock(this->lock);
+
+ return TRUE;
+}
+
+METHOD(listener_t, ike_rekey, bool,
+ private_stroke_counter_t *this, ike_sa_t *old, ike_sa_t *new)
+{
+ stroke_counter_type_t type;
+ ike_sa_id_t *id;
+
+ id = new->get_id(new);
+ if (id->is_initiator(id))
+ {
+ type = COUNTER_INIT_IKE_SA_REKEY;
+ }
+ else
+ {
+ type = COUNTER_RESP_IKE_SA_REKEY;
+ }
+
+ this->lock->lock(this->lock);
+ this->counter[type]++;
+ this->lock->unlock(this->lock);
+
+ return TRUE;
+}
+
+METHOD(listener_t, child_rekey, bool,
+ private_stroke_counter_t *this, ike_sa_t *ike_sa,
+ child_sa_t *old, child_sa_t *new)
+{
+ this->lock->lock(this->lock);
+ this->counter[COUNTER_CHILD_SA_REKEY]++;
+ this->lock->unlock(this->lock);
+
+ return TRUE;
+}
+
+METHOD(listener_t, message_hook, bool,
+ private_stroke_counter_t *this, ike_sa_t *ike_sa, message_t *message,
+ bool incoming, bool plain)
+{
+ stroke_counter_type_t type;
+ bool request;
+
+ if ((incoming && !plain) || (!incoming && !plain))
+ { /* handle each message only once */
+ return TRUE;
+ }
+
+ request = message->get_request(message);
+ switch (message->get_exchange_type(message))
+ {
+ case IKE_SA_INIT:
+ if (incoming)
+ {
+ type = request ? COUNTER_IN_IKE_SA_INIT_REQ
+ : COUNTER_IN_IKE_SA_INIT_RSP;
+ }
+ else
+ {
+ type = request ? COUNTER_OUT_IKE_SA_INIT_REQ
+ : COUNTER_OUT_IKE_SA_INIT_RES;
+ }
+ break;
+ case IKE_AUTH:
+ if (incoming)
+ {
+ type = request ? COUNTER_IN_IKE_AUTH_REQ
+ : COUNTER_IN_IKE_AUTH_RSP;
+ }
+ else
+ {
+ type = request ? COUNTER_OUT_IKE_AUTH_REQ
+ : COUNTER_OUT_IKE_AUTH_RSP;
+ }
+ break;
+ case CREATE_CHILD_SA:
+ if (incoming)
+ {
+ type = request ? COUNTER_IN_CREATE_CHILD_SA_REQ
+ : COUNTER_IN_CREATE_CHILD_SA_RSP;
+ }
+ else
+ {
+ type = request ? COUNTER_OUT_CREATE_CHILD_SA_REQ
+ : COUNTER_OUT_CREATE_CHILD_SA_RSP;
+ }
+ break;
+ case INFORMATIONAL:
+ if (incoming)
+ {
+ type = request ? COUNTER_IN_INFORMATIONAL_REQ
+ : COUNTER_IN_INFORMATIONAL_RSP;
+ }
+ else
+ {
+ type = request ? COUNTER_OUT_INFORMATIONAL_REQ
+ : COUNTER_OUT_INFORMATIONAL_RSP;
+ }
+ break;
+ default:
+ return TRUE;
+ }
+
+ this->lock->lock(this->lock);
+ this->counter[type]++;
+ this->lock->unlock(this->lock);
+
+ return TRUE;
+}
+
+METHOD(stroke_counter_t, print, void,
+ private_stroke_counter_t *this, FILE *out)
+{
+ u_int64_t counter[COUNTER_MAX];
+ int i;
+
+ /* Take a snapshot to have congruent results, */
+ this->lock->lock(this->lock);
+ for (i = 0; i < countof(this->counter); i++)
+ {
+ counter[i] = this->counter[i];
+ }
+ this->lock->unlock(this->lock);
+
+ fprintf(out, "\nList of IKE counters:\n\n");
+
+ /* but do blocking write without the lock. */
+ for (i = 0; i < countof(this->counter); i++)
+ {
+ fprintf(out, "%-18N %12llu\n", stroke_counter_type_names, i, counter[i]);
+ }
+}
+
+METHOD(stroke_counter_t, destroy, void,
+ private_stroke_counter_t *this)
+{
+ this->lock->destroy(this->lock);
+ free(this);
+}
+
+/**
+ * See header
+ */
+stroke_counter_t *stroke_counter_create()
+{
+ private_stroke_counter_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .alert = _alert,
+ .ike_rekey = _ike_rekey,
+ .child_rekey = _child_rekey,
+ .message = _message_hook,
+ },
+ .print = _print,
+ .destroy = _destroy,
+ },
+ .lock = spinlock_create(),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/stroke/stroke_counter.h b/src/libcharon/plugins/stroke/stroke_counter.h
new file mode 100644
index 000000000..efaae0d6f
--- /dev/null
+++ b/src/libcharon/plugins/stroke/stroke_counter.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup stroke_counter stroke_counter
+ * @{ @ingroup stroke
+ */
+
+#ifndef STROKE_COUNTER_H_
+#define STROKE_COUNTER_H_
+
+#include <bus/listeners/listener.h>
+
+typedef struct stroke_counter_t stroke_counter_t;
+typedef enum stroke_counter_type_t stroke_counter_type_t;
+
+enum stroke_counter_type_t {
+ /** initiated IKE_SA rekeyings */
+ COUNTER_INIT_IKE_SA_REKEY,
+ /** responded IKE_SA rekeyings */
+ COUNTER_RESP_IKE_SA_REKEY,
+ /** completed CHILD_SA rekeyings */
+ COUNTER_CHILD_SA_REKEY,
+ /** messages with invalid types, length, or a value out of range */
+ COUNTER_IN_INVALID,
+ /** messages with an invalid IKE SPI */
+ COUNTER_IN_INVALID_IKE_SPI,
+ /** received IKE_SA_INIT requests */
+ COUNTER_IN_IKE_SA_INIT_REQ,
+ /** received IKE_SA_INIT responses */
+ COUNTER_IN_IKE_SA_INIT_RSP,
+ /** sent IKE_SA_INIT requests */
+ COUNTER_OUT_IKE_SA_INIT_REQ,
+ /** sent IKE_SA_INIT responses */
+ COUNTER_OUT_IKE_SA_INIT_RES,
+ /** received IKE_AUTH requests */
+ COUNTER_IN_IKE_AUTH_REQ,
+ /** received IKE_AUTH responses */
+ COUNTER_IN_IKE_AUTH_RSP,
+ /** sent IKE_AUTH requests */
+ COUNTER_OUT_IKE_AUTH_REQ,
+ /** sent IKE_AUTH responses */
+ COUNTER_OUT_IKE_AUTH_RSP,
+ /** received CREATE_CHILD_SA requests */
+ COUNTER_IN_CREATE_CHILD_SA_REQ,
+ /** received CREATE_CHILD_SA responses */
+ COUNTER_IN_CREATE_CHILD_SA_RSP,
+ /** sent CREATE_CHILD_SA requests */
+ COUNTER_OUT_CREATE_CHILD_SA_REQ,
+ /** sent CREATE_CHILD_SA responses */
+ COUNTER_OUT_CREATE_CHILD_SA_RSP,
+ /** received INFORMATIONAL requests */
+ COUNTER_IN_INFORMATIONAL_REQ,
+ /** received INFORMATIONAL responses */
+ COUNTER_IN_INFORMATIONAL_RSP,
+ /** sent INFORMATIONAL requests */
+ COUNTER_OUT_INFORMATIONAL_REQ,
+ /** sent INFORMATIONAL responses */
+ COUNTER_OUT_INFORMATIONAL_RSP,
+ /** number of counter types */
+ COUNTER_MAX
+};
+
+/**
+ * Collection of counter values for different IKE events.
+ */
+struct stroke_counter_t {
+
+ /**
+ * Implements listener_t.
+ */
+ listener_t listener;
+
+ /**
+ * Print counter values to an output stream.
+ *
+ * @param out output stream to write to
+ */
+ void (*print)(stroke_counter_t *this, FILE *out);
+
+ /**
+ * Destroy a stroke_counter_t.
+ */
+ void (*destroy)(stroke_counter_t *this);
+};
+
+/**
+ * Create a stroke_counter instance.
+ */
+stroke_counter_t *stroke_counter_create();
+
+#endif /** STROKE_COUNTER_H_ @}*/
diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c
index ebc09c0d5..c401bc6f1 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.c
+++ b/src/libcharon/plugins/stroke/stroke_cred.c
@@ -34,7 +34,7 @@
#include <credentials/certificates/ac.h>
#include <credentials/sets/mem_cred.h>
#include <credentials/sets/callback_cred.h>
-#include <utils/linked_list.h>
+#include <collections/linked_list.h>
#include <utils/lexparser.h>
#include <threading/rwlock.h>
#include <daemon.h>
@@ -82,35 +82,137 @@ struct private_stroke_cred_t {
bool cachecrl;
};
-METHOD(stroke_cred_t, load_ca, certificate_t*,
- private_stroke_cred_t *this, char *filename)
+/** Length of smartcard specifier parts (module, keyid) */
+#define SC_PART_LEN 128
+
+/**
+ * Kind of smartcard specifier token
+ */
+typedef enum {
+ SC_FORMAT_SLOT_MODULE_KEYID,
+ SC_FORMAT_SLOT_KEYID,
+ SC_FORMAT_KEYID,
+ SC_FORMAT_INVALID,
+} smartcard_format_t;
+
+/**
+ * Parse a smartcard specifier token
+ */
+static smartcard_format_t parse_smartcard(char *smartcard, u_int *slot,
+ char *module, char *keyid)
{
- certificate_t *cert;
- char path[PATH_MAX];
+ /* The token has one of the following three formats:
+ * - %smartcard<slot>@<module>:<keyid>
+ * - %smartcard<slot>:<keyid>
+ * - %smartcard:<keyid>
+ */
+ char buf[2 * SC_PART_LEN], *pos;
- if (*filename == '/')
+ if (sscanf(smartcard, "%%smartcard%u@%255s", slot, buf) == 2)
+ {
+ pos = strchr(buf, ':');
+ if (!pos)
+ {
+ return SC_FORMAT_INVALID;
+ }
+ *pos++ = '\0';
+ snprintf(module, SC_PART_LEN, "%s", buf);
+ snprintf(keyid, SC_PART_LEN, "%s", pos);
+ return SC_FORMAT_SLOT_MODULE_KEYID;
+ }
+ if (sscanf(smartcard, "%%smartcard%u:%127s", slot, keyid) == 2)
{
- snprintf(path, sizeof(path), "%s", filename);
+ return SC_FORMAT_SLOT_KEYID;
}
- else
+ if (sscanf(smartcard, "%%smartcard:%127s", keyid) == 1)
{
- snprintf(path, sizeof(path), "%s/%s", CA_CERTIFICATE_DIR, filename);
+ return SC_FORMAT_KEYID;
}
+ return SC_FORMAT_INVALID;
+}
- if (this->force_ca_cert)
- { /* we treat this certificate as a CA certificate even if it has no
- * CA basic constraint */
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_FROM_FILE, path, BUILD_X509_FLAG, X509_CA,
- BUILD_END);
+/**
+ * Load a credential from a smartcard
+ */
+static certificate_t *load_from_smartcard(smartcard_format_t format,
+ u_int slot, char *module, char *keyid,
+ credential_type_t type, int subtype)
+{
+ chunk_t chunk;
+ void *cred;
+
+ chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
+ switch (format)
+ {
+ case SC_FORMAT_SLOT_MODULE_KEYID:
+ cred = lib->creds->create(lib->creds, type, subtype,
+ BUILD_PKCS11_SLOT, slot,
+ BUILD_PKCS11_MODULE, module,
+ BUILD_PKCS11_KEYID, chunk, BUILD_END);
+ break;
+ case SC_FORMAT_SLOT_KEYID:
+ cred = lib->creds->create(lib->creds, type, subtype,
+ BUILD_PKCS11_SLOT, slot,
+ BUILD_PKCS11_KEYID, chunk, BUILD_END);
+ break;
+ case SC_FORMAT_KEYID:
+ cred = lib->creds->create(lib->creds, type, subtype,
+ BUILD_PKCS11_KEYID, chunk, BUILD_END);
+ break;
+ default:
+ cred = NULL;
+ break;
+ }
+ free(chunk.ptr);
+
+ return cred;
+}
+
+METHOD(stroke_cred_t, load_ca, certificate_t*,
+ private_stroke_cred_t *this, char *filename)
+{
+ certificate_t *cert = NULL;
+ char path[PATH_MAX];
+
+ if (strneq(filename, "%smartcard", strlen("%smartcard")))
+ {
+ smartcard_format_t format;
+ char module[SC_PART_LEN], keyid[SC_PART_LEN];
+ u_int slot;
+
+ format = parse_smartcard(filename, &slot, module, keyid);
+ if (format != SC_FORMAT_INVALID)
+ {
+ cert = (certificate_t*)load_from_smartcard(format,
+ slot, module, keyid, CRED_CERTIFICATE, CERT_X509);
+ }
}
else
{
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_FROM_FILE, path,
- BUILD_END);
+ if (*filename == '/')
+ {
+ snprintf(path, sizeof(path), "%s", filename);
+ }
+ else
+ {
+ snprintf(path, sizeof(path), "%s/%s", CA_CERTIFICATE_DIR, filename);
+ }
+
+ if (this->force_ca_cert)
+ { /* we treat this certificate as a CA certificate even if it has no
+ * CA basic constraint */
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, path, BUILD_X509_FLAG, X509_CA,
+ BUILD_END);
+ }
+ else
+ {
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, path,
+ BUILD_END);
+ }
}
if (cert)
{
@@ -123,6 +225,8 @@ METHOD(stroke_cred_t, load_ca, certificate_t*,
cert->destroy(cert);
return NULL;
}
+ DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s",
+ cert->get_subject(cert), filename);
return this->creds->add_cert_ref(this->creds, TRUE, cert);
}
return NULL;
@@ -131,22 +235,38 @@ METHOD(stroke_cred_t, load_ca, certificate_t*,
METHOD(stroke_cred_t, load_peer, certificate_t*,
private_stroke_cred_t *this, char *filename)
{
- certificate_t *cert;
+ certificate_t *cert = NULL;
char path[PATH_MAX];
- if (*filename == '/')
+ if (strneq(filename, "%smartcard", strlen("%smartcard")))
{
- snprintf(path, sizeof(path), "%s", filename);
+ smartcard_format_t format;
+ char module[SC_PART_LEN], keyid[SC_PART_LEN];
+ u_int slot;
+
+ format = parse_smartcard(filename, &slot, module, keyid);
+ if (format != SC_FORMAT_INVALID)
+ {
+ cert = (certificate_t*)load_from_smartcard(format,
+ slot, module, keyid, CRED_CERTIFICATE, CERT_X509);
+ }
}
else
{
- snprintf(path, sizeof(path), "%s/%s", CERTIFICATE_DIR, filename);
- }
+ if (*filename == '/')
+ {
+ snprintf(path, sizeof(path), "%s", filename);
+ }
+ else
+ {
+ snprintf(path, sizeof(path), "%s/%s", CERTIFICATE_DIR, filename);
+ }
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_ANY,
- BUILD_FROM_FILE, path,
- BUILD_END);
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_ANY,
+ BUILD_FROM_FILE, path,
+ BUILD_END);
+ }
if (cert)
{
cert = this->creds->add_cert_ref(this->creds, TRUE, cert);
@@ -585,7 +705,7 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
FILE *prompt)
{
chunk_t sc = chunk_empty, secret = chunk_empty;
- char smartcard[64], keyid[64], module[64], *pos;
+ char smartcard[BUF_LEN], keyid[SC_PART_LEN], module[SC_PART_LEN];
private_key_t *key = NULL;
u_int slot;
chunk_t chunk;
@@ -594,11 +714,7 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
mem_cred_t *mem = NULL;
callback_cred_t *cb = NULL;
pin_cb_data_t pin_data;
- enum {
- SC_FORMAT_SLOT_MODULE_KEYID,
- SC_FORMAT_SLOT_KEYID,
- SC_FORMAT_KEYID,
- } format;
+ smartcard_format_t format;
err_t ugh = extract_value(&sc, &line);
@@ -615,33 +731,8 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
snprintf(smartcard, sizeof(smartcard), "%.*s", (int)sc.len, sc.ptr);
smartcard[sizeof(smartcard) - 1] = '\0';
- /* parse slot and key id. Three formats are supported:
- * - %smartcard<slot>@<module>:<keyid>
- * - %smartcard<slot>:<keyid>
- * - %smartcard:<keyid>
- */
- if (sscanf(smartcard, "%%smartcard%u@%s", &slot, module) == 2)
- {
- pos = strchr(module, ':');
- if (!pos)
- {
- DBG1(DBG_CFG, "line %d: the given %%smartcard specifier is "
- "invalid", line_nr);
- return FALSE;
- }
- *pos = '\0';
- strncpy(keyid, pos + 1, sizeof(keyid));
- format = SC_FORMAT_SLOT_MODULE_KEYID;
- }
- else if (sscanf(smartcard, "%%smartcard%u:%s", &slot, keyid) == 2)
- {
- format = SC_FORMAT_SLOT_KEYID;
- }
- else if (sscanf(smartcard, "%%smartcard:%s", keyid) == 1)
- {
- format = SC_FORMAT_KEYID;
- }
- else
+ format = parse_smartcard(smartcard, &slot, module, keyid);
+ if (format == SC_FORMAT_INVALID)
{
DBG1(DBG_CFG, "line %d: the given %%smartcard specifier is not"
" supported or invalid", line_nr);
@@ -666,7 +757,7 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
free(secret.ptr);
if (!prompt)
{ /* no IO channel to prompt, skip */
- free(chunk.ptr);
+ chunk_clear(&chunk);
return TRUE;
}
/* use callback credential set to prompt for the pin */
@@ -688,27 +779,8 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
}
/* unlock: smartcard needs the pin and potentially calls public set */
- switch (format)
- {
- case SC_FORMAT_SLOT_MODULE_KEYID:
- key = lib->creds->create(lib->creds,
- CRED_PRIVATE_KEY, KEY_ANY,
- BUILD_PKCS11_SLOT, slot,
- BUILD_PKCS11_MODULE, module,
- BUILD_PKCS11_KEYID, chunk, BUILD_END);
- break;
- case SC_FORMAT_SLOT_KEYID:
- key = lib->creds->create(lib->creds,
- CRED_PRIVATE_KEY, KEY_ANY,
- BUILD_PKCS11_SLOT, slot,
- BUILD_PKCS11_KEYID, chunk, BUILD_END);
- break;
- case SC_FORMAT_KEYID:
- key = lib->creds->create(lib->creds,
- CRED_PRIVATE_KEY, KEY_ANY,
- BUILD_PKCS11_KEYID, chunk, BUILD_END);
- break;
- }
+ key = (private_key_t*)load_from_smartcard(format, slot, module, keyid,
+ CRED_PRIVATE_KEY, KEY_ANY);
if (mem)
{
lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
@@ -719,6 +791,7 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
lib->credmgr->remove_local_set(lib->credmgr, &cb->set);
cb->destroy(cb);
}
+ chunk_clear(&chunk);
if (key)
{
diff --git a/src/libcharon/plugins/stroke/stroke_cred.h b/src/libcharon/plugins/stroke/stroke_cred.h
index 83e648819..c37d05808 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.h
+++ b/src/libcharon/plugins/stroke/stroke_cred.h
@@ -27,7 +27,7 @@
#include <stroke_msg.h>
#include <credentials/credential_set.h>
#include <credentials/certificates/certificate.h>
-#include <utils/linked_list.h>
+#include <collections/linked_list.h>
typedef struct stroke_cred_t stroke_cred_t;
diff --git a/src/libcharon/plugins/stroke/stroke_handler.c b/src/libcharon/plugins/stroke/stroke_handler.c
index 523151efb..fef8cab67 100644
--- a/src/libcharon/plugins/stroke/stroke_handler.c
+++ b/src/libcharon/plugins/stroke/stroke_handler.c
@@ -16,7 +16,7 @@
#include "stroke_handler.h"
#include <daemon.h>
-#include <utils/linked_list.h>
+#include <collections/linked_list.h>
#include <threading/rwlock.h>
typedef struct private_stroke_handler_t private_stroke_handler_t;
diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c
index c012ff25d..b3a20a6c7 100644
--- a/src/libcharon/plugins/stroke/stroke_list.c
+++ b/src/libcharon/plugins/stroke/stroke_list.c
@@ -25,7 +25,7 @@
#include <hydra.h>
#include <daemon.h>
-#include <utils/linked_list.h>
+#include <collections/linked_list.h>
#include <plugins/plugin.h>
#include <credentials/certificates/x509.h>
#include <credentials/certificates/ac.h>
diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c
index 241f0fbf6..2771f0146 100644
--- a/src/libcharon/plugins/stroke/stroke_socket.c
+++ b/src/libcharon/plugins/stroke/stroke_socket.c
@@ -29,7 +29,7 @@
#include <threading/mutex.h>
#include <threading/thread.h>
#include <threading/condvar.h>
-#include <utils/linked_list.h>
+#include <collections/linked_list.h>
#include <processing/jobs/callback_job.h>
#include "stroke_config.h"
@@ -39,6 +39,7 @@
#include "stroke_attribute.h"
#include "stroke_handler.h"
#include "stroke_list.h"
+#include "stroke_counter.h"
/**
* To avoid clogging the thread pool with (blocking) jobs, we limit the number
@@ -123,6 +124,11 @@ struct private_stroke_socket_t {
* status information logging
*/
stroke_list_t *list;
+
+ /**
+ * Counter values for IKE events
+ */
+ stroke_counter_t *counter;
};
/**
@@ -389,6 +395,10 @@ static void stroke_list(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *
this->ca->list(this->ca, msg, out);
}
this->list->list(this->list, msg, out);
+ if (msg->list.flags & LIST_COUNTERS)
+ {
+ this->counter->print(this->counter, out);
+ }
}
/**
@@ -500,9 +510,6 @@ static void stroke_user_creds(private_stroke_socket_t *this,
static void stroke_loglevel(private_stroke_socket_t *this,
stroke_msg_t *msg, FILE *out)
{
- enumerator_t *enumerator;
- sys_logger_t *sys_logger;
- file_logger_t *file_logger;
debug_t group;
pop_string(msg, &(msg->loglevel.type));
@@ -515,21 +522,7 @@ static void stroke_loglevel(private_stroke_socket_t *this,
fprintf(out, "invalid type (%s)!\n", msg->loglevel.type);
return;
}
- /* we set the loglevel on ALL sys- and file-loggers */
- enumerator = charon->sys_loggers->create_enumerator(charon->sys_loggers);
- while (enumerator->enumerate(enumerator, &sys_logger))
- {
- sys_logger->set_level(sys_logger, group, msg->loglevel.level);
- charon->bus->add_logger(charon->bus, &sys_logger->logger);
- }
- enumerator->destroy(enumerator);
- enumerator = charon->file_loggers->create_enumerator(charon->file_loggers);
- while (enumerator->enumerate(enumerator, &file_logger))
- {
- file_logger->set_level(file_logger, group, msg->loglevel.level);
- charon->bus->add_logger(charon->bus, &file_logger->logger);
- }
- enumerator->destroy(enumerator);
+ charon->set_level(charon, group, msg->loglevel.level);
}
/**
@@ -798,6 +791,7 @@ METHOD(stroke_socket_t, destroy, void,
charon->backends->remove_backend(charon->backends, &this->config->backend);
hydra->attributes->remove_provider(hydra->attributes, &this->attribute->provider);
hydra->attributes->remove_handler(hydra->attributes, &this->handler->handler);
+ charon->bus->remove_listener(charon->bus, &this->counter->listener);
this->cred->destroy(this->cred);
this->ca->destroy(this->ca);
this->config->destroy(this->config);
@@ -805,6 +799,7 @@ METHOD(stroke_socket_t, destroy, void,
this->handler->destroy(this->handler);
this->control->destroy(this->control);
this->list->destroy(this->list);
+ this->counter->destroy(this->counter);
free(this);
}
@@ -834,6 +829,7 @@ stroke_socket_t *stroke_socket_create()
this->config = stroke_config_create(this->ca, this->cred, this->attribute);
this->control = stroke_control_create();
this->list = stroke_list_create(this->attribute);
+ this->counter = stroke_counter_create();
this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
this->condvar = condvar_create(CONDVAR_TYPE_DEFAULT);
@@ -847,6 +843,7 @@ stroke_socket_t *stroke_socket_create()
charon->backends->add_backend(charon->backends, &this->config->backend);
hydra->attributes->add_provider(hydra->attributes, &this->attribute->provider);
hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
+ charon->bus->add_listener(charon->bus, &this->counter->listener);
lib->processor->queue_job(lib->processor,
(job_t*)callback_job_create_with_prio((callback_job_cb_t)receive, this,