summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/stroke
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2013-08-25 15:37:26 +0200
committerYves-Alexis Perez <corsac@debian.org>2013-08-25 15:37:26 +0200
commit6b99c8d9cff7b3e8ae8f3204b99e7ea40f791349 (patch)
tree009fc492961e13860d2a4bc2de8caf2bbe2975e7 /src/libcharon/plugins/stroke
parentc83921a2b566aa9d55d8ccc7258f04fca6292ee6 (diff)
downloadvyos-strongswan-6b99c8d9cff7b3e8ae8f3204b99e7ea40f791349.tar.gz
vyos-strongswan-6b99c8d9cff7b3e8ae8f3204b99e7ea40f791349.zip
Imported Upstream version 5.1.0
Diffstat (limited to 'src/libcharon/plugins/stroke')
-rw-r--r--src/libcharon/plugins/stroke/Makefile.am14
-rw-r--r--src/libcharon/plugins/stroke/Makefile.in83
-rw-r--r--src/libcharon/plugins/stroke/stroke_config.c136
-rw-r--r--src/libcharon/plugins/stroke/stroke_control.c2
-rw-r--r--src/libcharon/plugins/stroke/stroke_cred.c241
-rw-r--r--src/libcharon/plugins/stroke/stroke_cred.h7
-rw-r--r--src/libcharon/plugins/stroke/stroke_list.c14
-rw-r--r--src/libcharon/plugins/stroke/stroke_plugin.c4
-rw-r--r--src/libcharon/plugins/stroke/stroke_socket.c346
9 files changed, 503 insertions, 344 deletions
diff --git a/src/libcharon/plugins/stroke/Makefile.am b/src/libcharon/plugins/stroke/Makefile.am
index 39b3e79d2..9509b1bd3 100644
--- a/src/libcharon/plugins/stroke/Makefile.am
+++ b/src/libcharon/plugins/stroke/Makefile.am
@@ -1,11 +1,13 @@
-
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/stroke
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon \
+ -I$(top_srcdir)/src/stroke \
+ -DIPSEC_CONFDIR=\"${sysconfdir}\" \
+ -DIPSEC_PIDDIR=\"${piddir}\"
AM_CFLAGS = \
--rdynamic \
--DIPSEC_CONFDIR=\"${sysconfdir}\" \
--DIPSEC_PIDDIR=\"${piddir}\"
+ -rdynamic
if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-stroke.la
diff --git a/src/libcharon/plugins/stroke/Makefile.in b/src/libcharon/plugins/stroke/Makefile.in
index 7d1100c08..151e7ba69 100644
--- a/src/libcharon/plugins/stroke/Makefile.in
+++ b/src/libcharon/plugins/stroke/Makefile.in
@@ -62,7 +62,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
$(top_srcdir)/m4/macros/add-plugin.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -105,9 +105,13 @@ am_libstrongswan_stroke_la_OBJECTS = stroke_plugin.lo stroke_socket.lo \
stroke_list.lo
libstrongswan_stroke_la_OBJECTS = \
$(am_libstrongswan_stroke_la_OBJECTS)
-libstrongswan_stroke_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libstrongswan_stroke_la_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+libstrongswan_stroke_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_stroke_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
@MONOLITHIC_FALSE@am_libstrongswan_stroke_la_rpath = -rpath \
@MONOLITHIC_FALSE@ $(plugindir)
@MONOLITHIC_TRUE@am_libstrongswan_stroke_la_rpath =
@@ -117,13 +121,26 @@ am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
SOURCES = $(libstrongswan_stroke_la_SOURCES)
DIST_SOURCES = $(libstrongswan_stroke_la_SOURCES)
am__can_run_installinfo = \
@@ -137,6 +154,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
@@ -149,6 +167,8 @@ CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CHECK_CFLAGS = @CHECK_CFLAGS@
CHECK_LIBS = @CHECK_LIBS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -164,6 +184,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GENHTML = @GENHTML@
GPERF = @GPERF@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
@@ -172,6 +193,7 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
@@ -218,6 +240,7 @@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCKLIB = @SOCKLIB@
STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
VERSION = @VERSION@
YACC = @YACC@
YFLAGS = @YFLAGS@
@@ -246,6 +269,7 @@ charon_natt_port = @charon_natt_port@
charon_plugins = @charon_plugins@
charon_udp_port = @charon_udp_port@
clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -323,13 +347,16 @@ top_srcdir = @top_srcdir@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/stroke
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon \
+ -I$(top_srcdir)/src/stroke \
+ -DIPSEC_CONFDIR=\"${sysconfdir}\" \
+ -DIPSEC_PIDDIR=\"${piddir}\"
AM_CFLAGS = \
--rdynamic \
--DIPSEC_CONFDIR=\"${sysconfdir}\" \
--DIPSEC_PIDDIR=\"${piddir}\"
+ -rdynamic
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-stroke.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-stroke.la
@@ -422,7 +449,7 @@ clean-pluginLTLIBRARIES:
rm -f "$${dir}/so_locations"; \
done
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)
+ $(AM_V_CCLD)$(libstrongswan_stroke_la_LINK) $(am_libstrongswan_stroke_la_rpath) $(libstrongswan_stroke_la_OBJECTS) $(libstrongswan_stroke_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -442,25 +469,25 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_socket.Plo@am__quote@
.c.o:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
-@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c
index 86f0fe431..079e65f11 100644
--- a/src/libcharon/plugins/stroke/stroke_config.c
+++ b/src/libcharon/plugins/stroke/stroke_config.c
@@ -21,6 +21,8 @@
#include <threading/mutex.h>
#include <utils/lexparser.h>
+#include <netdb.h>
+
typedef struct private_stroke_config_t private_stroke_config_t;
/**
@@ -489,8 +491,7 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
pubkey = end->rsakey;
if (pubkey && !streq(pubkey, "") && !streq(pubkey, "%cert"))
{
- certificate = this->cred->load_pubkey(this->cred, KEY_RSA, pubkey,
- identity);
+ certificate = this->cred->load_pubkey(this->cred, pubkey, identity);
if (certificate)
{
cfg->add(cfg, AUTH_RULE_SUBJECT_CERT, certificate);
@@ -558,9 +559,9 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
}
/* authentication metod (class, actually) */
- if (strneq(auth, "pubkey", strlen("pubkey")) ||
- strneq(auth, "rsa", strlen("rsa")) ||
- strneq(auth, "ecdsa", strlen("ecdsa")))
+ if (strpfx(auth, "pubkey") ||
+ strpfx(auth, "rsa") ||
+ strpfx(auth, "ecdsa"))
{
cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
build_crl_policy(cfg, local, msg->add_conn.crl_policy);
@@ -571,7 +572,7 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
{
cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
}
- else if (strneq(auth, "xauth", 5))
+ else if (strpfx(auth, "xauth"))
{
char *pos;
@@ -587,7 +588,7 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
identification_create_from_string(msg->add_conn.xauth_identity));
}
}
- else if (strneq(auth, "eap", 3))
+ else if (strpfx(auth, "eap"))
{
eap_vendor_type_t *type;
@@ -884,6 +885,96 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
}
/**
+ * Parse a protoport specifier
+ */
+static bool parse_protoport(char *token, u_int16_t *from_port,
+ u_int16_t *to_port, u_int8_t *protocol)
+{
+ char *sep, *port = "", *endptr;
+ struct protoent *proto;
+ struct servent *svc;
+ long int p;
+
+ sep = strrchr(token, ']');
+ if (!sep)
+ {
+ return FALSE;
+ }
+ *sep = '\0';
+
+ sep = strchr(token, '/');
+ if (sep)
+ { /* protocol/port */
+ *sep = '\0';
+ port = sep + 1;
+ }
+
+ if (streq(token, "%any"))
+ {
+ *protocol = 0;
+ }
+ else
+ {
+ proto = getprotobyname(token);
+ if (proto)
+ {
+ *protocol = proto->p_proto;
+ }
+ else
+ {
+ p = strtol(token, &endptr, 0);
+ if ((*token && *endptr) || p < 0 || p > 0xff)
+ {
+ return FALSE;
+ }
+ *protocol = (u_int8_t)p;
+ }
+ }
+ if (streq(port, "%any"))
+ {
+ *from_port = 0;
+ *to_port = 0xffff;
+ }
+ else if (streq(port, "%opaque"))
+ {
+ *from_port = 0xffff;
+ *to_port = 0;
+ }
+ else if (*port)
+ {
+ svc = getservbyname(port, NULL);
+ if (svc)
+ {
+ *from_port = *to_port = ntohs(svc->s_port);
+ }
+ else
+ {
+ p = strtol(port, &endptr, 0);
+ if (p < 0 || p > 0xffff)
+ {
+ return FALSE;
+ }
+ *from_port = p;
+ if (*endptr == '-')
+ {
+ port = endptr + 1;
+ p = strtol(port, &endptr, 0);
+ if (p < 0 || p > 0xffff)
+ {
+ return FALSE;
+ }
+ }
+ *to_port = p;
+ if (*endptr)
+ {
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/**
* build a traffic selector from a stroke_end
*/
static void add_ts(private_stroke_config_t *this,
@@ -914,13 +1005,38 @@ static void add_ts(private_stroke_config_t *this,
else
{
enumerator_t *enumerator;
- char *subnet;
+ char *subnet, *pos;
+ u_int16_t from_port, to_port;
+ u_int8_t proto;
enumerator = enumerator_create_token(end->subnets, ",", " ");
while (enumerator->enumerate(enumerator, &subnet))
{
- ts = traffic_selector_create_from_cidr(subnet, end->protocol,
- end->from_port, end->to_port);
+ from_port = end->from_port;
+ to_port = end->to_port;
+ proto = end->protocol;
+
+ pos = strchr(subnet, '[');
+ if (pos)
+ {
+ *(pos++) = '\0';
+ if (!parse_protoport(pos, &from_port, &to_port, &proto))
+ {
+ DBG1(DBG_CFG, "invalid proto/port: %s, skipped subnet",
+ pos);
+ continue;
+ }
+ }
+ if (streq(subnet, "%dynamic"))
+ {
+ ts = traffic_selector_create_dynamic(proto,
+ from_port, to_port);
+ }
+ else
+ {
+ ts = traffic_selector_create_from_cidr(subnet, proto,
+ from_port, to_port);
+ }
if (ts)
{
child_cfg->add_traffic_selector(child_cfg, local, ts);
diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c
index 91130d1ee..fdd1635a6 100644
--- a/src/libcharon/plugins/stroke/stroke_control.c
+++ b/src/libcharon/plugins/stroke/stroke_control.c
@@ -603,7 +603,7 @@ static void charon_route(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
}
else
{
- if (charon->traps->install(charon->traps, peer_cfg, child_cfg))
+ if (charon->traps->install(charon->traps, peer_cfg, child_cfg, 0))
{
fprintf(out, "'%s' routed\n", name);
}
diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c
index eda746f7e..8d0001271 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.c
+++ b/src/libcharon/plugins/stroke/stroke_cred.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2012 Tobias Brunner
+ * Copyright (C) 2008-2013 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -32,6 +32,7 @@
#include <credentials/certificates/x509.h>
#include <credentials/certificates/crl.h>
#include <credentials/certificates/ac.h>
+#include <credentials/containers/pkcs12.h>
#include <credentials/sets/mem_cred.h>
#include <credentials/sets/callback_cred.h>
#include <collections/linked_list.h>
@@ -72,7 +73,7 @@ struct private_stroke_cred_t {
/**
* ignore missing CA basic constraint (i.e. treat all certificates in
- * ipsec.conf ca sections and ipsec.d/cacert as CA certificates)
+ * ipsec.conf ca sections and ipsec.d/cacerts as CA certificates)
*/
bool force_ca_cert;
@@ -174,7 +175,7 @@ METHOD(stroke_cred_t, load_ca, certificate_t*,
certificate_t *cert = NULL;
char path[PATH_MAX];
- if (strneq(filename, "%smartcard", strlen("%smartcard")))
+ if (strpfx(filename, "%smartcard"))
{
smartcard_format_t format;
char module[SC_PART_LEN], keyid[SC_PART_LEN];
@@ -225,7 +226,7 @@ METHOD(stroke_cred_t, load_ca, certificate_t*,
cert->destroy(cert);
return NULL;
}
- DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s",
+ DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
cert->get_subject(cert), filename);
return this->creds->add_cert_ref(this->creds, TRUE, cert);
}
@@ -238,7 +239,7 @@ METHOD(stroke_cred_t, load_peer, certificate_t*,
certificate_t *cert = NULL;
char path[PATH_MAX];
- if (strneq(filename, "%smartcard", strlen("%smartcard")))
+ if (strpfx(filename, "%smartcard"))
{
smartcard_format_t format;
char module[SC_PART_LEN], keyid[SC_PART_LEN];
@@ -279,29 +280,45 @@ METHOD(stroke_cred_t, load_peer, certificate_t*,
}
METHOD(stroke_cred_t, load_pubkey, certificate_t*,
- private_stroke_cred_t *this, key_type_t type, char *filename,
- identification_t *identity)
+ private_stroke_cred_t *this, char *filename, identification_t *identity)
{
certificate_t *cert;
+ public_key_t *key;
char path[PATH_MAX];
+ builder_part_t build_part;
+ key_type_t type = KEY_ANY;
if (streq(filename, "%dns"))
{
-
+ return NULL;
+ }
+ if (strncaseeq(filename, "dns:", 4))
+ { /* RFC 3110 format */
+ build_part = BUILD_BLOB_DNSKEY;
+ /* not a complete RR, only RSA supported */
+ type = KEY_RSA;
+ filename += 4;
+ }
+ else if (strncaseeq(filename, "ssh:", 4))
+ { /* SSH key */
+ build_part = BUILD_BLOB_SSHKEY;
+ filename += 4;
+ }
+ else
+ { /* try PKCS#1 by default */
+ build_part = BUILD_BLOB_ASN1_DER;
}
- else if (strncaseeq(filename, "0x", 2) || strncaseeq(filename, "0s", 2))
+ if (strncaseeq(filename, "0x", 2) || strncaseeq(filename, "0s", 2))
{
- chunk_t printable_key, rfc3110_key;
- public_key_t *key;
+ chunk_t printable_key, raw_key;
printable_key = chunk_create(filename + 2, strlen(filename) - 2);
- rfc3110_key = strncaseeq(filename, "0x", 2) ?
+ raw_key = strncaseeq(filename, "0x", 2) ?
chunk_from_hex(printable_key, NULL) :
chunk_from_base64(printable_key, NULL);
- key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
- BUILD_BLOB_DNSKEY, rfc3110_key,
- BUILD_END);
- free(rfc3110_key.ptr);
+ key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, type,
+ build_part, raw_key, BUILD_END);
+ chunk_free(&raw_key);
if (key)
{
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,
@@ -309,6 +326,7 @@ METHOD(stroke_cred_t, load_pubkey, certificate_t*,
BUILD_PUBLIC_KEY, key,
BUILD_SUBJECT, identity,
BUILD_END);
+ type = key->get_type(key);
key->destroy(key);
if (cert)
{
@@ -318,8 +336,7 @@ METHOD(stroke_cred_t, load_pubkey, certificate_t*,
return cert;
}
}
- DBG1(DBG_CFG, " loading %N public key for \"%Y\" failed",
- key_type_names, type, identity);
+ DBG1(DBG_CFG, " loading public key for \"%Y\" failed", identity);
}
else
{
@@ -340,12 +357,15 @@ METHOD(stroke_cred_t, load_pubkey, certificate_t*,
if (cert)
{
cert = this->creds->add_cert_ref(this->creds, TRUE, cert);
+ key = cert->get_public_key(cert);
+ type = key->get_type(key);
+ key->destroy(key);
DBG1(DBG_CFG, " loaded %N public key for \"%Y\" from '%s'",
key_type_names, type, identity, filename);
return cert;
}
- DBG1(DBG_CFG, " loading %N public key for \"%Y\" from '%s' failed",
- key_type_names, type, identity, filename);
+ DBG1(DBG_CFG, " loading public key for \"%Y\" from '%s' failed",
+ identity, filename);
}
return NULL;
}
@@ -580,8 +600,12 @@ static err_t extract_secret(chunk_t *secret, chunk_t *line)
* Data for passphrase callback
*/
typedef struct {
+ /** cached passphrases */
+ mem_cred_t *cache;
/** socket we use for prompting */
FILE *prompt;
+ /** type of secret to unlock */
+ int type;
/** private key file */
char *path;
/** number of tries */
@@ -589,13 +613,15 @@ typedef struct {
} passphrase_cb_data_t;
/**
- * Callback function to receive Passphrases
+ * Callback function to receive passphrases
*/
static shared_key_t* passphrase_cb(passphrase_cb_data_t *data,
- shared_key_type_t type,
- identification_t *me, identification_t *other,
- id_match_t *match_me, id_match_t *match_other)
+ shared_key_type_t type, identification_t *me,
+ identification_t *other, id_match_t *match_me,
+ id_match_t *match_other)
{
+ static const int max_tries = 3;
+ shared_key_t *shared;
chunk_t secret;
char buf[256];
@@ -604,17 +630,23 @@ static shared_key_t* passphrase_cb(passphrase_cb_data_t *data,
return NULL;
}
+ data->try++;
+ if (data->try > max_tries + 1)
+ { /* another builder might call this after we gave up, fail silently */
+ return NULL;
+ }
+ if (data->try > max_tries)
+ {
+ fprintf(data->prompt, "Passphrase invalid, giving up.\n");
+ return NULL;
+ }
if (data->try > 1)
{
- if (data->try > 5)
- {
- fprintf(data->prompt, "PIN invalid, giving up.\n");
- return NULL;
- }
- fprintf(data->prompt, "PIN invalid!\n");
+ fprintf(data->prompt, "Passphrase invalid!\n");
}
- data->try++;
- fprintf(data->prompt, "Private key '%s' is encrypted.\n", data->path);
+ fprintf(data->prompt, "%s '%s' is encrypted.\n",
+ data->type == CRED_PRIVATE_KEY ? "Private key" : "PKCS#12 file",
+ data->path);
fprintf(data->prompt, "Passphrase:\n");
if (fgets(buf, sizeof(buf), data->prompt))
{
@@ -630,7 +662,10 @@ static shared_key_t* passphrase_cb(passphrase_cb_data_t *data,
{
*match_other = ID_MATCH_NONE;
}
- return shared_key_create(SHARED_PRIVATE_KEY_PASS, chunk_clone(secret));
+ shared = shared_key_create(SHARED_PRIVATE_KEY_PASS,
+ chunk_clone(secret));
+ data->cache->add_shared(data->cache, shared->get_ref(shared), NULL);
+ return shared;
}
}
return NULL;
@@ -670,12 +705,12 @@ static shared_key_t* pin_cb(pin_cb_data_t *data, shared_key_type_t type,
return NULL;
}
+ data->try++;
if (data->try > 1)
{
fprintf(data->prompt, "PIN invalid, aborting.\n");
return NULL;
}
- data->try++;
fprintf(data->prompt, "Login to '%s' required\n", data->card);
fprintf(data->prompt, "PIN:\n");
if (fgets(buf, sizeof(buf), data->prompt))
@@ -752,7 +787,7 @@ static bool load_pin(mem_cred_t *secrets, chunk_t line, int line_nr,
}
chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
- if (secret.len == 7 && strneq(secret.ptr, "%prompt", 7))
+ if (secret.len == 7 && strpfx(secret.ptr, "%prompt"))
{
free(secret.ptr);
if (!prompt)
@@ -764,7 +799,7 @@ static bool load_pin(mem_cred_t *secrets, chunk_t line, int line_nr,
pin_data.prompt = prompt;
pin_data.card = smartcard;
pin_data.keyid = chunk;
- pin_data.try = 1;
+ pin_data.try = 0;
cb = callback_cred_create_shared((void*)pin_cb, &pin_data);
lib->credmgr->add_local_set(lib->credmgr, &cb->set, FALSE);
}
@@ -802,15 +837,14 @@ static bool load_pin(mem_cred_t *secrets, chunk_t line, int line_nr,
}
/**
- * Load a private key
+ * Load a private key or PKCS#12 container from a file
*/
-static bool load_private(mem_cred_t *secrets, chunk_t line, int line_nr,
- FILE *prompt, key_type_t key_type)
+static bool load_from_file(chunk_t line, int line_nr, FILE *prompt,
+ char *path, int type, int subtype,
+ void **result)
{
- char path[PATH_MAX];
chunk_t filename;
chunk_t secret = chunk_empty;
- private_key_t *key;
err_t ugh = extract_value(&filename, &line);
@@ -827,12 +861,12 @@ static bool load_private(mem_cred_t *secrets, chunk_t line, int line_nr,
if (*filename.ptr == '/')
{
/* absolute path name */
- snprintf(path, sizeof(path), "%.*s", (int)filename.len, filename.ptr);
+ snprintf(path, PATH_MAX, "%.*s", (int)filename.len, filename.ptr);
}
else
{
/* relative path name */
- snprintf(path, sizeof(path), "%s/%.*s", PRIVATE_KEY_DIR,
+ snprintf(path, PATH_MAX, "%s/%.*s", PRIVATE_KEY_DIR,
(int)filename.len, filename.ptr);
}
@@ -846,32 +880,37 @@ static bool load_private(mem_cred_t *secrets, chunk_t line, int line_nr,
return FALSE;
}
}
- if (secret.len == 7 && strneq(secret.ptr, "%prompt", 7))
+ if (secret.len == 7 && strpfx(secret.ptr, "%prompt"))
{
- callback_cred_t *cb = NULL;
+ callback_cred_t *cb;
passphrase_cb_data_t pp_data = {
.prompt = prompt,
+ .type = type,
.path = path,
- .try = 1,
+ .try = 0,
};
free(secret.ptr);
if (!prompt)
{
+ *result = NULL;
return TRUE;
}
+ /* add cache first so if valid passphrases are needed multiple times
+ * the callback is not called anymore */
+ pp_data.cache = mem_cred_create();
+ lib->credmgr->add_local_set(lib->credmgr, &pp_data.cache->set, FALSE);
/* use callback credential set to prompt for the passphrase */
- pp_data.prompt = prompt;
- pp_data.path = path;
- pp_data.try = 1;
cb = callback_cred_create_shared((void*)passphrase_cb, &pp_data);
lib->credmgr->add_local_set(lib->credmgr, &cb->set, FALSE);
- key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, key_type,
- BUILD_FROM_FILE, path, BUILD_END);
+ *result = lib->creds->create(lib->creds, type, subtype,
+ BUILD_FROM_FILE, path, BUILD_END);
lib->credmgr->remove_local_set(lib->credmgr, &cb->set);
cb->destroy(cb);
+ lib->credmgr->remove_local_set(lib->credmgr, &pp_data.cache->set);
+ pp_data.cache->destroy(pp_data.cache);
}
else
{
@@ -882,14 +921,44 @@ static bool load_private(mem_cred_t *secrets, chunk_t line, int line_nr,
shared = shared_key_create(SHARED_PRIVATE_KEY_PASS, secret);
mem = mem_cred_create();
mem->add_shared(mem, shared, NULL);
+ if (eat_whitespace(&line))
+ { /* if there is a second passphrase add that too, could be needed for
+ * PKCS#12 files using different passwords for MAC and encryption */
+ ugh = extract_secret(&secret, &line);
+ if (ugh != NULL)
+ {
+ DBG1(DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh);
+ mem->destroy(mem);
+ return FALSE;
+ }
+ shared = shared_key_create(SHARED_PRIVATE_KEY_PASS, secret);
+ mem->add_shared(mem, shared, NULL);
+ }
lib->credmgr->add_local_set(lib->credmgr, &mem->set, FALSE);
- key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, key_type,
- BUILD_FROM_FILE, path, BUILD_END);
+ *result = lib->creds->create(lib->creds, type, subtype,
+ BUILD_FROM_FILE, path, BUILD_END);
lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
mem->destroy(mem);
}
+ return TRUE;
+}
+
+/**
+ * Load a private key
+ */
+static bool load_private(mem_cred_t *secrets, chunk_t line, int line_nr,
+ FILE *prompt, key_type_t key_type)
+{
+ char path[PATH_MAX];
+ private_key_t *key;
+
+ if (!load_from_file(line, line_nr, prompt, path, CRED_PRIVATE_KEY,
+ key_type, (void**)&key))
+ {
+ return FALSE;
+ }
if (key)
{
DBG1(DBG_CFG, " loaded %N private key from '%s'",
@@ -904,6 +973,58 @@ static bool load_private(mem_cred_t *secrets, chunk_t line, int line_nr,
}
/**
+ * Load a PKCS#12 container
+ */
+static bool load_pkcs12(private_stroke_cred_t *this, mem_cred_t *secrets,
+ chunk_t line, int line_nr, FILE *prompt)
+{
+ enumerator_t *enumerator;
+ char path[PATH_MAX];
+ certificate_t *cert;
+ private_key_t *key;
+ pkcs12_t *pkcs12;
+
+ if (!load_from_file(line, line_nr, prompt, path, CRED_CONTAINER,
+ CONTAINER_PKCS12, (void**)&pkcs12))
+ {
+ return FALSE;
+ }
+ if (!pkcs12)
+ {
+ DBG1(DBG_CFG, " loading credentials from '%s' failed", path);
+ return TRUE;
+ }
+ enumerator = pkcs12->create_cert_enumerator(pkcs12);
+ while (enumerator->enumerate(enumerator, &cert))
+ {
+ x509_t *x509 = (x509_t*)cert;
+
+ if (x509->get_flags(x509) & X509_CA)
+ {
+ DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
+ cert->get_subject(cert), path);
+ }
+ else
+ {
+ DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'",
+ cert->get_subject(cert), path);
+ }
+ this->creds->add_cert(this->creds, TRUE, cert->get_ref(cert));
+ }
+ enumerator->destroy(enumerator);
+ enumerator = pkcs12->create_key_enumerator(pkcs12);
+ while (enumerator->enumerate(enumerator, &key))
+ {
+ DBG1(DBG_CFG, " loaded %N private key from '%s'",
+ key_type_names, key->get_type(key), path);
+ secrets->add_key(secrets, key->get_ref(key));
+ }
+ enumerator->destroy(enumerator);
+ pkcs12->container.destroy(&pkcs12->container);
+ return TRUE;
+}
+
+/**
* Load a shared key
*/
static bool load_shared(mem_cred_t *secrets, chunk_t line, int line_nr,
@@ -1021,8 +1142,7 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
{
continue;
}
- if (line.len > strlen("include ") &&
- strneq(line.ptr, "include ", strlen("include ")))
+ if (line.len > strlen("include ") && strpfx(line.ptr, "include "))
{
char **expanded, *dir, pattern[PATH_MAX];
u_char *pos;
@@ -1090,7 +1210,7 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
continue;
}
- if (line.len > 2 && strneq(": ", line.ptr, 2))
+ if (line.len > 2 && strpfx(line.ptr, ": "))
{
/* no ids, skip the ':' */
ids = chunk_empty;
@@ -1121,6 +1241,13 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
break;
}
}
+ else if (match("P12", &token))
+ {
+ if (!load_pkcs12(this, secrets, line, line_nr, prompt))
+ {
+ break;
+ }
+ }
else if (match("PIN", &token))
{
if (!load_pin(secrets, line, line_nr, prompt))
@@ -1141,7 +1268,7 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
else
{
DBG1(DBG_CFG, "line %d: token must be either "
- "RSA, ECDSA, PSK, EAP, XAUTH or PIN", line_nr);
+ "RSA, ECDSA, P12, PIN, PSK, EAP, XAUTH or NTLM", line_nr);
break;
}
}
diff --git a/src/libcharon/plugins/stroke/stroke_cred.h b/src/libcharon/plugins/stroke/stroke_cred.h
index c37d05808..f6fbb96d3 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.h
+++ b/src/libcharon/plugins/stroke/stroke_cred.h
@@ -68,13 +68,12 @@ struct stroke_cred_t {
/**
* Load a raw public key and serve it through the credential_set.
*
- * @param type type of the raw public key (RSA or ECDSA)
- * @param filename file to load raw public key from
+ * @param filename encoding or file to load raw public key from
* @param identity identity of the raw public key owner
* @return reference to loaded raw public key, or NULL
*/
- certificate_t* (*load_pubkey)(stroke_cred_t *this, key_type_t type,
- char *filename, identification_t *identity);
+ certificate_t* (*load_pubkey)(stroke_cred_t *this, char *filename,
+ identification_t *identity);
/**
* Add a shared secret to serve through the credential_set.
diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c
index a2e1c80a5..e81f3fc32 100644
--- a/src/libcharon/plugins/stroke/stroke_list.c
+++ b/src/libcharon/plugins/stroke/stroke_list.c
@@ -207,8 +207,10 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
time_t use_in, use_out, rekey, now;
u_int64_t bytes_in, bytes_out, packets_in, packets_out;
proposal_t *proposal;
- child_cfg_t *config = child_sa->get_config(child_sa);
+ linked_list_t *my_ts, *other_ts;
+ child_cfg_t *config;
+ config = child_sa->get_config(child_sa);
now = time_monotonic(NULL);
fprintf(out, "%12s{%d}: %N, %N%s",
@@ -319,10 +321,15 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
fprintf(out, ", expires in %V", &now, &rekey);
}
+ my_ts = linked_list_create_from_enumerator(
+ child_sa->create_ts_enumerator(child_sa, TRUE));
+ other_ts = linked_list_create_from_enumerator(
+ child_sa->create_ts_enumerator(child_sa, FALSE));
fprintf(out, "\n%12s{%d}: %#R=== %#R\n",
child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
- child_sa->get_traffic_selectors(child_sa, TRUE),
- child_sa->get_traffic_selectors(child_sa, FALSE));
+ my_ts, other_ts);
+ my_ts->destroy(my_ts);
+ other_ts->destroy(other_ts);
}
/**
@@ -1364,6 +1371,7 @@ static void list_plugins(FILE *out)
free(str);
}
}
+ list->destroy(list);
}
enumerator->destroy(enumerator);
}
diff --git a/src/libcharon/plugins/stroke/stroke_plugin.c b/src/libcharon/plugins/stroke/stroke_plugin.c
index 4e47a120d..31df1f99b 100644
--- a/src/libcharon/plugins/stroke/stroke_plugin.c
+++ b/src/libcharon/plugins/stroke/stroke_plugin.c
@@ -51,12 +51,13 @@ static bool register_stroke(private_stroke_plugin_t *this,
if (reg)
{
this->socket = stroke_socket_create();
+ return this->socket != NULL;
}
else
{
DESTROY_IF(this->socket);
+ return TRUE;
}
- return TRUE;
}
METHOD(plugin_t, get_features, int,
@@ -104,4 +105,3 @@ plugin_t *stroke_plugin_create()
return &this->public.plugin;
}
-
diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c
index aa5c73b8b..88f73f3b0 100644
--- a/src/libcharon/plugins/stroke/stroke_socket.c
+++ b/src/libcharon/plugins/stroke/stroke_socket.c
@@ -26,11 +26,6 @@
#include <hydra.h>
#include <daemon.h>
-#include <threading/mutex.h>
-#include <threading/thread.h>
-#include <threading/condvar.h>
-#include <collections/linked_list.h>
-#include <processing/jobs/callback_job.h>
#include "stroke_config.h"
#include "stroke_control.h"
@@ -61,34 +56,9 @@ struct private_stroke_socket_t {
stroke_socket_t public;
/**
- * Unix socket to listen for strokes
+ * Service accepting stroke connections
*/
- int socket;
-
- /**
- * queued stroke commands
- */
- linked_list_t *commands;
-
- /**
- * lock for command list
- */
- mutex_t *mutex;
-
- /**
- * condvar to signal the arrival or completion of commands
- */
- condvar_t *condvar;
-
- /**
- * the number of currently handled commands
- */
- u_int handling;
-
- /**
- * the maximum number of concurrently handled commands
- */
- u_int max_concurrent;
+ stream_service_t *service;
/**
* configuration backend
@@ -132,22 +102,6 @@ struct private_stroke_socket_t {
};
/**
- * job context to pass to processing thread
- */
-struct stroke_job_context_t {
-
- /**
- * file descriptor to read from
- */
- int fd;
-
- /**
- * global stroke interface
- */
- private_stroke_socket_t *this;
-};
-
-/**
* Helper function which corrects the string pointers
* in a stroke_msg_t. Strings in a stroke_msg sent over "wire"
* contains RELATIVE addresses (relative to the beginning of the
@@ -432,6 +386,20 @@ static void stroke_purge(private_stroke_socket_t *this,
}
/**
+ * Print a certificate in PEM to out
+ */
+static void print_pem_cert(FILE *out, certificate_t *cert)
+{
+ chunk_t encoded;
+
+ if (cert->get_encoding(cert, CERT_PEM, &encoded))
+ {
+ fprintf(out, "%.*s", (int)encoded.len, encoded.ptr);
+ free(encoded.ptr);
+ }
+}
+
+/**
* Export in-memory credentials
*/
static void stroke_export(private_stroke_socket_t *this,
@@ -444,22 +412,67 @@ static void stroke_export(private_stroke_socket_t *this,
enumerator_t *enumerator;
identification_t *id;
certificate_t *cert;
- chunk_t encoded;
id = identification_create_from_string(msg->export.selector);
enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
CERT_X509, KEY_ANY, id, FALSE);
while (enumerator->enumerate(enumerator, &cert))
{
- if (cert->get_encoding(cert, CERT_PEM, &encoded))
- {
- fprintf(out, "%.*s", (int)encoded.len, encoded.ptr);
- free(encoded.ptr);
- }
+ print_pem_cert(out, cert);
}
enumerator->destroy(enumerator);
id->destroy(id);
}
+
+ if (msg->export.flags & (EXPORT_CONN_CERT | EXPORT_CONN_CHAIN))
+ {
+ enumerator_t *sas, *auths, *certs;
+ ike_sa_t *ike_sa;
+ auth_cfg_t *auth;
+ certificate_t *cert;
+ auth_rule_t rule;
+
+ sas = charon->ike_sa_manager->create_enumerator(
+ charon->ike_sa_manager, TRUE);
+ while (sas->enumerate(sas, &ike_sa))
+ {
+ if (streq(msg->export.selector, ike_sa->get_name(ike_sa)))
+ {
+ auths = ike_sa->create_auth_cfg_enumerator(ike_sa, FALSE);
+ while (auths->enumerate(auths, &auth))
+ {
+ bool got_subject = FALSE;
+
+ certs = auth->create_enumerator(auth);
+ while (certs->enumerate(certs, &rule, &cert))
+ {
+ switch (rule)
+ {
+ case AUTH_RULE_CA_CERT:
+ case AUTH_RULE_IM_CERT:
+ if (msg->export.flags & EXPORT_CONN_CHAIN)
+ {
+ print_pem_cert(out, cert);
+ }
+ break;
+ case AUTH_RULE_SUBJECT_CERT:
+ if (!got_subject)
+ {
+ print_pem_cert(out, cert);
+ got_subject = TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ certs->destroy(certs);
+ }
+ auths->destroy(auths);
+ }
+ }
+ sas->destroy(sas);
+ }
}
/**
@@ -557,68 +570,47 @@ static void stroke_config(private_stroke_socket_t *this,
}
/**
- * destroy a job context
- */
-static void stroke_job_context_destroy(stroke_job_context_t *this)
-{
- if (this->fd)
- {
- close(this->fd);
- }
- free(this);
-}
-
-/**
- * called to signal the completion of a command
- */
-static inline job_requeue_t job_processed(private_stroke_socket_t *this)
-{
- this->mutex->lock(this->mutex);
- this->handling--;
- this->condvar->signal(this->condvar);
- this->mutex->unlock(this->mutex);
- return JOB_REQUEUE_NONE;
-}
-
-/**
- * process a stroke request from the socket pointed by "fd"
+ * process a stroke request
*/
-static job_requeue_t process(stroke_job_context_t *ctx)
+static bool on_accept(private_stroke_socket_t *this, stream_t *stream)
{
stroke_msg_t *msg;
- u_int16_t msg_length;
- ssize_t bytes_read;
+ u_int16_t len;
FILE *out;
- private_stroke_socket_t *this = ctx->this;
- int strokefd = ctx->fd;
- /* peek the length */
- bytes_read = recv(strokefd, &msg_length, sizeof(msg_length), MSG_PEEK);
- if (bytes_read != sizeof(msg_length))
+ /* read length */
+ if (!stream->read_all(stream, &len, sizeof(len)))
{
- DBG1(DBG_CFG, "reading length of stroke message failed: %s",
- strerror(errno));
- return job_processed(this);
+ if (errno != EWOULDBLOCK)
+ {
+ DBG1(DBG_CFG, "reading length of stroke message failed: %s",
+ strerror(errno));
+ }
+ return FALSE;
}
/* read message */
- msg = alloca(msg_length);
- bytes_read = recv(strokefd, msg, msg_length, 0);
- if (bytes_read != msg_length)
+ msg = malloc(len);
+ msg->length = len;
+ if (!stream->read_all(stream, (char*)msg + sizeof(len), len - sizeof(len)))
{
- DBG1(DBG_CFG, "reading stroke message failed: %s", strerror(errno));
- return job_processed(this);
+ if (errno != EWOULDBLOCK)
+ {
+ DBG1(DBG_CFG, "reading stroke message failed: %s", strerror(errno));
+ }
+ free(msg);
+ return FALSE;
}
- out = fdopen(strokefd, "w+");
- if (out == NULL)
+ DBG3(DBG_CFG, "stroke message %b", (void*)msg, len);
+
+ out = stream->get_file(stream);
+ if (!out)
{
- DBG1(DBG_CFG, "opening stroke output channel failed: %s", strerror(errno));
- return job_processed(this);
+ DBG1(DBG_CFG, "creating stroke output stream failed");
+ free(msg);
+ return FALSE;
}
-
- DBG3(DBG_CFG, "stroke message %b", (void*)msg, msg_length);
-
switch (msg->type)
{
case STR_INITIATE:
@@ -694,123 +686,15 @@ static job_requeue_t process(stroke_job_context_t *ctx)
DBG1(DBG_CFG, "received unknown stroke");
break;
}
+ free(msg);
fclose(out);
- /* fclose() closes underlying FD */
- ctx->fd = 0;
- return job_processed(this);
-}
-
-/**
- * Handle queued stroke commands
- */
-static job_requeue_t handle(private_stroke_socket_t *this)
-{
- stroke_job_context_t *ctx;
- callback_job_t *job;
- bool oldstate;
-
- this->mutex->lock(this->mutex);
- thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex);
- oldstate = thread_cancelability(TRUE);
- while (this->commands->get_count(this->commands) == 0 ||
- this->handling >= this->max_concurrent)
- {
- this->condvar->wait(this->condvar, this->mutex);
- }
- thread_cancelability(oldstate);
- this->commands->remove_first(this->commands, (void**)&ctx);
- this->handling++;
- thread_cleanup_pop(TRUE);
- job = callback_job_create_with_prio((callback_job_cb_t)process, ctx,
- (void*)stroke_job_context_destroy, NULL, JOB_PRIO_HIGH);
- lib->processor->queue_job(lib->processor, (job_t*)job);
- return JOB_REQUEUE_DIRECT;
-}
-
-/**
- * Accept stroke commands and queue them to be handled
- */
-static job_requeue_t receive(private_stroke_socket_t *this)
-{
- struct sockaddr_un strokeaddr;
- int strokeaddrlen = sizeof(strokeaddr);
- int strokefd;
- bool oldstate;
- stroke_job_context_t *ctx;
-
- oldstate = thread_cancelability(TRUE);
- strokefd = accept(this->socket, (struct sockaddr *)&strokeaddr, &strokeaddrlen);
- thread_cancelability(oldstate);
-
- if (strokefd < 0)
- {
- DBG1(DBG_CFG, "accepting stroke connection failed: %s", strerror(errno));
- return JOB_REQUEUE_FAIR;
- }
-
- INIT(ctx,
- .fd = strokefd,
- .this = this,
- );
- this->mutex->lock(this->mutex);
- this->commands->insert_last(this->commands, ctx);
- this->condvar->signal(this->condvar);
- this->mutex->unlock(this->mutex);
-
- return JOB_REQUEUE_FAIR;
-}
-
-/**
- * initialize and open stroke socket
- */
-static bool open_socket(private_stroke_socket_t *this)
-{
- 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);
- if (this->socket == -1)
- {
- DBG1(DBG_CFG, "could not create stroke socket");
- return FALSE;
- }
-
- unlink(socket_addr.sun_path);
- old = umask(~(S_IRWXU | S_IRWXG));
- if (bind(this->socket, (struct sockaddr *)&socket_addr, sizeof(socket_addr)) < 0)
- {
- DBG1(DBG_CFG, "could not bind stroke socket: %s", strerror(errno));
- close(this->socket);
- return FALSE;
- }
- umask(old);
- if (chown(socket_addr.sun_path, charon->caps->get_uid(charon->caps),
- charon->caps->get_gid(charon->caps)) != 0)
- {
- DBG1(DBG_CFG, "changing stroke socket permissions failed: %s",
- strerror(errno));
- }
-
- if (listen(this->socket, 10) < 0)
- {
- DBG1(DBG_CFG, "could not listen on stroke socket: %s", strerror(errno));
- close(this->socket);
- unlink(socket_addr.sun_path);
- return FALSE;
- }
- return TRUE;
+ return FALSE;
}
METHOD(stroke_socket_t, destroy, void,
private_stroke_socket_t *this)
{
- this->commands->destroy_function(this->commands, (void*)stroke_job_context_destroy);
- this->condvar->destroy(this->condvar);
- this->mutex->destroy(this->mutex);
+ DESTROY_IF(this->service);
lib->credmgr->remove_set(lib->credmgr, &this->ca->set);
lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
charon->backends->remove_backend(charon->backends, &this->config->backend);
@@ -834,6 +718,8 @@ METHOD(stroke_socket_t, destroy, void,
stroke_socket_t *stroke_socket_create()
{
private_stroke_socket_t *this;
+ int max_concurrent;
+ char *uri;
INIT(this,
.public = {
@@ -841,12 +727,6 @@ stroke_socket_t *stroke_socket_create()
},
);
- if (!open_socket(this))
- {
- free(this);
- return NULL;
- }
-
this->cred = stroke_cred_create();
this->attribute = stroke_attribute_create();
this->handler = stroke_handler_create();
@@ -856,13 +736,6 @@ stroke_socket_t *stroke_socket_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);
- this->commands = linked_list_create();
- this->max_concurrent = lib->settings->get_int(lib->settings,
- "%s.plugins.stroke.max_concurrent", MAX_CONCURRENT_DEFAULT,
- charon->name);
-
lib->credmgr->add_set(lib->credmgr, &this->ca->set);
lib->credmgr->add_set(lib->credmgr, &this->cred->set);
charon->backends->add_backend(charon->backends, &this->config->backend);
@@ -870,13 +743,20 @@ stroke_socket_t *stroke_socket_create()
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,
- NULL, (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL));
-
- lib->processor->queue_job(lib->processor,
- (job_t*)callback_job_create_with_prio((callback_job_cb_t)handle, this,
- NULL, (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL));
+ max_concurrent = lib->settings->get_int(lib->settings,
+ "%s.plugins.stroke.max_concurrent", MAX_CONCURRENT_DEFAULT,
+ charon->name);
+ uri = lib->settings->get_str(lib->settings,
+ "%s.plugins.stroke.socket", "unix://" STROKE_SOCKET, charon->name);
+ this->service = lib->streams->create_service(lib->streams, uri, 10);
+ if (!this->service)
+ {
+ DBG1(DBG_CFG, "creating stroke socket failed");
+ destroy(this);
+ return NULL;
+ }
+ this->service->on_accept(this->service, (stream_service_cb_t)on_accept,
+ this, JOB_PRIO_CRITICAL, max_concurrent);
return &this->public;
}