summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins
diff options
context:
space:
mode:
authorRené Mayrhofer <rene@mayrhofer.eu.org>2011-05-19 13:37:29 +0200
committerRené Mayrhofer <rene@mayrhofer.eu.org>2011-05-19 13:37:29 +0200
commit0a9d51a49042a68daa15b0c74a2b7f152f52606b (patch)
tree451888dcb17d00e52114f734e846821373fbbd44 /src/libcharon/plugins
parent568905f488e63e28778f87ac0e38d845f45bae79 (diff)
downloadvyos-strongswan-0a9d51a49042a68daa15b0c74a2b7f152f52606b.tar.gz
vyos-strongswan-0a9d51a49042a68daa15b0c74a2b7f152f52606b.zip
Imported Upstream version 4.5.2
Diffstat (limited to 'src/libcharon/plugins')
-rw-r--r--src/libcharon/plugins/addrblock/Makefile.in3
-rw-r--r--src/libcharon/plugins/addrblock/addrblock_plugin.c8
-rw-r--r--src/libcharon/plugins/addrblock/addrblock_validator.c6
-rw-r--r--src/libcharon/plugins/android/Makefile.in3
-rw-r--r--src/libcharon/plugins/android/android_plugin.c11
-rw-r--r--src/libcharon/plugins/coupling/Makefile.am16
-rw-r--r--src/libcharon/plugins/coupling/Makefile.in608
-rw-r--r--src/libcharon/plugins/coupling/coupling_plugin.c81
-rw-r--r--src/libcharon/plugins/coupling/coupling_plugin.h42
-rw-r--r--src/libcharon/plugins/coupling/coupling_validator.c258
-rw-r--r--src/libcharon/plugins/coupling/coupling_validator.h49
-rw-r--r--src/libcharon/plugins/dhcp/Makefile.in3
-rw-r--r--src/libcharon/plugins/dhcp/dhcp_plugin.c8
-rw-r--r--src/libcharon/plugins/dhcp/dhcp_socket.c3
-rw-r--r--src/libcharon/plugins/duplicheck/Makefile.am21
-rw-r--r--src/libcharon/plugins/duplicheck/Makefile.in668
-rw-r--r--src/libcharon/plugins/duplicheck/duplicheck.c59
-rw-r--r--src/libcharon/plugins/duplicheck/duplicheck_listener.c262
-rw-r--r--src/libcharon/plugins/duplicheck/duplicheck_listener.h54
-rw-r--r--src/libcharon/plugins/duplicheck/duplicheck_notify.c211
-rw-r--r--src/libcharon/plugins/duplicheck/duplicheck_notify.h51
-rw-r--r--src/libcharon/plugins/duplicheck/duplicheck_plugin.c94
-rw-r--r--src/libcharon/plugins/duplicheck/duplicheck_plugin.h42
-rw-r--r--src/libcharon/plugins/eap_aka/Makefile.in3
-rw-r--r--src/libcharon/plugins/eap_aka/eap_aka_peer.c122
-rw-r--r--src/libcharon/plugins/eap_aka/eap_aka_plugin.c24
-rw-r--r--src/libcharon/plugins/eap_aka/eap_aka_server.c88
-rw-r--r--src/libcharon/plugins/eap_aka_3gpp2/Makefile.in3
-rw-r--r--src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_plugin.c26
-rw-r--r--src/libcharon/plugins/eap_gtc/Makefile.in3
-rw-r--r--src/libcharon/plugins/eap_gtc/eap_gtc.c102
-rw-r--r--src/libcharon/plugins/eap_gtc/eap_gtc_plugin.c22
-rw-r--r--src/libcharon/plugins/eap_identity/Makefile.in3
-rw-r--r--src/libcharon/plugins/eap_identity/eap_identity.c30
-rw-r--r--src/libcharon/plugins/eap_identity/eap_identity_plugin.c8
-rw-r--r--src/libcharon/plugins/eap_md5/Makefile.in3
-rw-r--r--src/libcharon/plugins/eap_md5/eap_md5.c26
-rw-r--r--src/libcharon/plugins/eap_md5/eap_md5_plugin.c8
-rw-r--r--src/libcharon/plugins/eap_mschapv2/Makefile.in3
-rw-r--r--src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c105
-rw-r--r--src/libcharon/plugins/eap_mschapv2/eap_mschapv2_plugin.c24
-rw-r--r--src/libcharon/plugins/eap_peap/Makefile.am21
-rw-r--r--src/libcharon/plugins/eap_peap/Makefile.in617
-rw-r--r--src/libcharon/plugins/eap_peap/eap_peap.c213
-rw-r--r--src/libcharon/plugins/eap_peap/eap_peap.h59
-rw-r--r--src/libcharon/plugins/eap_peap/eap_peap_avp.c152
-rw-r--r--src/libcharon/plugins/eap_peap/eap_peap_avp.h71
-rw-r--r--src/libcharon/plugins/eap_peap/eap_peap_peer.c256
-rw-r--r--src/libcharon/plugins/eap_peap/eap_peap_peer.h49
-rw-r--r--src/libcharon/plugins/eap_peap/eap_peap_plugin.c59
-rw-r--r--src/libcharon/plugins/eap_peap/eap_peap_plugin.h47
-rw-r--r--src/libcharon/plugins/eap_peap/eap_peap_server.c432
-rw-r--r--src/libcharon/plugins/eap_peap/eap_peap_server.h49
-rw-r--r--src/libcharon/plugins/eap_radius/Makefile.in3
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius.c28
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_plugin.c79
-rw-r--r--src/libcharon/plugins/eap_radius/radius_client.c21
-rw-r--r--src/libcharon/plugins/eap_radius/radius_server.c55
-rw-r--r--src/libcharon/plugins/eap_radius/radius_server.h18
-rw-r--r--src/libcharon/plugins/eap_radius/radius_socket.c80
-rw-r--r--src/libcharon/plugins/eap_radius/radius_socket.h8
-rw-r--r--src/libcharon/plugins/eap_sim/Makefile.in3
-rw-r--r--src/libcharon/plugins/eap_sim/eap_sim_peer.c143
-rw-r--r--src/libcharon/plugins/eap_sim/eap_sim_plugin.c24
-rw-r--r--src/libcharon/plugins/eap_sim/eap_sim_server.c83
-rw-r--r--src/libcharon/plugins/eap_sim_file/Makefile.in3
-rw-r--r--src/libcharon/plugins/eap_sim_file/eap_sim_file_card.c51
-rw-r--r--src/libcharon/plugins/eap_sim_file/eap_sim_file_plugin.c28
-rw-r--r--src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.c41
-rw-r--r--src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c28
-rw-r--r--src/libcharon/plugins/eap_sim_pcsc/Makefile.am18
-rw-r--r--src/libcharon/plugins/eap_sim_pcsc/Makefile.in611
-rw-r--r--src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.c392
-rw-r--r--src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.h48
-rw-r--r--src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.c73
-rw-r--r--src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.h41
-rw-r--r--src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in3
-rw-r--r--src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c26
-rw-r--r--src/libcharon/plugins/eap_simaka_reauth/Makefile.in3
-rw-r--r--src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c26
-rw-r--r--src/libcharon/plugins/eap_simaka_sql/Makefile.in3
-rw-r--r--src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_plugin.c8
-rw-r--r--src/libcharon/plugins/eap_tls/Makefile.in3
-rw-r--r--src/libcharon/plugins/eap_tls/eap_tls.c20
-rw-r--r--src/libcharon/plugins/eap_tls/eap_tls_plugin.c7
-rw-r--r--src/libcharon/plugins/eap_tnc/Makefile.in3
-rw-r--r--src/libcharon/plugins/eap_tnc/eap_tnc.c22
-rw-r--r--src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c8
-rw-r--r--src/libcharon/plugins/eap_ttls/Makefile.in3
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls.c22
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls_peer.c49
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c7
-rw-r--r--src/libcharon/plugins/farp/Makefile.in3
-rw-r--r--src/libcharon/plugins/farp/farp_plugin.c8
-rw-r--r--src/libcharon/plugins/ha/Makefile.in3
-rw-r--r--src/libcharon/plugins/ha/ha_child.c4
-rw-r--r--src/libcharon/plugins/ha/ha_dispatcher.c5
-rw-r--r--src/libcharon/plugins/ha/ha_message.c2
-rw-r--r--src/libcharon/plugins/ha/ha_message.h2
-rw-r--r--src/libcharon/plugins/ha/ha_plugin.c8
-rw-r--r--src/libcharon/plugins/led/Makefile.in3
-rw-r--r--src/libcharon/plugins/led/led_plugin.c8
-rw-r--r--src/libcharon/plugins/load_tester/Makefile.in3
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_ipsec.c4
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_plugin.c51
-rw-r--r--src/libcharon/plugins/maemo/Makefile.in3
-rw-r--r--src/libcharon/plugins/maemo/maemo_plugin.c11
-rw-r--r--src/libcharon/plugins/medcli/Makefile.in3
-rw-r--r--src/libcharon/plugins/medcli/medcli_plugin.c26
-rw-r--r--src/libcharon/plugins/medsrv/Makefile.in3
-rw-r--r--src/libcharon/plugins/medsrv/medsrv_plugin.c26
-rw-r--r--src/libcharon/plugins/nm/Makefile.in3
-rw-r--r--src/libcharon/plugins/nm/nm_plugin.c33
-rw-r--r--src/libcharon/plugins/smp/Makefile.in3
-rw-r--r--src/libcharon/plugins/smp/smp.c24
-rw-r--r--src/libcharon/plugins/socket_default/Makefile.in3
-rw-r--r--src/libcharon/plugins/socket_default/socket_default_plugin.c9
-rw-r--r--src/libcharon/plugins/socket_dynamic/Makefile.in3
-rw-r--r--src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c9
-rw-r--r--src/libcharon/plugins/socket_raw/Makefile.in3
-rw-r--r--src/libcharon/plugins/socket_raw/socket_raw_plugin.c9
-rw-r--r--src/libcharon/plugins/sql/Makefile.in3
-rw-r--r--src/libcharon/plugins/sql/sql_plugin.c8
-rw-r--r--src/libcharon/plugins/stroke/Makefile.in3
-rw-r--r--src/libcharon/plugins/stroke/stroke_config.c2
-rw-r--r--src/libcharon/plugins/stroke/stroke_control.c193
-rw-r--r--src/libcharon/plugins/stroke/stroke_cred.c17
-rw-r--r--src/libcharon/plugins/stroke/stroke_list.c9
-rw-r--r--src/libcharon/plugins/stroke/stroke_plugin.c8
-rw-r--r--src/libcharon/plugins/stroke/stroke_socket.c4
-rw-r--r--src/libcharon/plugins/tnc_imc/Makefile.in3
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc.c36
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c18
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_manager.c36
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c14
-rw-r--r--src/libcharon/plugins/tnc_imv/Makefile.in3
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv.c35
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c36
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_manager.c70
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c14
-rw-r--r--src/libcharon/plugins/tnccs_11/Makefile.in3
-rw-r--r--src/libcharon/plugins/tnccs_11/tnccs_11.c44
-rw-r--r--src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c10
-rw-r--r--src/libcharon/plugins/tnccs_20/Makefile.in3
-rw-r--r--src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.c18
-rw-r--r--src/libcharon/plugins/tnccs_20/tnccs_20.c70
-rw-r--r--src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c10
-rw-r--r--src/libcharon/plugins/tnccs_dynamic/Makefile.in3
-rw-r--r--src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c10
-rw-r--r--src/libcharon/plugins/uci/Makefile.in3
-rw-r--r--src/libcharon/plugins/uci/uci_plugin.c34
-rw-r--r--src/libcharon/plugins/unit_tester/Makefile.in3
-rw-r--r--src/libcharon/plugins/unit_tester/unit_tester.c26
-rw-r--r--src/libcharon/plugins/updown/Makefile.in3
-rw-r--r--src/libcharon/plugins/updown/updown_plugin.c26
-rw-r--r--src/libcharon/plugins/whitelist/Makefile.am21
-rw-r--r--src/libcharon/plugins/whitelist/Makefile.in668
-rw-r--r--src/libcharon/plugins/whitelist/whitelist.c190
-rw-r--r--src/libcharon/plugins/whitelist/whitelist_control.c233
-rw-r--r--src/libcharon/plugins/whitelist/whitelist_control.h44
-rw-r--r--src/libcharon/plugins/whitelist/whitelist_listener.c213
-rw-r--r--src/libcharon/plugins/whitelist/whitelist_listener.h87
-rw-r--r--src/libcharon/plugins/whitelist/whitelist_msg.h58
-rw-r--r--src/libcharon/plugins/whitelist/whitelist_plugin.c83
-rw-r--r--src/libcharon/plugins/whitelist/whitelist_plugin.h42
165 files changed, 9185 insertions, 788 deletions
diff --git a/src/libcharon/plugins/addrblock/Makefile.in b/src/libcharon/plugins/addrblock/Makefile.in
index 018318a59..57aab1db7 100644
--- a/src/libcharon/plugins/addrblock/Makefile.in
+++ b/src/libcharon/plugins/addrblock/Makefile.in
@@ -244,6 +244,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -267,6 +269,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/addrblock/addrblock_plugin.c b/src/libcharon/plugins/addrblock/addrblock_plugin.c
index 5fdb36c5c..72c551f0f 100644
--- a/src/libcharon/plugins/addrblock/addrblock_plugin.c
+++ b/src/libcharon/plugins/addrblock/addrblock_plugin.c
@@ -43,6 +43,12 @@ struct private_addrblock_plugin_t {
addrblock_narrow_t *narrower;
};
+METHOD(plugin_t, get_name, char*,
+ private_addrblock_plugin_t *this)
+{
+ return "addrblock";
+}
+
METHOD(plugin_t, destroy, void,
private_addrblock_plugin_t *this)
{
@@ -63,6 +69,8 @@ plugin_t *addrblock_plugin_create()
INIT(this,
.public = {
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/addrblock/addrblock_validator.c b/src/libcharon/plugins/addrblock/addrblock_validator.c
index 12cf0c941..1b07378f7 100644
--- a/src/libcharon/plugins/addrblock/addrblock_validator.c
+++ b/src/libcharon/plugins/addrblock/addrblock_validator.c
@@ -88,7 +88,7 @@ static bool check_addrblock(x509_t *subject, x509_t *issuer)
METHOD(cert_validator_t, validate, bool,
private_addrblock_validator_t *this, certificate_t *subject,
- certificate_t *issuer, bool online, int pathlen, bool anchor,
+ certificate_t *issuer, bool online, u_int pathlen, bool anchor,
auth_cfg_t *auth)
{
if (subject->get_type(subject) == CERT_X509 &&
@@ -114,7 +114,9 @@ addrblock_validator_t *addrblock_validator_create()
INIT(this,
.public = {
- .validator.validate = _validate,
+ .validator = {
+ .validate = _validate,
+ },
.destroy = _destroy,
},
);
diff --git a/src/libcharon/plugins/android/Makefile.in b/src/libcharon/plugins/android/Makefile.in
index 7d6eb2b9c..08248da12 100644
--- a/src/libcharon/plugins/android/Makefile.in
+++ b/src/libcharon/plugins/android/Makefile.in
@@ -244,6 +244,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -267,6 +269,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/android/android_plugin.c b/src/libcharon/plugins/android/android_plugin.c
index 3d82d8f60..54a7017a1 100644
--- a/src/libcharon/plugins/android/android_plugin.c
+++ b/src/libcharon/plugins/android/android_plugin.c
@@ -54,11 +54,16 @@ struct private_android_plugin_t {
* Service that interacts with the Android Settings frontend
*/
android_service_t *service;
-
};
+METHOD(plugin_t, get_name, char*,
+ private_android_plugin_t *this)
+{
+ return "android";
+}
+
METHOD(plugin_t, destroy, void,
- private_android_plugin_t *this)
+ private_android_plugin_t *this)
{
hydra->attributes->remove_handler(hydra->attributes,
&this->handler->handler);
@@ -81,6 +86,8 @@ plugin_t *android_plugin_create()
INIT(this,
.public = {
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/coupling/Makefile.am b/src/libcharon/plugins/coupling/Makefile.am
new file mode 100644
index 000000000..642ce820c
--- /dev/null
+++ b/src/libcharon/plugins/coupling/Makefile.am
@@ -0,0 +1,16 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = -rdynamic
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-coupling.la
+else
+plugin_LTLIBRARIES = libstrongswan-coupling.la
+endif
+
+libstrongswan_coupling_la_SOURCES = coupling_plugin.h coupling_plugin.c \
+ coupling_validator.h coupling_validator.c
+
+libstrongswan_coupling_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/coupling/Makefile.in b/src/libcharon/plugins/coupling/Makefile.in
new file mode 100644
index 000000000..a3104e4c0
--- /dev/null
+++ b/src/libcharon/plugins/coupling/Makefile.in
@@ -0,0 +1,608 @@
+# Makefile.in generated by automake 1.11.1 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.
+# 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libcharon/plugins/coupling
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.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
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+libstrongswan_coupling_la_LIBADD =
+am_libstrongswan_coupling_la_OBJECTS = coupling_plugin.lo \
+ coupling_validator.lo
+libstrongswan_coupling_la_OBJECTS = \
+ $(am_libstrongswan_coupling_la_OBJECTS)
+libstrongswan_coupling_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_coupling_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_coupling_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_coupling_la_rpath =
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+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)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_coupling_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_coupling_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREADLIB = @PTHREADLIB@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+default_pkcs11 = @default_pkcs11@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
+libdir = @libdir@
+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@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+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
+
+AM_CFLAGS = -rdynamic
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-coupling.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-coupling.la
+libstrongswan_coupling_la_SOURCES = coupling_plugin.h coupling_plugin.c \
+ coupling_validator.h coupling_validator.c
+
+libstrongswan_coupling_la_LDFLAGS = -module -avoid-version
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/coupling/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/coupling/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+ }
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstrongswan-coupling.la: $(libstrongswan_coupling_la_OBJECTS) $(libstrongswan_coupling_la_DEPENDENCIES)
+ $(libstrongswan_coupling_la_LINK) $(am_libstrongswan_coupling_la_rpath) $(libstrongswan_coupling_la_OBJECTS) $(libstrongswan_coupling_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coupling_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coupling_validator.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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-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
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
+ ctags distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-pluginLTLIBRARIES install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/coupling/coupling_plugin.c b/src/libcharon/plugins/coupling/coupling_plugin.c
new file mode 100644
index 000000000..7ccc51db5
--- /dev/null
+++ b/src/libcharon/plugins/coupling/coupling_plugin.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 "coupling_plugin.h"
+
+#include "coupling_validator.h"
+
+#include <daemon.h>
+
+typedef struct private_coupling_plugin_t private_coupling_plugin_t;
+
+/**
+ * private data of coupling plugin
+ */
+struct private_coupling_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ coupling_plugin_t public;
+
+ /**
+ * validator controlling couplings
+ */
+ coupling_validator_t *validator;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_coupling_plugin_t *this)
+{
+ return "coupling";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_coupling_plugin_t *this)
+{
+ lib->credmgr->remove_validator(lib->credmgr, &this->validator->validator);
+ this->validator->destroy(this->validator);
+ free(this);
+}
+
+/**
+ * Plugin constructor
+ */
+plugin_t *coupling_plugin_create()
+{
+ private_coupling_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ .validator = coupling_validator_create(),
+ );
+
+ if (!this->validator)
+ {
+ free(this);
+ return NULL;
+ }
+
+ lib->credmgr->add_validator(lib->credmgr, &this->validator->validator);
+
+ return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/coupling/coupling_plugin.h b/src/libcharon/plugins/coupling/coupling_plugin.h
new file mode 100644
index 000000000..645100b45
--- /dev/null
+++ b/src/libcharon/plugins/coupling/coupling_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 coupling coupling
+ * @ingroup cplugins
+ *
+ * @defgroup coupling_plugin coupling_plugin
+ * @{ @ingroup coupling
+ */
+
+#ifndef COUPLING_PLUGIN_H_
+#define COUPLING_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct coupling_plugin_t coupling_plugin_t;
+
+/**
+ * Plugin to couple peer certificates permanently to peer authentication.
+ */
+struct coupling_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** COUPLING_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/coupling/coupling_validator.c b/src/libcharon/plugins/coupling/coupling_validator.c
new file mode 100644
index 000000000..06b6f7d86
--- /dev/null
+++ b/src/libcharon/plugins/coupling/coupling_validator.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 "coupling_validator.h"
+
+#include <errno.h>
+#include <time.h>
+
+#include <daemon.h>
+#include <threading/mutex.h>
+
+/* buffer size for hex-encoded hash */
+#define MAX_HASH_SIZE (HASH_SIZE_SHA512 * 2 + 1)
+
+typedef struct private_coupling_validator_t private_coupling_validator_t;
+
+/**
+ * Private data of an coupling_validator_t object.
+ */
+struct private_coupling_validator_t {
+
+ /**
+ * Public coupling_validator_t interface.
+ */
+ coupling_validator_t public;
+
+ /**
+ * Mutex
+ */
+ mutex_t *mutex;
+
+ /**
+ * File with device couplings
+ */
+ FILE *f;
+
+ /**
+ * Hasher to create hashes
+ */
+ hasher_t *hasher;
+
+ /**
+ * maximum number of couplings
+ */
+ int max_couplings;
+};
+
+/**
+ * Get hash of a certificate
+ */
+static bool get_cert_hash(private_coupling_validator_t *this,
+ certificate_t *cert, char *hex)
+{
+ char buf[MAX_HASH_SIZE];
+ chunk_t encoding;
+
+ if (!cert->get_encoding(cert, CERT_ASN1_DER, &encoding))
+ {
+ return FALSE;
+ }
+ this->hasher->get_hash(this->hasher, encoding, buf);
+ free(encoding.ptr);
+ chunk_to_hex(chunk_create(buf, this->hasher->get_hash_size(this->hasher)),
+ hex, FALSE);
+ return TRUE;
+}
+
+/**
+ * Check if we have an entry for a given hash
+ */
+static bool has_entry(private_coupling_validator_t *this, char *hash)
+{
+ char line[256];
+ int hash_len;
+
+ hash_len = strlen(hash);
+ rewind(this->f);
+
+ while (fgets(line, sizeof(line), this->f))
+ {
+ if (strlen(line) >= hash_len &&
+ strncaseeq(line, hash, hash_len))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * Get the number of coupling entries we currently have
+ */
+static int get_number_of_entries(private_coupling_validator_t *this)
+{
+ char line[256];
+ int count = 0;
+
+ rewind(this->f);
+
+ while (fgets(line, sizeof(line), this->f))
+ {
+ /* valid entries start with hex encoded hash */
+ if (strchr("1234567890abcdefABCDEF", line[0]))
+ {
+ count++;
+ }
+ }
+ return count;
+}
+
+/**
+ * Add a new entry to the file
+ */
+static bool add_entry(private_coupling_validator_t *this, char *hash,
+ identification_t *id)
+{
+ return fseek(this->f, 0, SEEK_END) == 0 &&
+ fprintf(this->f, "%s %u '%Y'\n", hash, time(NULL), id) > 0;
+}
+
+METHOD(cert_validator_t, validate, bool,
+ private_coupling_validator_t *this,
+ certificate_t *subject, certificate_t *issuer,
+ bool online, u_int pathlen, bool anchor, auth_cfg_t *auth)
+{
+ bool valid = FALSE;
+ char hash[MAX_HASH_SIZE];
+
+ if (pathlen != 0)
+ {
+ return TRUE;
+ }
+ if (get_cert_hash(this, subject, hash))
+ {
+ this->mutex->lock(this->mutex);
+ if (has_entry(this, hash))
+ {
+ DBG1(DBG_CFG, "coupled certificate '%Y' found, accepted",
+ subject->get_subject(subject));
+ valid = TRUE;
+ }
+ else if (get_number_of_entries(this) < this->max_couplings)
+ {
+ if (add_entry(this, hash, subject->get_subject(subject)))
+ {
+ DBG1(DBG_CFG, "coupled new certificate '%Y'",
+ subject->get_subject(subject));
+ valid = TRUE;
+ }
+ else
+ {
+ DBG1(DBG_CFG, "coupling new certificate '%Y' failed",
+ subject->get_subject(subject));
+ }
+ }
+ else
+ {
+ DBG1(DBG_CFG, "coupling new certificate '%Y' failed, limit of %d "
+ "couplings reached", subject->get_subject(subject),
+ this->max_couplings);
+ }
+ this->mutex->unlock(this->mutex);
+ }
+ return valid;
+}
+
+METHOD(coupling_validator_t, destroy, void,
+ private_coupling_validator_t *this)
+{
+ if (this->f)
+ {
+ fclose(this->f);
+ }
+ DESTROY_IF(this->hasher);
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/**
+ * See header
+ */
+coupling_validator_t *coupling_validator_create()
+{
+ private_coupling_validator_t *this;
+ char *path, *hash;
+ int i;
+ struct {
+ hash_algorithm_t alg;
+ char *name;
+ } hash_types[] = {
+ { HASH_MD5, "md5"},
+ { HASH_SHA1, "sha1"},
+ { HASH_SHA256, "sha256"},
+ { HASH_SHA384, "sha384"},
+ { HASH_SHA512, "sha512"},
+ };
+
+ INIT(this,
+ .public = {
+ .validator = {
+ .validate = _validate,
+ },
+ .destroy = _destroy,
+ },
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .max_couplings = lib->settings->get_int(lib->settings,
+ "charon.plugins.coupling.max", 1),
+ );
+
+ hash = lib->settings->get_str(lib->settings,
+ "charon.plugins.coupling.hash", "sha1");
+ for (i = 0; i < countof(hash_types); i++)
+ {
+ if (strcaseeq(hash_types[i].name, hash))
+ {
+ this->hasher = lib->crypto->create_hasher(lib->crypto,
+ hash_types[i].alg);
+ break;
+ }
+ }
+ if (!this->hasher)
+ {
+ DBG1(DBG_CFG, "unsupported coupling hash algorithm: %s", hash);
+ destroy(this);
+ return NULL;
+ }
+
+ path = lib->settings->get_str(lib->settings,
+ "charon.plugins.coupling.file", NULL);
+ if (!path)
+ {
+ DBG1(DBG_CFG, "coupling file path unspecified");
+ destroy(this);
+ return NULL;
+ }
+ this->f = fopen(path, "a+");
+ if (!this->f)
+ {
+ DBG1(DBG_CFG, "opening coupling file '%s' failed: %s",
+ path, strerror(errno));
+ destroy(this);
+ return NULL;
+ }
+ setlinebuf(this->f);
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/coupling/coupling_validator.h b/src/libcharon/plugins/coupling/coupling_validator.h
new file mode 100644
index 000000000..d6b4d3718
--- /dev/null
+++ b/src/libcharon/plugins/coupling/coupling_validator.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 coupling_validator coupling_validator
+ * @{ @ingroup coupling
+ */
+
+#ifndef COUPLING_VALIDATOR_H_
+#define COUPLING_VALIDATOR_H_
+
+#include <credentials/cert_validator.h>
+
+typedef struct coupling_validator_t coupling_validator_t;
+
+/**
+ * Validator that couples authenticated certificates permanently.
+ */
+struct coupling_validator_t {
+
+ /**
+ * Implements cert_validator_t interface.
+ */
+ cert_validator_t validator;
+
+ /**
+ * Destroy a coupling_validator_t.
+ */
+ void (*destroy)(coupling_validator_t *this);
+};
+
+/**
+ * Create a coupling_validator instance.
+ */
+coupling_validator_t *coupling_validator_create();
+
+#endif /** COUPLING_VALIDATOR_H_ @}*/
diff --git a/src/libcharon/plugins/dhcp/Makefile.in b/src/libcharon/plugins/dhcp/Makefile.in
index 8046fc052..7853659df 100644
--- a/src/libcharon/plugins/dhcp/Makefile.in
+++ b/src/libcharon/plugins/dhcp/Makefile.in
@@ -241,6 +241,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -264,6 +266,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/dhcp/dhcp_plugin.c b/src/libcharon/plugins/dhcp/dhcp_plugin.c
index fccc99ba5..f8782c2a4 100644
--- a/src/libcharon/plugins/dhcp/dhcp_plugin.c
+++ b/src/libcharon/plugins/dhcp/dhcp_plugin.c
@@ -44,6 +44,12 @@ struct private_dhcp_plugin_t {
dhcp_provider_t *provider;
};
+METHOD(plugin_t, get_name, char*,
+ private_dhcp_plugin_t *this)
+{
+ return "dhcp";
+}
+
METHOD(plugin_t, destroy, void,
private_dhcp_plugin_t *this)
{
@@ -64,6 +70,8 @@ plugin_t *dhcp_plugin_create()
INIT(this,
.public = {
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/dhcp/dhcp_socket.c b/src/libcharon/plugins/dhcp/dhcp_socket.c
index 8851c1b79..c98d50554 100644
--- a/src/libcharon/plugins/dhcp/dhcp_socket.c
+++ b/src/libcharon/plugins/dhcp/dhcp_socket.c
@@ -201,6 +201,9 @@ static int prepare_dhcp(private_dhcp_socket_t *this,
dhcp->transaction_id = transaction->get_id(transaction);
if (chunk_equals(broadcast, this->dst->get_address(this->dst)))
{
+ /* Set broadcast flag to get broadcasted replies, as we actually
+ * do not own the MAC we request an address for. */
+ dhcp->flags = htons(0x8000);
/* TODO: send with 0.0.0.0 source address */
}
else
diff --git a/src/libcharon/plugins/duplicheck/Makefile.am b/src/libcharon/plugins/duplicheck/Makefile.am
new file mode 100644
index 000000000..63c91dfab
--- /dev/null
+++ b/src/libcharon/plugins/duplicheck/Makefile.am
@@ -0,0 +1,21 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = -rdynamic \
+ -DIPSEC_PIDDIR=\"${piddir}\"
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-duplicheck.la
+else
+plugin_LTLIBRARIES = libstrongswan-duplicheck.la
+endif
+
+libstrongswan_duplicheck_la_SOURCES = duplicheck_plugin.h duplicheck_plugin.c \
+ duplicheck_listener.h duplicheck_listener.c \
+ duplicheck_notify.h duplicheck_notify.c
+
+libstrongswan_duplicheck_la_LDFLAGS = -module -avoid-version
+
+ipsec_PROGRAMS = duplicheck
+duplicheck_SOURCES = duplicheck.c
diff --git a/src/libcharon/plugins/duplicheck/Makefile.in b/src/libcharon/plugins/duplicheck/Makefile.in
new file mode 100644
index 000000000..8cffa2f10
--- /dev/null
+++ b/src/libcharon/plugins/duplicheck/Makefile.in
@@ -0,0 +1,668 @@
+# Makefile.in generated by automake 1.11.1 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.
+# 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+ipsec_PROGRAMS = duplicheck$(EXEEXT)
+subdir = src/libcharon/plugins/duplicheck
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.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
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(ipsecdir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+libstrongswan_duplicheck_la_LIBADD =
+am_libstrongswan_duplicheck_la_OBJECTS = duplicheck_plugin.lo \
+ duplicheck_listener.lo duplicheck_notify.lo
+libstrongswan_duplicheck_la_OBJECTS = \
+ $(am_libstrongswan_duplicheck_la_OBJECTS)
+libstrongswan_duplicheck_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_duplicheck_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_duplicheck_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_duplicheck_la_rpath =
+PROGRAMS = $(ipsec_PROGRAMS)
+am_duplicheck_OBJECTS = duplicheck.$(OBJEXT)
+duplicheck_OBJECTS = $(am_duplicheck_OBJECTS)
+duplicheck_LDADD = $(LDADD)
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+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)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_duplicheck_la_SOURCES) $(duplicheck_SOURCES)
+DIST_SOURCES = $(libstrongswan_duplicheck_la_SOURCES) \
+ $(duplicheck_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREADLIB = @PTHREADLIB@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+default_pkcs11 = @default_pkcs11@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
+libdir = @libdir@
+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@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+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
+
+AM_CFLAGS = -rdynamic \
+ -DIPSEC_PIDDIR=\"${piddir}\"
+
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-duplicheck.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-duplicheck.la
+libstrongswan_duplicheck_la_SOURCES = duplicheck_plugin.h duplicheck_plugin.c \
+ duplicheck_listener.h duplicheck_listener.c \
+ duplicheck_notify.h duplicheck_notify.c
+
+libstrongswan_duplicheck_la_LDFLAGS = -module -avoid-version
+duplicheck_SOURCES = duplicheck.c
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/duplicheck/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/duplicheck/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+ }
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstrongswan-duplicheck.la: $(libstrongswan_duplicheck_la_OBJECTS) $(libstrongswan_duplicheck_la_DEPENDENCIES)
+ $(libstrongswan_duplicheck_la_LINK) $(am_libstrongswan_duplicheck_la_rpath) $(libstrongswan_duplicheck_la_OBJECTS) $(libstrongswan_duplicheck_la_LIBADD) $(LIBS)
+install-ipsecPROGRAMS: $(ipsec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(ipsecdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsecdir)"
+ @list='$(ipsec_PROGRAMS)'; test -n "$(ipsecdir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(ipsecdir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(ipsecdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-ipsecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ipsec_PROGRAMS)'; test -n "$(ipsecdir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(ipsecdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(ipsecdir)" && rm -f $$files
+
+clean-ipsecPROGRAMS:
+ @list='$(ipsec_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+duplicheck$(EXEEXT): $(duplicheck_OBJECTS) $(duplicheck_DEPENDENCIES)
+ @rm -f duplicheck$(EXEEXT)
+ $(LINK) $(duplicheck_OBJECTS) $(duplicheck_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/duplicheck.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/duplicheck_listener.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/duplicheck_notify.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/duplicheck_plugin.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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(ipsecdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-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
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-ipsecPROGRAMS clean-libtool \
+ clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-ipsecPROGRAMS install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-ipsecPROGRAMS uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-ipsecPROGRAMS clean-libtool clean-noinstLTLIBRARIES \
+ clean-pluginLTLIBRARIES ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-ipsecPROGRAMS install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-ipsecPROGRAMS \
+ uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/duplicheck/duplicheck.c b/src/libcharon/plugins/duplicheck/duplicheck.c
new file mode 100644
index 000000000..99731a22b
--- /dev/null
+++ b/src/libcharon/plugins/duplicheck/duplicheck.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <errno.h>
+
+#define DUPLICHECK_SOCKET IPSEC_PIDDIR "/charon.dck"
+
+int main(int argc, char *argv[])
+{
+ struct sockaddr_un addr;
+ char buf[128];
+ int fd, len;
+
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path, DUPLICHECK_SOCKET);
+
+ fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+ if (fd < 0)
+ {
+ fprintf(stderr, "opening socket failed: %s\n", strerror(errno));
+ return 1;
+ }
+ if (connect(fd, (struct sockaddr *)&addr,
+ offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path)) < 0)
+ {
+ fprintf(stderr, "connecting to %s failed: %s\n",
+ DUPLICHECK_SOCKET, strerror(errno));
+ close(fd);
+ return 1;
+ }
+ while (1)
+ {
+ len = recv(fd, &buf, sizeof(buf) - 1, 0);
+ if (len < 0)
+ {
+ fprintf(stderr, "reading from socket failed: %s\n", strerror(errno));
+ close(fd);
+ return 1;
+ }
+ printf("%.*s\n", len, buf);
+ }
+}
diff --git a/src/libcharon/plugins/duplicheck/duplicheck_listener.c b/src/libcharon/plugins/duplicheck/duplicheck_listener.c
new file mode 100644
index 000000000..226b2bd4e
--- /dev/null
+++ b/src/libcharon/plugins/duplicheck/duplicheck_listener.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 "duplicheck_listener.h"
+
+#include <daemon.h>
+#include <threading/mutex.h>
+#include <utils/hashtable.h>
+#include <encoding/payloads/delete_payload.h>
+#include <processing/jobs/delete_ike_sa_job.h>
+
+typedef struct private_duplicheck_listener_t private_duplicheck_listener_t;
+
+/**
+ * Private data of an duplicheck_listener_t object.
+ */
+struct private_duplicheck_listener_t {
+
+ /**
+ * Public duplicheck_listener_t interface.
+ */
+ duplicheck_listener_t public;
+
+ /**
+ * Socket to send notifications to
+ */
+ duplicheck_notify_t *notify;
+
+ /**
+ * Mutex to lock hashtables
+ */
+ mutex_t *mutex;
+
+ /**
+ * Hashtable of active IKE_SAs, identification_t => entry_t
+ */
+ hashtable_t *active;
+
+ /**
+ * Hashtable with active liveness checks, identification_t => entry_t
+ */
+ hashtable_t *checking;
+};
+
+/**
+ * Entry for hashtables
+ */
+typedef struct {
+ /** peer identity */
+ identification_t *id;
+ /** IKE_SA identifier */
+ ike_sa_id_t *sa;
+} entry_t;
+
+/**
+ * Destroy a hashtable entry
+ */
+static void entry_destroy(entry_t *this)
+{
+ this->id->destroy(this->id);
+ this->sa->destroy(this->sa);
+ free(this);
+}
+
+/**
+ * Hashtable hash function
+ */
+static u_int hash(identification_t *key)
+{
+ return chunk_hash(key->get_encoding(key));
+}
+
+/**
+ * Hashtable equals function
+ */
+static bool equals(identification_t *a, identification_t *b)
+{
+ return a->equals(a, b);
+}
+
+METHOD(listener_t, ike_rekey, bool,
+ private_duplicheck_listener_t *this, ike_sa_t *old, ike_sa_t *new)
+{
+ identification_t *id;
+ ike_sa_id_t *sa;
+ entry_t *entry;
+
+ sa = new->get_id(new);
+ id = new->get_other_id(new);
+
+ INIT(entry,
+ .id = id->clone(id),
+ .sa = sa->clone(sa),
+ );
+ this->mutex->lock(this->mutex);
+ entry = this->active->put(this->active, entry->id, entry);
+ this->mutex->unlock(this->mutex);
+ if (entry)
+ {
+ entry_destroy(entry);
+ }
+ return TRUE;
+}
+
+METHOD(listener_t, ike_updown, bool,
+ private_duplicheck_listener_t *this, ike_sa_t *ike_sa, bool up)
+{
+ identification_t *id;
+ ike_sa_id_t *sa;
+ entry_t *entry;
+ job_t *job;
+
+ sa = ike_sa->get_id(ike_sa);
+ id = ike_sa->get_other_id(ike_sa);
+
+ if (up)
+ {
+ INIT(entry,
+ .id = id->clone(id),
+ .sa = sa->clone(sa),
+ );
+ this->mutex->lock(this->mutex);
+ entry = this->active->put(this->active, entry->id, entry);
+ this->mutex->unlock(this->mutex);
+ if (entry)
+ {
+ DBG1(DBG_CFG, "detected duplicate IKE_SA for '%Y', "
+ "triggering delete for old IKE_SA", id);
+ job = (job_t*)delete_ike_sa_job_create(entry->sa, TRUE);
+ this->mutex->lock(this->mutex);
+ entry = this->checking->put(this->checking, entry->id, entry);
+ this->mutex->unlock(this->mutex);
+ lib->processor->queue_job(lib->processor, job);
+ if (entry)
+ {
+ entry_destroy(entry);
+ }
+ }
+ }
+ else
+ {
+ this->mutex->lock(this->mutex);
+ entry = this->checking->remove(this->checking, id);
+ this->mutex->unlock(this->mutex);
+ if (entry)
+ {
+ DBG1(DBG_CFG, "delete for duplicate IKE_SA '%Y' timed out, "
+ "keeping new IKE_SA", id);
+ entry_destroy(entry);
+ }
+ else
+ {
+ this->mutex->lock(this->mutex);
+ entry = this->active->remove(this->active, id);
+ this->mutex->unlock(this->mutex);
+ if (entry)
+ {
+ entry_destroy(entry);
+ }
+ }
+ }
+ return TRUE;
+}
+
+METHOD(listener_t, message_hook, bool,
+ private_duplicheck_listener_t *this, ike_sa_t *ike_sa,
+ message_t *message, bool incoming)
+{
+ if (incoming && !message->get_request(message))
+ {
+ identification_t *id;
+ entry_t *entry;
+
+ id = ike_sa->get_other_id(ike_sa);
+ this->mutex->lock(this->mutex);
+ entry = this->checking->remove(this->checking, id);
+ this->mutex->unlock(this->mutex);
+ if (entry)
+ {
+ DBG1(DBG_CFG, "got a response on a duplicate IKE_SA for '%Y', "
+ "deleting new IKE_SA", id);
+ entry_destroy(entry);
+ this->mutex->lock(this->mutex);
+ entry = this->active->remove(this->active, id);
+ this->mutex->unlock(this->mutex);
+ if (entry)
+ {
+ lib->processor->queue_job(lib->processor,
+ (job_t*)delete_ike_sa_job_create(entry->sa, TRUE));
+ entry_destroy(entry);
+ }
+ this->notify->send(this->notify, id);
+ }
+ }
+ return TRUE;
+}
+
+METHOD(duplicheck_listener_t, destroy, void,
+ private_duplicheck_listener_t *this)
+{
+ enumerator_t *enumerator;
+ identification_t *key;
+ entry_t *value;
+
+ enumerator = this->active->create_enumerator(this->active);
+ while (enumerator->enumerate(enumerator, &key, &value))
+ {
+ entry_destroy(value);
+ }
+ enumerator->destroy(enumerator);
+
+ enumerator = this->checking->create_enumerator(this->checking);
+ while (enumerator->enumerate(enumerator, &key, &value))
+ {
+ entry_destroy(value);
+ }
+ enumerator->destroy(enumerator);
+
+ this->active->destroy(this->active);
+ this->checking->destroy(this->checking);
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/**
+ * See header
+ */
+duplicheck_listener_t *duplicheck_listener_create(duplicheck_notify_t *notify)
+{
+ private_duplicheck_listener_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .ike_rekey = _ike_rekey,
+ .ike_updown = _ike_updown,
+ .message = _message_hook,
+ },
+ .destroy = _destroy,
+ },
+ .notify = notify,
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .active = hashtable_create((hashtable_hash_t)hash,
+ (hashtable_equals_t)equals, 32),
+ .checking = hashtable_create((hashtable_hash_t)hash,
+ (hashtable_equals_t)equals, 2),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/duplicheck/duplicheck_listener.h b/src/libcharon/plugins/duplicheck/duplicheck_listener.h
new file mode 100644
index 000000000..7c575dd64
--- /dev/null
+++ b/src/libcharon/plugins/duplicheck/duplicheck_listener.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 duplicheck_listener duplicheck_listener
+ * @{ @ingroup duplicheck
+ */
+
+#ifndef DUPLICHECK_LISTENER_H_
+#define DUPLICHECK_LISTENER_H_
+
+#include "duplicheck_notify.h"
+
+#include <bus/listeners/listener.h>
+
+typedef struct duplicheck_listener_t duplicheck_listener_t;
+
+/**
+ * Listener checking for duplicates.
+ */
+struct duplicheck_listener_t {
+
+ /**
+ * Implements listener_t interface.
+ */
+ listener_t listener;
+
+ /**
+ * Destroy a duplicheck_listener_t.
+ */
+ void (*destroy)(duplicheck_listener_t *this);
+};
+
+/**
+ * Create a duplicheck_listener instance.
+ *
+ * @param notify socket to send notifications to
+ * @return listener
+ */
+duplicheck_listener_t *duplicheck_listener_create(duplicheck_notify_t *notify);
+
+#endif /** DUPLICHECK_LISTENER_H_ @}*/
diff --git a/src/libcharon/plugins/duplicheck/duplicheck_notify.c b/src/libcharon/plugins/duplicheck/duplicheck_notify.c
new file mode 100644
index 000000000..4e7618235
--- /dev/null
+++ b/src/libcharon/plugins/duplicheck/duplicheck_notify.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 "duplicheck_notify.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <daemon.h>
+#include <threading/mutex.h>
+#include <threading/thread.h>
+#include <utils/linked_list.h>
+#include <processing/jobs/callback_job.h>
+
+#define DUPLICHECK_SOCKET IPSEC_PIDDIR "/charon.dck"
+
+typedef struct private_duplicheck_notify_t private_duplicheck_notify_t;
+
+/**
+ * Private data of an duplicheck_notify_t object.
+ */
+struct private_duplicheck_notify_t {
+
+ /**
+ * Public duplicheck_notify_t interface.
+ */
+ duplicheck_notify_t public;
+
+ /**
+ * Callback job dispatching connections
+ */
+ callback_job_t *job;
+
+ /**
+ * Mutex to lock list
+ */
+ mutex_t *mutex;
+
+ /**
+ * List of connected sockets
+ */
+ linked_list_t *connected;
+
+ /**
+ * Socket dispatching connections
+ */
+ int socket;
+};
+
+/**
+ * Open duplicheck unix socket
+ */
+static bool open_socket(private_duplicheck_notify_t *this)
+{
+ struct sockaddr_un addr;
+ mode_t old;
+
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path, DUPLICHECK_SOCKET);
+
+ this->socket = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+ if (this->socket == -1)
+ {
+ DBG1(DBG_CFG, "creating duplicheck socket failed");
+ return FALSE;
+ }
+ unlink(addr.sun_path);
+ old = umask(~(S_IRWXU | S_IRWXG));
+ if (bind(this->socket, (struct sockaddr*)&addr, sizeof(addr)) < 0)
+ {
+ DBG1(DBG_CFG, "binding duplicheck socket failed: %s", strerror(errno));
+ close(this->socket);
+ return FALSE;
+ }
+ umask(old);
+ if (chown(addr.sun_path, charon->uid, charon->gid) != 0)
+ {
+ DBG1(DBG_CFG, "changing duplicheck socket permissions failed: %s",
+ strerror(errno));
+ }
+ if (listen(this->socket, 3) < 0)
+ {
+ DBG1(DBG_CFG, "listening on duplicheck socket failed: %s",
+ strerror(errno));
+ close(this->socket);
+ unlink(addr.sun_path);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Accept duplicheck notification connections
+ */
+static job_requeue_t receive(private_duplicheck_notify_t *this)
+{
+ struct sockaddr_un addr;
+ int len = sizeof(addr);
+ uintptr_t fd;
+ bool oldstate;
+
+ oldstate = thread_cancelability(TRUE);
+ fd = accept(this->socket, (struct sockaddr*)&addr, &len);
+ thread_cancelability(oldstate);
+
+ if (fd != -1)
+ {
+ this->mutex->lock(this->mutex);
+ this->connected->insert_last(this->connected, (void*)fd);
+ this->mutex->unlock(this->mutex);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "accepting duplicheck connection failed: %s",
+ strerror(errno));
+ }
+ return JOB_REQUEUE_FAIR;
+}
+
+METHOD(duplicheck_notify_t, send_, void,
+ private_duplicheck_notify_t *this, identification_t *id)
+{
+ char buf[128];
+ enumerator_t *enumerator;
+ uintptr_t fd;
+ int len;
+
+ len = snprintf(buf, sizeof(buf), "%Y", id);
+ if (len > 0 && len < sizeof(buf))
+ {
+ this->mutex->lock(this->mutex);
+ enumerator = this->connected->create_enumerator(this->connected);
+ while (enumerator->enumerate(enumerator, &fd))
+ {
+ if (send(fd, &buf, len + 1, 0) != len + 1)
+ {
+ DBG1(DBG_CFG, "sending duplicheck notify failed: %s",
+ strerror(errno));
+ this->connected->remove_at(this->connected, enumerator);
+ close(fd);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ }
+}
+
+METHOD(duplicheck_notify_t, destroy, void,
+ private_duplicheck_notify_t *this)
+{
+ enumerator_t *enumerator;
+ uintptr_t fd;
+
+ if (this->job)
+ {
+ this->job->cancel(this->job);
+ }
+ enumerator = this->connected->create_enumerator(this->connected);
+ while (enumerator->enumerate(enumerator, &fd))
+ {
+ close(fd);
+ }
+ enumerator->destroy(enumerator);
+ this->connected->destroy(this->connected);
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/**
+ * See header
+ */
+duplicheck_notify_t *duplicheck_notify_create()
+{
+ private_duplicheck_notify_t *this;
+
+ INIT(this,
+ .public = {
+ .send = _send_,
+ .destroy = _destroy,
+ },
+ .connected = linked_list_create(),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ );
+
+ if (!open_socket(this))
+ {
+ destroy(this);
+ return NULL;
+ }
+ this->job = callback_job_create((callback_job_cb_t)receive,
+ this, NULL, NULL);
+ lib->processor->queue_job(lib->processor, (job_t*)this->job);
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/duplicheck/duplicheck_notify.h b/src/libcharon/plugins/duplicheck/duplicheck_notify.h
new file mode 100644
index 000000000..43dd20cca
--- /dev/null
+++ b/src/libcharon/plugins/duplicheck/duplicheck_notify.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 duplicheck_notify duplicheck_notify
+ * @{ @ingroup duplicheck
+ */
+
+#ifndef DUPLICHECK_NOTIFY_H_
+#define DUPLICHECK_NOTIFY_H_
+
+#include <utils/identification.h>
+
+typedef struct duplicheck_notify_t duplicheck_notify_t;
+
+/**
+ * Sends notifications over a unix socket when duplicates are detected.
+ */
+struct duplicheck_notify_t {
+
+ /**
+ * Send a notification message if duplicate IKE_SA detected.
+ *
+ * @param id identity a duplicate tunnel has been detected
+ */
+ void (*send)(duplicheck_notify_t *this, identification_t *id);
+
+ /**
+ * Destroy a duplicheck_notify_t.
+ */
+ void (*destroy)(duplicheck_notify_t *this);
+};
+
+/**
+ * Create a duplicheck_notify instance.
+ */
+duplicheck_notify_t *duplicheck_notify_create();
+
+#endif /** DUPLICHECK_NOTIFY_H_ @}*/
diff --git a/src/libcharon/plugins/duplicheck/duplicheck_plugin.c b/src/libcharon/plugins/duplicheck/duplicheck_plugin.c
new file mode 100644
index 000000000..5bc1a14af
--- /dev/null
+++ b/src/libcharon/plugins/duplicheck/duplicheck_plugin.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 "duplicheck_plugin.h"
+
+#include "duplicheck_notify.h"
+#include "duplicheck_listener.h"
+
+#include <daemon.h>
+
+typedef struct private_duplicheck_plugin_t private_duplicheck_plugin_t;
+
+/**
+ * Private data of duplicheck plugin
+ */
+struct private_duplicheck_plugin_t {
+
+ /**
+ * Implements plugin interface
+ */
+ duplicheck_plugin_t public;
+
+ /**
+ * Listener doing duplicate checks
+ */
+ duplicheck_listener_t *listener;
+
+ /**
+ * Notification sender facility
+ */
+ duplicheck_notify_t *notify;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_duplicheck_plugin_t *this)
+{
+ return "duplicheck";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_duplicheck_plugin_t *this)
+{
+ charon->bus->remove_listener(charon->bus, &this->listener->listener);
+ this->notify->destroy(this->notify);
+ this->listener->destroy(this->listener);
+ free(this);
+}
+
+/**
+ * Plugin constructor
+ */
+plugin_t *duplicheck_plugin_create()
+{
+ private_duplicheck_plugin_t *this;
+
+ if (!lib->settings->get_bool(lib->settings,
+ "charon.plugins.duplicheck.enabled", TRUE))
+ {
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ .notify = duplicheck_notify_create(),
+ );
+
+ if (!this->notify)
+ {
+ free(this);
+ return NULL;
+ }
+ this->listener = duplicheck_listener_create(this->notify);
+ charon->bus->add_listener(charon->bus, &this->listener->listener);
+
+ return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/duplicheck/duplicheck_plugin.h b/src/libcharon/plugins/duplicheck/duplicheck_plugin.h
new file mode 100644
index 000000000..3dddf1494
--- /dev/null
+++ b/src/libcharon/plugins/duplicheck/duplicheck_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 duplicheck duplicheck
+ * @ingroup cplugins
+ *
+ * @defgroup duplicheck_plugin duplicheck_plugin
+ * @{ @ingroup duplicheck
+ */
+
+#ifndef DUPLICHECK_PLUGIN_H_
+#define DUPLICHECK_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct duplicheck_plugin_t duplicheck_plugin_t;
+
+/**
+ * Advanced duplicate checking using liveness checks.
+ */
+struct duplicheck_plugin_t {
+
+ /**
+ * Implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** DUPLICHECK_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/eap_aka/Makefile.in b/src/libcharon/plugins/eap_aka/Makefile.in
index 4a23f9010..666e22957 100644
--- a/src/libcharon/plugins/eap_aka/Makefile.in
+++ b/src/libcharon/plugins/eap_aka/Makefile.in
@@ -244,6 +244,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -267,6 +269,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/eap_aka/eap_aka_peer.c b/src/libcharon/plugins/eap_aka/eap_aka_peer.c
index dfcc69710..df0c4c5b4 100644
--- a/src/libcharon/plugins/eap_aka/eap_aka_peer.c
+++ b/src/libcharon/plugins/eap_aka/eap_aka_peer.c
@@ -54,6 +54,11 @@ struct private_eap_aka_peer_t {
identification_t *reauth;
/**
+ * EAP message identifier
+ */
+ u_int8_t identifier;
+
+ /**
* MSK
*/
chunk_t msk;
@@ -72,8 +77,7 @@ struct private_eap_aka_peer_t {
/**
* Create a AKA_CLIENT_ERROR: "Unable to process"
*/
-static eap_payload_t* create_client_error(private_eap_aka_peer_t *this,
- u_int8_t identifier)
+static eap_payload_t* create_client_error(private_eap_aka_peer_t *this)
{
simaka_message_t *message;
eap_payload_t *out;
@@ -82,7 +86,7 @@ static eap_payload_t* create_client_error(private_eap_aka_peer_t *this,
DBG1(DBG_IKE, "sending client error '%N'",
simaka_client_error_names, AKA_UNABLE_TO_PROCESS);
- message = simaka_message_create(FALSE, identifier, EAP_AKA,
+ message = simaka_message_create(FALSE, this->identifier, EAP_AKA,
AKA_CLIENT_ERROR, this->crypto);
encoded = htons(AKA_UNABLE_TO_PROCESS);
message->add_attribute(message, AT_CLIENT_ERROR_CODE,
@@ -124,7 +128,7 @@ static status_t process_identity(private_eap_aka_peer_t *this,
default:
if (!simaka_attribute_skippable(type))
{
- *out = create_client_error(this, in->get_identifier(in));
+ *out = create_client_error(this);
enumerator->destroy(enumerator);
return NEED_MORE;
}
@@ -159,7 +163,7 @@ static status_t process_identity(private_eap_aka_peer_t *this,
default:
break;
}
- message = simaka_message_create(FALSE, in->get_identifier(in), EAP_AKA,
+ message = simaka_message_create(FALSE, this->identifier, EAP_AKA,
AKA_IDENTITY, this->crypto);
if (id.len)
{
@@ -200,7 +204,7 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
default:
if (!simaka_attribute_skippable(type))
{
- *out = create_client_error(this, in->get_identifier(in));
+ *out = create_client_error(this);
enumerator->destroy(enumerator);
return NEED_MORE;
}
@@ -212,7 +216,7 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
if (!rand.len || !autn.len)
{
DBG1(DBG_IKE, "received invalid EAP-AKA challenge message");
- *out = create_client_error(this, in->get_identifier(in));
+ *out = create_client_error(this);
return NEED_MORE;
}
@@ -258,7 +262,7 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
* reading encrypted attributes */
if (!in->verify(in, chunk_empty) || !in->parse(in))
{
- *out = create_client_error(this, in->get_identifier(in));
+ *out = create_client_error(this);
return NEED_MORE;
}
@@ -285,7 +289,7 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
}
enumerator->destroy(enumerator);
- message = simaka_message_create(FALSE, in->get_identifier(in), EAP_AKA,
+ message = simaka_message_create(FALSE, this->identifier, EAP_AKA,
AKA_CHALLENGE, this->crypto);
message->add_attribute(message, AT_RES, chunk_create(res, res_len));
*out = message->generate(message, chunk_empty);
@@ -320,7 +324,7 @@ static status_t process_reauthentication(private_eap_aka_peer_t *this,
{
DBG1(DBG_IKE, "received %N, but not expected",
simaka_subtype_names, AKA_REAUTHENTICATION);
- *out = create_client_error(this, in->get_identifier(in));
+ *out = create_client_error(this);
return NEED_MORE;
}
@@ -330,7 +334,7 @@ static status_t process_reauthentication(private_eap_aka_peer_t *this,
/* verify MAC and parse again with decryption key */
if (!in->verify(in, chunk_empty) || !in->parse(in))
{
- *out = create_client_error(this, in->get_identifier(in));
+ *out = create_client_error(this);
return NEED_MORE;
}
@@ -351,7 +355,7 @@ static status_t process_reauthentication(private_eap_aka_peer_t *this,
default:
if (!simaka_attribute_skippable(type))
{
- *out = create_client_error(this, in->get_identifier(in));
+ *out = create_client_error(this);
enumerator->destroy(enumerator);
return NEED_MORE;
}
@@ -363,7 +367,7 @@ static status_t process_reauthentication(private_eap_aka_peer_t *this,
if (!nonce.len || !counter.len)
{
DBG1(DBG_IKE, "EAP-AKA/Request/Reauthentication message incomplete");
- *out = create_client_error(this, in->get_identifier(in));
+ *out = create_client_error(this);
return NEED_MORE;
}
@@ -440,38 +444,38 @@ static status_t process_notification(private_eap_aka_peer_t *this,
if (success)
{ /* empty notification reply */
- message = simaka_message_create(FALSE, in->get_identifier(in), EAP_AKA,
+ message = simaka_message_create(FALSE, this->identifier, EAP_AKA,
AKA_NOTIFICATION, this->crypto);
*out = message->generate(message, chunk_empty);
message->destroy(message);
}
else
{
- *out = create_client_error(this, in->get_identifier(in));
+ *out = create_client_error(this);
}
return NEED_MORE;
}
-/**
- * Implementation of eap_method_t.process
- */
-static status_t process(private_eap_aka_peer_t *this,
- eap_payload_t *in, eap_payload_t **out)
+METHOD(eap_method_t, process, status_t,
+ private_eap_aka_peer_t *this, eap_payload_t *in, eap_payload_t **out)
{
simaka_message_t *message;
status_t status;
+ /* store received EAP message identifier */
+ this->identifier = in->get_identifier(in);
+
message = simaka_message_create_from_payload(in, this->crypto);
if (!message)
{
- *out = create_client_error(this, in->get_identifier(in));
+ *out = create_client_error(this);
return NEED_MORE;
}
if (!message->parse(message))
{
message->destroy(message);
- *out = create_client_error(this, in->get_identifier(in));
+ *out = create_client_error(this);
return NEED_MORE;
}
switch (message->get_subtype(message))
@@ -491,7 +495,7 @@ static status_t process(private_eap_aka_peer_t *this,
default:
DBG1(DBG_IKE, "unable to process EAP-AKA subtype %N",
simaka_subtype_names, message->get_subtype(message));
- *out = create_client_error(this, in->get_identifier(in));
+ *out = create_client_error(this);
status = NEED_MORE;
break;
}
@@ -499,28 +503,22 @@ static status_t process(private_eap_aka_peer_t *this,
return status;
}
-/**
- * Implementation of eap_method_t.initiate
- */
-static status_t initiate(private_eap_aka_peer_t *this, eap_payload_t **out)
+METHOD(eap_method_t, initiate, status_t,
+ private_eap_aka_peer_t *this, eap_payload_t **out)
{
/* peer never initiates */
return FAILED;
}
-/**
- * Implementation of eap_method_t.get_type.
- */
-static eap_type_t get_type(private_eap_aka_peer_t *this, u_int32_t *vendor)
+METHOD(eap_method_t, get_type, eap_type_t,
+ private_eap_aka_peer_t *this, u_int32_t *vendor)
{
*vendor = 0;
return EAP_AKA;
}
-/**
- * Implementation of eap_method_t.get_msk.
- */
-static status_t get_msk(private_eap_aka_peer_t *this, chunk_t *msk)
+METHOD(eap_method_t, get_msk, status_t,
+ private_eap_aka_peer_t *this, chunk_t *msk)
{
if (this->msk.ptr)
{
@@ -530,18 +528,26 @@ static status_t get_msk(private_eap_aka_peer_t *this, chunk_t *msk)
return FAILED;
}
-/**
- * Implementation of eap_method_t.is_mutual.
- */
-static bool is_mutual(private_eap_aka_peer_t *this)
+METHOD(eap_method_t, get_identifier, u_int8_t,
+ private_eap_aka_peer_t *this)
+{
+ return this->identifier;
+}
+
+METHOD(eap_method_t, set_identifier, void,
+ private_eap_aka_peer_t *this, u_int8_t identifier)
+{
+ this->identifier = identifier;
+}
+
+METHOD(eap_method_t, is_mutual, bool,
+ private_eap_aka_peer_t *this)
{
return TRUE;
}
-/**
- * Implementation of eap_method_t.destroy.
- */
-static void destroy(private_eap_aka_peer_t *this)
+METHOD(eap_method_t, destroy, void,
+ private_eap_aka_peer_t *this)
{
this->crypto->destroy(this->crypto);
this->permanent->destroy(this->permanent);
@@ -557,25 +563,31 @@ static void destroy(private_eap_aka_peer_t *this)
eap_aka_peer_t *eap_aka_peer_create(identification_t *server,
identification_t *peer)
{
- private_eap_aka_peer_t *this = malloc_thing(private_eap_aka_peer_t);
-
- this->public.interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate;
- this->public.interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process;
- this->public.interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
- this->public.interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
- this->public.interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
- this->public.interface.destroy = (void(*)(eap_method_t*))destroy;
+ private_eap_aka_peer_t *this;
+
+ INIT(this,
+ .public = {
+ .interface = {
+ .initiate = _initiate,
+ .process = _process,
+ .get_type = _get_type,
+ .is_mutual = _is_mutual,
+ .get_msk = _get_msk,
+ .get_identifier = _get_identifier,
+ .set_identifier = _set_identifier,
+ .destroy = _destroy,
+ },
+ },
+ .crypto = simaka_crypto_create(),
+ );
- this->crypto = simaka_crypto_create();
if (!this->crypto)
{
free(this);
return NULL;
}
+
this->permanent = peer->clone(peer);
- this->pseudonym = NULL;
- this->reauth = NULL;
- this->msk = chunk_empty;
return &this->public;
}
diff --git a/src/libcharon/plugins/eap_aka/eap_aka_plugin.c b/src/libcharon/plugins/eap_aka/eap_aka_plugin.c
index f9283393a..394a14b59 100644
--- a/src/libcharon/plugins/eap_aka/eap_aka_plugin.c
+++ b/src/libcharon/plugins/eap_aka/eap_aka_plugin.c
@@ -20,10 +20,14 @@
#include <daemon.h>
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(eap_aka_plugin_t *this)
+METHOD(plugin_t, get_name, char*,
+ eap_aka_plugin_t *this)
+{
+ return "eap-aka";
+}
+
+METHOD(plugin_t, destroy, void,
+ eap_aka_plugin_t *this)
{
charon->eap->remove_method(charon->eap,
(eap_constructor_t)eap_aka_server_create);
@@ -37,9 +41,15 @@ static void destroy(eap_aka_plugin_t *this)
*/
plugin_t *eap_aka_plugin_create()
{
- eap_aka_plugin_t *this = malloc_thing(eap_aka_plugin_t);
-
- this->plugin.destroy = (void(*)(plugin_t*))destroy;
+ eap_aka_plugin_t *this;
+
+ INIT(this,
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ );
charon->eap->add_method(charon->eap, EAP_AKA, 0, EAP_SERVER,
(eap_constructor_t)eap_aka_server_create);
diff --git a/src/libcharon/plugins/eap_aka/eap_aka_server.c b/src/libcharon/plugins/eap_aka/eap_aka_server.c
index 9baff3e23..bf0020ad8 100644
--- a/src/libcharon/plugins/eap_aka/eap_aka_server.c
+++ b/src/libcharon/plugins/eap_aka/eap_aka_server.c
@@ -57,7 +57,7 @@ struct private_eap_aka_server_t {
identification_t *reauth;
/**
- * EAP identifier value
+ * EAP message identifier
*/
u_int8_t identifier;
@@ -251,10 +251,8 @@ static status_t reauthenticate(private_eap_aka_server_t *this,
return NEED_MORE;
}
-/**
- * Implementation of eap_method_t.initiate
- */
-static status_t initiate(private_eap_aka_server_t *this, eap_payload_t **out)
+METHOD(eap_method_t, initiate, status_t,
+ private_eap_aka_server_t *this, eap_payload_t **out)
{
if (this->use_permanent || this->use_pseudonym || this->use_reauth)
{
@@ -560,11 +558,8 @@ static status_t process_authentication_reject(private_eap_aka_server_t *this,
return FAILED;
}
-/**
- * Implementation of eap_method_t.process
- */
-static status_t process(private_eap_aka_server_t *this,
- eap_payload_t *in, eap_payload_t **out)
+METHOD(eap_method_t, process, status_t,
+ private_eap_aka_server_t *this, eap_payload_t *in, eap_payload_t **out)
{
simaka_message_t *message;
status_t status;
@@ -609,19 +604,15 @@ static status_t process(private_eap_aka_server_t *this,
return status;
}
-/**
- * Implementation of eap_method_t.get_type.
- */
-static eap_type_t get_type(private_eap_aka_server_t *this, u_int32_t *vendor)
+METHOD(eap_method_t, get_type, eap_type_t,
+ private_eap_aka_server_t *this, u_int32_t *vendor)
{
*vendor = 0;
return EAP_AKA;
}
-/**
- * Implementation of eap_method_t.get_msk.
- */
-static status_t get_msk(private_eap_aka_server_t *this, chunk_t *msk)
+METHOD(eap_method_t, get_msk, status_t,
+ private_eap_aka_server_t *this, chunk_t *msk)
{
if (this->msk.ptr)
{
@@ -631,18 +622,26 @@ static status_t get_msk(private_eap_aka_server_t *this, chunk_t *msk)
return FAILED;
}
-/**
- * Implementation of eap_method_t.is_mutual.
- */
-static bool is_mutual(private_eap_aka_server_t *this)
+METHOD(eap_method_t, get_identifier, u_int8_t,
+ private_eap_aka_server_t *this)
+{
+ return this->identifier;
+}
+
+METHOD(eap_method_t, set_identifier, void,
+ private_eap_aka_server_t *this, u_int8_t identifier)
+{
+ this->identifier = identifier;
+}
+
+METHOD(eap_method_t, is_mutual, bool,
+ private_eap_aka_server_t *this)
{
return TRUE;
}
-/**
- * Implementation of eap_method_t.destroy.
- */
-static void destroy(private_eap_aka_server_t *this)
+METHOD(eap_method_t, destroy, void,
+ private_eap_aka_server_t *this)
{
this->crypto->destroy(this->crypto);
this->permanent->destroy(this->permanent);
@@ -662,34 +661,35 @@ static void destroy(private_eap_aka_server_t *this)
eap_aka_server_t *eap_aka_server_create(identification_t *server,
identification_t *peer)
{
- private_eap_aka_server_t *this = malloc_thing(private_eap_aka_server_t);
-
- this->public.interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate;
- this->public.interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process;
- this->public.interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
- this->public.interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
- this->public.interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
- this->public.interface.destroy = (void(*)(eap_method_t*))destroy;
+ private_eap_aka_server_t *this;
+
+ INIT(this,
+ .public = {
+ .interface = {
+ .initiate = _initiate,
+ .process = _process,
+ .get_type = _get_type,
+ .is_mutual = _is_mutual,
+ .get_msk = _get_msk,
+ .get_identifier = _get_identifier,
+ .set_identifier = _set_identifier,
+ .destroy = _destroy,
+ },
+ },
+ .crypto = simaka_crypto_create(),
+ );
- this->crypto = simaka_crypto_create();
if (!this->crypto)
{
free(this);
return NULL;
}
+
this->permanent = peer->clone(peer);
- this->pseudonym = NULL;
- this->reauth = NULL;
- this->xres = chunk_empty;
- this->rand = chunk_empty;
- this->nonce = chunk_empty;
- this->msk = chunk_empty;
- this->counter = chunk_empty;
- this->pending = 0;
- this->synchronized = FALSE;
this->use_reauth = this->use_pseudonym = this->use_permanent =
lib->settings->get_bool(lib->settings,
"charon.plugins.eap-aka.request_identity", TRUE);
+
/* generate a non-zero identifier */
do {
this->identifier = random();
diff --git a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
index ad1ae1906..1fe86a2bb 100644
--- a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
+++ b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
@@ -245,6 +245,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -268,6 +270,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_plugin.c b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_plugin.c
index 626e83311..ef5f62e34 100644
--- a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_plugin.c
+++ b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_plugin.c
@@ -48,10 +48,14 @@ struct private_eap_aka_3gpp2_t {
eap_aka_3gpp2_functions_t *functions;
};
-/**
- * Implementation of eap_aka_3gpp2_t.destroy.
- */
-static void destroy(private_eap_aka_3gpp2_t *this)
+METHOD(plugin_t, get_name, char*,
+ private_eap_aka_3gpp2_t *this)
+{
+ return "eap-aka-3gpp2";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_eap_aka_3gpp2_t *this)
{
charon->sim->remove_card(charon->sim, &this->card->card);
charon->sim->remove_provider(charon->sim, &this->provider->provider);
@@ -66,11 +70,19 @@ static void destroy(private_eap_aka_3gpp2_t *this)
*/
plugin_t *eap_aka_3gpp2_plugin_create()
{
- private_eap_aka_3gpp2_t *this = malloc_thing(private_eap_aka_3gpp2_t);
+ private_eap_aka_3gpp2_t *this;
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ .functions = eap_aka_3gpp2_functions_create(),
+ );
- this->functions = eap_aka_3gpp2_functions_create();
if (!this->functions)
{
free(this);
diff --git a/src/libcharon/plugins/eap_gtc/Makefile.in b/src/libcharon/plugins/eap_gtc/Makefile.in
index 142a35e50..4f555a982 100644
--- a/src/libcharon/plugins/eap_gtc/Makefile.in
+++ b/src/libcharon/plugins/eap_gtc/Makefile.in
@@ -242,6 +242,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -265,6 +267,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/eap_gtc/eap_gtc.c b/src/libcharon/plugins/eap_gtc/eap_gtc.c
index f641ad13a..c3ab07de0 100644
--- a/src/libcharon/plugins/eap_gtc/eap_gtc.c
+++ b/src/libcharon/plugins/eap_gtc/eap_gtc.c
@@ -70,10 +70,8 @@ struct eap_gtc_header_t {
u_int8_t data[];
} __attribute__((__packed__));
-/**
- * Implementation of eap_method_t.initiate for the peer
- */
-static status_t initiate_peer(private_eap_gtc_t *this, eap_payload_t **out)
+METHOD(eap_method_t, initiate_peer, status_t,
+ private_eap_gtc_t *this, eap_payload_t **out)
{
/* peer never initiates */
return FAILED;
@@ -136,10 +134,8 @@ static bool authenticate(char *service, char *user, char *password)
return ret == PAM_SUCCESS;
}
-/**
- * Implementation of eap_method_t.initiate for the server
- */
-static status_t initiate_server(private_eap_gtc_t *this, eap_payload_t **out)
+METHOD(eap_method_t, initiate_server, status_t,
+ private_eap_gtc_t *this, eap_payload_t **out)
{
eap_gtc_header_t *req;
size_t len;
@@ -157,11 +153,8 @@ static status_t initiate_server(private_eap_gtc_t *this, eap_payload_t **out)
return NEED_MORE;
}
-/**
- * Implementation of eap_method_t.process for the peer
- */
-static status_t process_peer(private_eap_gtc_t *this,
- eap_payload_t *in, eap_payload_t **out)
+METHOD(eap_method_t, process_peer, status_t,
+ private_eap_gtc_t *this, eap_payload_t *in, eap_payload_t **out)
{
eap_gtc_header_t *res;
shared_key_t *shared;
@@ -181,10 +174,11 @@ static status_t process_peer(private_eap_gtc_t *this,
/* TODO: According to the draft we should "SASLprep" password, RFC4013. */
+ this->identifier = in->get_identifier(in);
res = alloca(sizeof(eap_gtc_header_t) + len);
res->length = htons(sizeof(eap_gtc_header_t) + len);
res->code = EAP_RESPONSE;
- res->identifier = in->get_identifier(in);
+ res->identifier = this->identifier;
res->type = EAP_GTC;
memcpy(res->data, key.ptr, len);
@@ -195,11 +189,8 @@ static status_t process_peer(private_eap_gtc_t *this,
return NEED_MORE;
}
-/**
- * Implementation of eap_method_t.process for the server
- */
-static status_t process_server(private_eap_gtc_t *this,
- eap_payload_t *in, eap_payload_t **out)
+METHOD(eap_method_t, process_server, status_t,
+ private_eap_gtc_t *this, eap_payload_t *in, eap_payload_t **out)
{
chunk_t data, encoding;
char *user, *password, *service, *pos;
@@ -236,35 +227,39 @@ static status_t process_server(private_eap_gtc_t *this,
return SUCCESS;
}
-/**
- * Implementation of eap_method_t.get_type.
- */
-static eap_type_t get_type(private_eap_gtc_t *this, u_int32_t *vendor)
+METHOD(eap_method_t, get_type, eap_type_t,
+ private_eap_gtc_t *this, u_int32_t *vendor)
{
*vendor = 0;
return EAP_GTC;
}
-/**
- * Implementation of eap_method_t.get_msk.
- */
-static status_t get_msk(private_eap_gtc_t *this, chunk_t *msk)
+METHOD(eap_method_t, get_msk, status_t,
+ private_eap_gtc_t *this, chunk_t *msk)
{
return FAILED;
}
-/**
- * Implementation of eap_method_t.is_mutual.
- */
-static bool is_mutual(private_eap_gtc_t *this)
+METHOD(eap_method_t, get_identifier, u_int8_t,
+ private_eap_gtc_t *this)
+{
+ return this->identifier;
+}
+
+METHOD(eap_method_t, set_identifier, void,
+ private_eap_gtc_t *this, u_int8_t identifier)
+{
+ this->identifier = identifier;
+}
+
+METHOD(eap_method_t, is_mutual, bool,
+ private_eap_gtc_t *this)
{
return FALSE;
}
-/**
- * Implementation of eap_method_t.destroy.
- */
-static void destroy(private_eap_gtc_t *this)
+METHOD(eap_method_t, destroy, void,
+ private_eap_gtc_t *this)
{
this->peer->destroy(this->peer);
this->server->destroy(this->server);
@@ -277,19 +272,22 @@ static void destroy(private_eap_gtc_t *this)
static private_eap_gtc_t *eap_gtc_create_generic(identification_t *server,
identification_t *peer)
{
- private_eap_gtc_t *this = malloc_thing(private_eap_gtc_t);
-
- this->public.eap_method_interface.initiate = NULL;
- this->public.eap_method_interface.process = NULL;
- this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
- this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
- this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
- this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
-
- /* private data */
- this->peer = peer->clone(peer);
- this->server = server->clone(server);
- this->identifier = 0;
+ private_eap_gtc_t *this;
+
+ INIT(this,
+ .public = {
+ .eap_method_interface = {
+ .get_type = _get_type,
+ .is_mutual = _is_mutual,
+ .get_msk = _get_msk,
+ .get_identifier = _get_identifier,
+ .set_identifier = _set_identifier,
+ .destroy = _destroy,
+ },
+ },
+ .peer = peer->clone(peer),
+ .server = server->clone(server),
+ );
return this;
}
@@ -301,8 +299,8 @@ eap_gtc_t *eap_gtc_create_server(identification_t *server, identification_t *pee
{
private_eap_gtc_t *this = eap_gtc_create_generic(server, peer);
- this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_server;
- this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_server;
+ this->public.eap_method_interface.initiate = _initiate_server;
+ this->public.eap_method_interface.process = _process_server;
/* generate a non-zero identifier */
do {
@@ -319,8 +317,8 @@ eap_gtc_t *eap_gtc_create_peer(identification_t *server, identification_t *peer)
{
private_eap_gtc_t *this = eap_gtc_create_generic(server, peer);
- this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_peer;
- this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_peer;
+ this->public.eap_method_interface.initiate = _initiate_peer;
+ this->public.eap_method_interface.process = _process_peer;
return &this->public;
}
diff --git a/src/libcharon/plugins/eap_gtc/eap_gtc_plugin.c b/src/libcharon/plugins/eap_gtc/eap_gtc_plugin.c
index 91ba84b3d..c40ce60eb 100644
--- a/src/libcharon/plugins/eap_gtc/eap_gtc_plugin.c
+++ b/src/libcharon/plugins/eap_gtc/eap_gtc_plugin.c
@@ -22,10 +22,14 @@
/* missing in cababilities.h */
#define CAP_AUDIT_WRITE 29
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(eap_gtc_plugin_t *this)
+METHOD(plugin_t, get_name, char*,
+ eap_gtc_plugin_t *this)
+{
+ return "eap-gtc";
+}
+
+METHOD(plugin_t, destroy, void,
+ eap_gtc_plugin_t *this)
{
charon->eap->remove_method(charon->eap,
(eap_constructor_t)eap_gtc_create_server);
@@ -39,9 +43,15 @@ static void destroy(eap_gtc_plugin_t *this)
*/
plugin_t *eap_gtc_plugin_create()
{
- eap_gtc_plugin_t *this = malloc_thing(eap_gtc_plugin_t);
+ eap_gtc_plugin_t *this;
- this->plugin.destroy = (void(*)(plugin_t*))destroy;
+ INIT(this,
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ );
/* required for PAM authentication */
charon->keep_cap(charon, CAP_AUDIT_WRITE);
diff --git a/src/libcharon/plugins/eap_identity/Makefile.in b/src/libcharon/plugins/eap_identity/Makefile.in
index 5c1e07ade..9dc4602ff 100644
--- a/src/libcharon/plugins/eap_identity/Makefile.in
+++ b/src/libcharon/plugins/eap_identity/Makefile.in
@@ -244,6 +244,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -267,6 +269,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/eap_identity/eap_identity.c b/src/libcharon/plugins/eap_identity/eap_identity.c
index 03066b2f8..6ecde065c 100644
--- a/src/libcharon/plugins/eap_identity/eap_identity.c
+++ b/src/libcharon/plugins/eap_identity/eap_identity.c
@@ -39,6 +39,11 @@ struct private_eap_identity_t {
* received identity chunk
*/
chunk_t identity;
+
+ /**
+ * EAP identifier
+ */
+ u_int8_t identifier;
};
typedef struct eap_identity_header_t eap_identity_header_t;
@@ -68,10 +73,13 @@ METHOD(eap_method_t, process_peer, status_t,
id = this->peer->get_encoding(this->peer);
len = sizeof(eap_identity_header_t) + id.len;
-
+ if (in)
+ {
+ this->identifier = in->get_identifier(in);
+ }
hdr = alloca(len);
hdr->code = EAP_RESPONSE;
- hdr->identifier = in ? in->get_identifier(in) : 0;
+ hdr->identifier = this->identifier;
hdr->length = htons(len);
hdr->type = EAP_IDENTITY;
memcpy(hdr->data, id.ptr, id.len);
@@ -106,7 +114,7 @@ METHOD(eap_method_t, initiate_server, status_t,
eap_identity_header_t hdr;
hdr.code = EAP_REQUEST;
- hdr.identifier = 0;
+ hdr.identifier = this->identifier;
hdr.length = htons(sizeof(eap_identity_header_t));
hdr.type = EAP_IDENTITY;
@@ -133,6 +141,18 @@ METHOD(eap_method_t, get_msk, status_t,
return FAILED;
}
+METHOD(eap_method_t, get_identifier, u_int8_t,
+ private_eap_identity_t *this)
+{
+ return this->identifier;
+}
+
+METHOD(eap_method_t, set_identifier, void,
+ private_eap_identity_t *this, u_int8_t identifier)
+{
+ this->identifier = identifier;
+}
+
METHOD(eap_method_t, is_mutual, bool,
private_eap_identity_t *this)
{
@@ -163,6 +183,8 @@ eap_identity_t *eap_identity_create_peer(identification_t *server,
.get_type = _get_type,
.is_mutual = _is_mutual,
.get_msk = _get_msk,
+ .get_identifier = _get_identifier,
+ .set_identifier = _set_identifier,
.destroy = _destroy,
},
},
@@ -189,6 +211,8 @@ eap_identity_t *eap_identity_create_server(identification_t *server,
.get_type = _get_type,
.is_mutual = _is_mutual,
.get_msk = _get_msk,
+ .get_identifier = _get_identifier,
+ .set_identifier = _set_identifier,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/eap_identity/eap_identity_plugin.c b/src/libcharon/plugins/eap_identity/eap_identity_plugin.c
index 079c27909..3297416b2 100644
--- a/src/libcharon/plugins/eap_identity/eap_identity_plugin.c
+++ b/src/libcharon/plugins/eap_identity/eap_identity_plugin.c
@@ -18,6 +18,12 @@
#include <daemon.h>
+METHOD(plugin_t, get_name, char*,
+ eap_identity_plugin_t *this)
+{
+ return "eap-identity";
+}
+
METHOD(plugin_t, destroy, void,
eap_identity_plugin_t *this)
{
@@ -37,6 +43,8 @@ plugin_t *eap_identity_plugin_create()
INIT(this,
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
);
diff --git a/src/libcharon/plugins/eap_md5/Makefile.in b/src/libcharon/plugins/eap_md5/Makefile.in
index 4e01d96cc..e828fbc3e 100644
--- a/src/libcharon/plugins/eap_md5/Makefile.in
+++ b/src/libcharon/plugins/eap_md5/Makefile.in
@@ -242,6 +242,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -265,6 +267,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/eap_md5/eap_md5.c b/src/libcharon/plugins/eap_md5/eap_md5.c
index f70754abb..b0a234527 100644
--- a/src/libcharon/plugins/eap_md5/eap_md5.c
+++ b/src/libcharon/plugins/eap_md5/eap_md5.c
@@ -147,12 +147,12 @@ METHOD(eap_method_t, process_peer, status_t,
this->identifier = in->get_identifier(in);
data = in->get_data(in);
- this->challenge = chunk_clone(chunk_skip(data, 6));
- if (data.len < 6 || this->challenge.len < *(data.ptr + 5))
+ if (data.len < 6 || data.ptr[5] + 6 > data.len)
{
DBG1(DBG_IKE, "received invalid EAP-MD5 message");
return FAILED;
}
+ this->challenge = chunk_clone(chunk_create(data.ptr + 6, data.ptr[5]));
if (hash_challenge(this, &response, this->peer, this->server) != SUCCESS)
{
return FAILED;
@@ -176,7 +176,9 @@ METHOD(eap_method_t, process_server, status_t,
chunk_t response, expected;
chunk_t data;
- if (this->identifier != in->get_identifier(in))
+ data = in->get_data(in);
+ if (this->identifier != in->get_identifier(in) ||
+ data.len < 6 || data.ptr[5] + 6 > data.len)
{
DBG1(DBG_IKE, "received invalid EAP-MD5 message");
return FAILED;
@@ -185,9 +187,7 @@ METHOD(eap_method_t, process_server, status_t,
{
return FAILED;
}
- data = in->get_data(in);
- response = chunk_skip(data, 6);
-
+ response = chunk_create(data.ptr + 6, data.ptr[5]);
if (response.len < expected.len ||
!memeq(response.ptr, expected.ptr, expected.len))
{
@@ -218,6 +218,18 @@ METHOD(eap_method_t, is_mutual, bool,
return FALSE;
}
+METHOD(eap_method_t, get_identifier, u_int8_t,
+ private_eap_md5_t *this)
+{
+ return this->identifier;
+}
+
+METHOD(eap_method_t, set_identifier, void,
+ private_eap_md5_t *this, u_int8_t identifier)
+{
+ this->identifier = identifier;
+}
+
METHOD(eap_method_t, destroy, void,
private_eap_md5_t *this)
{
@@ -242,6 +254,8 @@ eap_md5_t *eap_md5_create_server(identification_t *server, identification_t *pee
.get_type = _get_type,
.is_mutual = _is_mutual,
.get_msk = _get_msk,
+ .get_identifier = _get_identifier,
+ .set_identifier = _set_identifier,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/eap_md5/eap_md5_plugin.c b/src/libcharon/plugins/eap_md5/eap_md5_plugin.c
index 39a6f5731..fe5ae51bf 100644
--- a/src/libcharon/plugins/eap_md5/eap_md5_plugin.c
+++ b/src/libcharon/plugins/eap_md5/eap_md5_plugin.c
@@ -18,6 +18,12 @@
#include <daemon.h>
+METHOD(plugin_t, get_name, char*,
+ eap_md5_plugin_t *this)
+{
+ return "eap-md5";
+}
+
METHOD(plugin_t, destroy, void,
eap_md5_plugin_t *this)
{
@@ -37,6 +43,8 @@ plugin_t *eap_md5_plugin_create()
INIT(this,
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
);
diff --git a/src/libcharon/plugins/eap_mschapv2/Makefile.in b/src/libcharon/plugins/eap_mschapv2/Makefile.in
index 495ccf441..4986fdce3 100644
--- a/src/libcharon/plugins/eap_mschapv2/Makefile.in
+++ b/src/libcharon/plugins/eap_mschapv2/Makefile.in
@@ -244,6 +244,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -267,6 +269,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c
index 4f39c8608..1dd94f6fb 100644
--- a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c
+++ b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c
@@ -560,19 +560,15 @@ static void set_ms_length(eap_mschapv2_header_t *eap, u_int16_t len)
memcpy(&eap->ms_length, &len, sizeof(u_int16_t));
}
-/**
- * Implementation of eap_method_t.initiate for the peer
- */
-static status_t initiate_peer(private_eap_mschapv2_t *this, eap_payload_t **out)
+METHOD(eap_method_t, initiate_peer, status_t,
+ private_eap_mschapv2_t *this, eap_payload_t **out)
{
/* peer never initiates */
return FAILED;
}
-/**
- * Implementation of eap_method_t.initiate for the server
- */
-static status_t initiate_server(private_eap_mschapv2_t *this, eap_payload_t **out)
+METHOD(eap_method_t, initiate_server, status_t,
+ private_eap_mschapv2_t *this, eap_payload_t **out)
{
rng_t *rng;
eap_mschapv2_header_t *eap;
@@ -904,11 +900,8 @@ error:
return status;
}
-/**
- * Implementation of eap_method_t.process for the peer
- */
-static status_t process_peer(private_eap_mschapv2_t *this, eap_payload_t *in,
- eap_payload_t **out)
+METHOD(eap_method_t, process_peer, status_t,
+ private_eap_mschapv2_t *this, eap_payload_t *in, eap_payload_t **out)
{
chunk_t data;
eap_mschapv2_header_t *eap;
@@ -1091,11 +1084,8 @@ static status_t process_server_response(private_eap_mschapv2_t *this,
return process_server_retry(this, out);
}
-/**
- * Implementation of eap_method_t.process for the server
- */
-static status_t process_server(private_eap_mschapv2_t *this, eap_payload_t *in,
- eap_payload_t **out)
+METHOD(eap_method_t, process_server, status_t,
+ private_eap_mschapv2_t *this, eap_payload_t *in, eap_payload_t **out)
{
eap_mschapv2_header_t *eap;
chunk_t data;
@@ -1140,19 +1130,15 @@ static status_t process_server(private_eap_mschapv2_t *this, eap_payload_t *in,
return FAILED;
}
-/**
- * Implementation of eap_method_t.get_type.
- */
-static eap_type_t get_type(private_eap_mschapv2_t *this, u_int32_t *vendor)
+METHOD(eap_method_t, get_type, eap_type_t,
+ private_eap_mschapv2_t *this, u_int32_t *vendor)
{
*vendor = 0;
return EAP_MSCHAPV2;
}
-/**
- * Implementation of eap_method_t.get_msk.
- */
-static status_t get_msk(private_eap_mschapv2_t *this, chunk_t *msk)
+METHOD(eap_method_t, get_msk, status_t,
+ private_eap_mschapv2_t *this, chunk_t *msk)
{
if (this->msk.ptr)
{
@@ -1162,18 +1148,26 @@ static status_t get_msk(private_eap_mschapv2_t *this, chunk_t *msk)
return FAILED;
}
-/**
- * Implementation of eap_method_t.is_mutual.
- */
-static bool is_mutual(private_eap_mschapv2_t *this)
+METHOD(eap_method_t, get_identifier, u_int8_t,
+ private_eap_mschapv2_t *this)
+{
+ return this->identifier;
+}
+
+METHOD(eap_method_t, set_identifier, void,
+ private_eap_mschapv2_t *this, u_int8_t identifier)
+{
+ this->identifier = identifier;
+}
+
+METHOD(eap_method_t, is_mutual, bool,
+ private_eap_mschapv2_t *this)
{
return FALSE;
}
-/**
- * Implementation of eap_method_t.destroy.
- */
-static void destroy(private_eap_mschapv2_t *this)
+METHOD(eap_method_t, destroy, void,
+ private_eap_mschapv2_t *this)
{
this->peer->destroy(this->peer);
this->server->destroy(this->server);
@@ -1189,25 +1183,22 @@ static void destroy(private_eap_mschapv2_t *this)
*/
static private_eap_mschapv2_t *eap_mschapv2_create_generic(identification_t *server, identification_t *peer)
{
- private_eap_mschapv2_t *this = malloc_thing(private_eap_mschapv2_t);
-
- this->public.eap_method_interface.initiate = NULL;
- this->public.eap_method_interface.process = NULL;
- this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
- this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
- this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
- this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
-
- /* private data */
- this->peer = peer->clone(peer);
- this->server = server->clone(server);
- this->challenge = chunk_empty;
- this->nt_response = chunk_empty;
- this->auth_response = chunk_empty;
- this->msk = chunk_empty;
- this->identifier = 0;
- this->mschapv2id = 0;
- this->retries = 0;
+ private_eap_mschapv2_t *this;
+
+ INIT(this,
+ .public = {
+ .eap_method_interface = {
+ .get_type = _get_type,
+ .is_mutual = _is_mutual,
+ .get_msk = _get_msk,
+ .get_identifier = _get_identifier,
+ .set_identifier = _set_identifier,
+ .destroy = _destroy,
+ },
+ },
+ .peer = peer->clone(peer),
+ .server = server->clone(server),
+ );
return this;
}
@@ -1219,8 +1210,8 @@ eap_mschapv2_t *eap_mschapv2_create_server(identification_t *server, identificat
{
private_eap_mschapv2_t *this = eap_mschapv2_create_generic(server, peer);
- this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_server;
- this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*, eap_payload_t**))process_server;
+ this->public.eap_method_interface.initiate = _initiate_server;
+ this->public.eap_method_interface.process = _process_server;
/* generate a non-zero identifier */
do
@@ -1240,8 +1231,8 @@ eap_mschapv2_t *eap_mschapv2_create_peer(identification_t *server, identificatio
{
private_eap_mschapv2_t *this = eap_mschapv2_create_generic(server, peer);
- this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_peer;
- this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*, eap_payload_t**))process_peer;
+ this->public.eap_method_interface.initiate = _initiate_peer;
+ this->public.eap_method_interface.process = _process_peer;
return &this->public;
}
diff --git a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2_plugin.c b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2_plugin.c
index a7b41ddbf..e809b14b6 100644
--- a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2_plugin.c
+++ b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2_plugin.c
@@ -19,10 +19,14 @@
#include <daemon.h>
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(eap_mschapv2_plugin_t *this)
+METHOD(plugin_t, get_name, char*,
+ eap_mschapv2_plugin_t *this)
+{
+ return "eap-mschapv2";
+}
+
+METHOD(plugin_t, destroy, void,
+ eap_mschapv2_plugin_t *this)
{
charon->eap->remove_method(charon->eap,
(eap_constructor_t)eap_mschapv2_create_server);
@@ -36,9 +40,15 @@ static void destroy(eap_mschapv2_plugin_t *this)
*/
plugin_t *eap_mschapv2_plugin_create()
{
- eap_mschapv2_plugin_t *this = malloc_thing(eap_mschapv2_plugin_t);
-
- this->plugin.destroy = (void(*)(plugin_t*))destroy;
+ eap_mschapv2_plugin_t *this;
+
+ INIT(this,
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ );
charon->eap->add_method(charon->eap, EAP_MSCHAPV2, 0, EAP_SERVER,
(eap_constructor_t)eap_mschapv2_create_server);
diff --git a/src/libcharon/plugins/eap_peap/Makefile.am b/src/libcharon/plugins/eap_peap/Makefile.am
new file mode 100644
index 000000000..81f2575c7
--- /dev/null
+++ b/src/libcharon/plugins/eap_peap/Makefile.am
@@ -0,0 +1,21 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls
+
+AM_CFLAGS = -rdynamic
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-eap-peap.la
+else
+plugin_LTLIBRARIES = libstrongswan-eap-peap.la
+libstrongswan_eap_peap_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
+endif
+
+libstrongswan_eap_peap_la_SOURCES = \
+ eap_peap_plugin.h eap_peap_plugin.c \
+ eap_peap.h eap_peap.c \
+ eap_peap_peer.h eap_peap_peer.c \
+ eap_peap_server.h eap_peap_server.c \
+ eap_peap_avp.h eap_peap_avp.c
+
+libstrongswan_eap_peap_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/eap_peap/Makefile.in b/src/libcharon/plugins/eap_peap/Makefile.in
new file mode 100644
index 000000000..0ed4a3dcf
--- /dev/null
+++ b/src/libcharon/plugins/eap_peap/Makefile.in
@@ -0,0 +1,617 @@
+# Makefile.in generated by automake 1.11.1 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.
+# 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libcharon/plugins/eap_peap
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.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
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+@MONOLITHIC_FALSE@libstrongswan_eap_peap_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la
+am_libstrongswan_eap_peap_la_OBJECTS = eap_peap_plugin.lo eap_peap.lo \
+ eap_peap_peer.lo eap_peap_server.lo eap_peap_avp.lo
+libstrongswan_eap_peap_la_OBJECTS = \
+ $(am_libstrongswan_eap_peap_la_OBJECTS)
+libstrongswan_eap_peap_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_eap_peap_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_eap_peap_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_eap_peap_la_rpath =
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+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)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_eap_peap_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_eap_peap_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREADLIB = @PTHREADLIB@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+default_pkcs11 = @default_pkcs11@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
+libdir = @libdir@
+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@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+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/libtls
+
+AM_CFLAGS = -rdynamic
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-peap.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-peap.la
+@MONOLITHIC_FALSE@libstrongswan_eap_peap_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
+libstrongswan_eap_peap_la_SOURCES = \
+ eap_peap_plugin.h eap_peap_plugin.c \
+ eap_peap.h eap_peap.c \
+ eap_peap_peer.h eap_peap_peer.c \
+ eap_peap_server.h eap_peap_server.c \
+ eap_peap_avp.h eap_peap_avp.c
+
+libstrongswan_eap_peap_la_LDFLAGS = -module -avoid-version
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/eap_peap/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/eap_peap/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+ }
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstrongswan-eap-peap.la: $(libstrongswan_eap_peap_la_OBJECTS) $(libstrongswan_eap_peap_la_DEPENDENCIES)
+ $(libstrongswan_eap_peap_la_LINK) $(am_libstrongswan_eap_peap_la_rpath) $(libstrongswan_eap_peap_la_OBJECTS) $(libstrongswan_eap_peap_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_peap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_peap_avp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_peap_peer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_peap_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_peap_server.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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-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
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
+ ctags distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-pluginLTLIBRARIES install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/eap_peap/eap_peap.c b/src/libcharon/plugins/eap_peap/eap_peap.c
new file mode 100644
index 000000000..5bae0fa9b
--- /dev/null
+++ b/src/libcharon/plugins/eap_peap/eap_peap.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2010 Martin Willi, revosec AG
+ * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
+ *
+ * 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 "eap_peap.h"
+#include "eap_peap_peer.h"
+#include "eap_peap_server.h"
+
+#include <tls_eap.h>
+
+#include <daemon.h>
+#include <library.h>
+
+typedef struct private_eap_peap_t private_eap_peap_t;
+
+/**
+ * Private data of an eap_peap_t object.
+ */
+struct private_eap_peap_t {
+
+ /**
+ * Public interface.
+ */
+ eap_peap_t public;
+
+ /**
+ * TLS stack, wrapped by EAP helper
+ */
+ tls_eap_t *tls_eap;
+};
+
+/** Maximum number of EAP-PEAP messages/fragments allowed */
+#define MAX_MESSAGE_COUNT 32
+/** Default size of a EAP-PEAP fragment */
+#define MAX_FRAGMENT_LEN 1024
+
+METHOD(eap_method_t, initiate, status_t,
+ private_eap_peap_t *this, eap_payload_t **out)
+{
+ chunk_t data;
+
+ if (this->tls_eap->initiate(this->tls_eap, &data) == NEED_MORE)
+ {
+ *out = eap_payload_create_data(data);
+ free(data.ptr);
+ return NEED_MORE;
+ }
+ return FAILED;
+}
+
+METHOD(eap_method_t, process, status_t,
+ private_eap_peap_t *this, eap_payload_t *in, eap_payload_t **out)
+{
+ status_t status;
+ chunk_t data;
+
+ data = in->get_data(in);
+ status = this->tls_eap->process(this->tls_eap, data, &data);
+ if (status == NEED_MORE)
+ {
+ *out = eap_payload_create_data(data);
+ free(data.ptr);
+ }
+ return status;
+}
+
+METHOD(eap_method_t, get_type, eap_type_t,
+ private_eap_peap_t *this, u_int32_t *vendor)
+{
+ *vendor = 0;
+ return EAP_PEAP;
+}
+
+METHOD(eap_method_t, get_msk, status_t,
+ private_eap_peap_t *this, chunk_t *msk)
+{
+ *msk = this->tls_eap->get_msk(this->tls_eap);
+ if (msk->len)
+ {
+ return SUCCESS;
+ }
+ return FAILED;
+}
+
+METHOD(eap_method_t, get_identifier, u_int8_t,
+ private_eap_peap_t *this)
+{
+ return this->tls_eap->get_identifier(this->tls_eap);
+}
+
+METHOD(eap_method_t, set_identifier, void,
+ private_eap_peap_t *this, u_int8_t identifier)
+{
+ this->tls_eap->set_identifier(this->tls_eap, identifier);
+}
+
+METHOD(eap_method_t, is_mutual, bool,
+ private_eap_peap_t *this)
+{
+ return TRUE;
+}
+
+METHOD(eap_method_t, destroy, void,
+ private_eap_peap_t *this)
+{
+ this->tls_eap->destroy(this->tls_eap);
+ free(this);
+}
+
+/**
+ * Create an empty private eap_peap_t object
+ */
+static private_eap_peap_t *eap_peap_create_empty(void)
+{
+ private_eap_peap_t *this;
+
+ INIT(this,
+ .public = {
+ .eap_method = {
+ .initiate = _initiate,
+ .process = _process,
+ .get_type = _get_type,
+ .is_mutual = _is_mutual,
+ .get_msk = _get_msk,
+ .get_identifier = _get_identifier,
+ .set_identifier = _set_identifier,
+ .destroy = _destroy,
+ },
+ },
+ );
+ return this;
+}
+
+/**
+ * Generic private constructor
+ */
+static eap_peap_t *eap_peap_create(private_eap_peap_t * this,
+ identification_t *server,
+ identification_t *peer, bool is_server,
+ tls_application_t *application)
+{
+ size_t frag_size;
+ int max_msg_count;
+ bool include_length;
+ tls_t *tls;
+
+ if (is_server && !lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap-peap.request_peer_auth", FALSE))
+ {
+ peer = NULL;
+ }
+ frag_size = lib->settings->get_int(lib->settings,
+ "charon.plugins.eap-peap.fragment_size", MAX_FRAGMENT_LEN);
+ max_msg_count = lib->settings->get_int(lib->settings,
+ "charon.plugins.eap-peap.max_message_count", MAX_MESSAGE_COUNT);
+ include_length = lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap-peap.include_length", FALSE);
+ tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_PEAP, application);
+ this->tls_eap = tls_eap_create(EAP_PEAP, tls, frag_size, max_msg_count,
+ include_length);
+ if (!this->tls_eap)
+ {
+ application->destroy(application);
+ free(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+eap_peap_t *eap_peap_create_server(identification_t *server,
+ identification_t *peer)
+{
+ private_eap_peap_t *eap_peap;
+ eap_method_t *eap_method;
+ eap_peap_server_t *eap_peap_server;
+ tls_application_t *application;
+
+ /* the tunneled application needs a reference to the outer EAP-PEAP method */
+ eap_peap = eap_peap_create_empty();
+ eap_method = &eap_peap->public.eap_method;
+ eap_peap_server = eap_peap_server_create(server, peer, eap_method);
+ application = &eap_peap_server->application;
+
+ return eap_peap_create(eap_peap, server, peer, TRUE, application);
+}
+
+eap_peap_t *eap_peap_create_peer(identification_t *server,
+ identification_t *peer)
+{
+ private_eap_peap_t *eap_peap;
+ eap_method_t *eap_method;
+ eap_peap_peer_t *eap_peap_peer;
+ tls_application_t *application;
+
+ /* the tunneled application needs a reference to the outer EAP-PEAP method */
+ eap_peap = eap_peap_create_empty();
+ eap_method = &eap_peap->public.eap_method;
+ eap_peap_peer = eap_peap_peer_create(server, peer, eap_method);
+ application = &eap_peap_peer->application;
+
+ return eap_peap_create(eap_peap, server, peer, FALSE, application);
+}
diff --git a/src/libcharon/plugins/eap_peap/eap_peap.h b/src/libcharon/plugins/eap_peap/eap_peap.h
new file mode 100644
index 000000000..f47bad561
--- /dev/null
+++ b/src/libcharon/plugins/eap_peap/eap_peap.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011 HSR Hochschule fuer Technik Rapperswil
+ *
+ * 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 eap_peap_i eap_peap
+ * @{ @ingroup eap_peap
+ */
+
+#ifndef EAP_PEAP_H_
+#define EAP_PEAP_H_
+
+typedef struct eap_peap_t eap_peap_t;
+
+#include <sa/authenticators/eap/eap_method.h>
+
+/**
+ * Implementation of eap_method_t using EAP-PEAP.
+ */
+struct eap_peap_t {
+
+ /**
+ * Implements eap_method_t interface.
+ */
+ eap_method_t eap_method;
+};
+
+/**
+ * Creates the EAP method EAP-PEAP acting as server.
+ *
+ * @param server ID of the EAP server
+ * @param peer ID of the EAP client
+ * @return eap_peap_t object
+ */
+eap_peap_t *eap_peap_create_server(identification_t *server,
+ identification_t *peer);
+
+/**
+ * Creates the EAP method EAP-PEAP acting as peer.
+ *
+ * @param server ID of the EAP server
+ * @param peer ID of the EAP client
+ * @return eap_peap_t object
+ */
+eap_peap_t *eap_peap_create_peer(identification_t *server,
+ identification_t *peer);
+
+#endif /** EAP_PEAP_H_ @}*/
diff --git a/src/libcharon/plugins/eap_peap/eap_peap_avp.c b/src/libcharon/plugins/eap_peap/eap_peap_avp.c
new file mode 100644
index 000000000..06e5222d9
--- /dev/null
+++ b/src/libcharon/plugins/eap_peap/eap_peap_avp.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011 HSR Hochschule fuer Technik Rapperswil
+ *
+ * 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 "eap_peap_avp.h"
+
+#include <eap/eap.h>
+#include <debug.h>
+
+/**
+ * Microsoft Success and Failure Result AVPs
+ */
+static const chunk_t MS_AVP_Success = chunk_from_chars(
+ 0x80, 0x03, 0x00, 0x02, 0x00, 0x01);
+static const chunk_t MS_AVP_Failure = chunk_from_chars(
+ 0x80, 0x03, 0x00, 0x02, 0x00, 0x02);
+
+typedef struct private_eap_peap_avp_t private_eap_peap_avp_t;
+
+/**
+ * Private data of an eap_peap_avp_t object.
+ */
+struct private_eap_peap_avp_t {
+
+ /**
+ * Public eap_peap_avp_t interface.
+ */
+ eap_peap_avp_t public;
+
+ /**
+ * EAP server or peer
+ */
+ bool is_server;
+};
+
+METHOD(eap_peap_avp_t, build, void,
+ private_eap_peap_avp_t *this, tls_writer_t *writer, chunk_t data)
+{
+ u_int8_t code;
+ eap_packet_t *pkt;
+ chunk_t avp_data;
+
+ pkt = (eap_packet_t*)data.ptr;
+
+ if (pkt->code == EAP_SUCCESS || pkt->code == EAP_FAILURE)
+ {
+ code = (this->is_server) ? EAP_REQUEST : EAP_RESPONSE;
+ writer->write_uint8(writer, code);
+ writer->write_uint8(writer, pkt->identifier);
+ writer->write_uint16(writer, 11);
+ writer->write_uint8(writer, EAP_MSTLV);
+ avp_data = (pkt->code == EAP_SUCCESS) ? MS_AVP_Success : MS_AVP_Failure;
+ }
+ else
+ {
+ avp_data = chunk_skip(data, 4);
+ }
+ writer->write_data(writer, avp_data);
+}
+
+METHOD(eap_peap_avp_t, process, status_t,
+ private_eap_peap_avp_t* this, tls_reader_t *reader, chunk_t *data,
+ u_int8_t identifier)
+{
+ u_int8_t code;
+ u_int16_t len;
+ eap_packet_t *pkt;
+ chunk_t avp_data;
+
+ code = (this->is_server) ? EAP_RESPONSE : EAP_REQUEST;
+ len = reader->remaining(reader);
+ if (!reader->read_data(reader, len, &avp_data))
+ {
+ return FAILED;
+ }
+ pkt = (eap_packet_t*)avp_data.ptr;
+
+ if (len > 4 && pkt->code == code && untoh16(&pkt->length) == len)
+ {
+ if (len == 5 && pkt->type == EAP_IDENTITY)
+ {
+ DBG2(DBG_IKE, "uncompressed EAP Identity request");
+ *data = chunk_clone(avp_data);
+ return SUCCESS;
+ }
+ else if (len == 11 && pkt->type == EAP_MSTLV)
+ {
+ if (memeq(&pkt->data, MS_AVP_Success.ptr, MS_AVP_Success.len))
+ {
+ DBG2(DBG_IKE, "MS Success Result AVP");
+ code = EAP_SUCCESS;
+ }
+ else if (memeq(&pkt->data, MS_AVP_Failure.ptr, MS_AVP_Failure.len))
+ {
+ DBG2(DBG_IKE, "MS Failure Result AVP");
+ code = EAP_FAILURE;
+ }
+ else
+ {
+ DBG1(DBG_IKE, "unknown MS AVP message");
+ return FAILED;
+ }
+ identifier = pkt->identifier;
+ len = 0;
+ }
+ }
+
+ *data = chunk_alloc(4 + len);
+ pkt = (eap_packet_t*)data->ptr;
+ pkt->code = code;
+ pkt->identifier = identifier;
+ htoun16(&pkt->length, data->len);
+ memcpy(data->ptr + 4, avp_data.ptr, len);
+
+ return SUCCESS;
+}
+
+METHOD(eap_peap_avp_t, destroy, void,
+ private_eap_peap_avp_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header
+ */
+eap_peap_avp_t *eap_peap_avp_create(bool is_server)
+{
+ private_eap_peap_avp_t *this;
+
+ INIT(this,
+ .public= {
+ .process = _process,
+ .build = _build,
+ .destroy = _destroy,
+ },
+ .is_server = is_server,
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/eap_peap/eap_peap_avp.h b/src/libcharon/plugins/eap_peap/eap_peap_avp.h
new file mode 100644
index 000000000..db22f0f8f
--- /dev/null
+++ b/src/libcharon/plugins/eap_peap/eap_peap_avp.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011 HSR Hochschule fuer Technik Rapperswil
+ *
+ * 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 eap_peap_avp eap_peap_avp
+ * @{ @ingroup eap_peap
+ */
+
+#ifndef EAP_PEAP_AVP_H_
+#define EAP_PEAP_AVP_H_
+
+typedef struct eap_peap_avp_t eap_peap_avp_t;
+
+#include <library.h>
+
+#include <tls_reader.h>
+#include <tls_writer.h>
+
+/**
+ * EAP-PEAP Attribute-Value Pair (AVP) handler.
+ */
+struct eap_peap_avp_t {
+
+ /**
+ * Process received EAP-PEAP Message AVP.
+ *
+ * @param reader TLS data buffer
+ * @param data received EAP Message
+ * @param identifier EAP-PEAP message identifier
+ * @return
+ * - SUCCESS if AVP processing succeeded
+ * - FAILED if AVP processing failed
+ * - NEED_MORE if another invocation of process/build needed
+ */
+ status_t (*process)(eap_peap_avp_t *this, tls_reader_t *reader,
+ chunk_t *data, u_int8_t identifier);
+
+ /**
+ * Build EAP-PEAP Message AVP to send out.
+ *
+ * @param writer TLS data buffer to write to
+ * @param data EAP Message to send
+ */
+ void (*build)(eap_peap_avp_t *this, tls_writer_t *writer, chunk_t data);
+
+ /**
+ * Destroy a eap_peap_application_t.
+ */
+ void (*destroy)(eap_peap_avp_t *this);
+};
+
+/**
+ * Create an eap_peap_avp instance.
+ *
+ * @param is_server TRUE iv eap server, FALSE if eap peer
+ */
+eap_peap_avp_t *eap_peap_avp_create(bool is_server);
+
+#endif /** EAP_PEAP_AVP_H_ @}*/
diff --git a/src/libcharon/plugins/eap_peap/eap_peap_peer.c b/src/libcharon/plugins/eap_peap/eap_peap_peer.c
new file mode 100644
index 000000000..ca2af4fee
--- /dev/null
+++ b/src/libcharon/plugins/eap_peap/eap_peap_peer.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011 HSR Hochschule fuer Technik Rapperswil
+ *
+ * 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 "eap_peap_peer.h"
+#include "eap_peap_avp.h"
+
+#include <debug.h>
+#include <daemon.h>
+
+typedef struct private_eap_peap_peer_t private_eap_peap_peer_t;
+
+/**
+ * Private data of an eap_peap_peer_t object.
+ */
+struct private_eap_peap_peer_t {
+
+ /**
+ * Public eap_peap_peer_t interface.
+ */
+ eap_peap_peer_t public;
+
+ /**
+ * Server identity
+ */
+ identification_t *server;
+
+ /**
+ * Peer identity
+ */
+ identification_t *peer;
+
+ /**
+ * Outer phase 1 EAP method
+ */
+ eap_method_t *ph1_method;
+
+ /**
+ * Current phase 2 EAP method
+ */
+ eap_method_t *ph2_method;
+
+ /**
+ * Pending outbound EAP message
+ */
+ eap_payload_t *out;
+
+ /**
+ * AVP handler
+ */
+ eap_peap_avp_t *avp;
+};
+
+METHOD(tls_application_t, process, status_t,
+ private_eap_peap_peer_t *this, tls_reader_t *reader)
+{
+ chunk_t data = chunk_empty;
+ status_t status;
+ payload_t *payload;
+ eap_payload_t *in;
+ eap_code_t code;
+ eap_type_t type, received_type;
+ u_int32_t vendor, received_vendor;
+
+ status = this->avp->process(this->avp, reader, &data,
+ this->ph1_method->get_identifier(this->ph1_method));
+ switch (status)
+ {
+ case SUCCESS:
+ break;
+ case NEED_MORE:
+ return NEED_MORE;
+ case FAILED:
+ default:
+ return FAILED;
+ }
+
+ in = eap_payload_create_data(data);
+ DBG3(DBG_IKE, "%B", &data);
+ chunk_free(&data);
+ payload = (payload_t*)in;
+
+ if (payload->verify(payload) != SUCCESS)
+ {
+ in->destroy(in);
+ return FAILED;
+ }
+
+ code = in->get_code(in);
+ if (code == EAP_REQUEST || code == EAP_RESPONSE)
+ {
+ received_type = in->get_type(in, &received_vendor);
+ DBG1(DBG_IKE, "received tunneled EAP-PEAP AVP [EAP/%N/%N]",
+ eap_code_short_names, code,
+ eap_type_short_names, received_type);
+ if (code != EAP_REQUEST)
+ {
+ DBG1(DBG_IKE, "%N expected", eap_code_names, EAP_REQUEST);
+ in->destroy(in);
+ return FAILED;
+ }
+ }
+ else
+ {
+ DBG1(DBG_IKE, "received tunneled EAP-PEAP AVP [EAP/%N]",
+ eap_code_short_names, code);
+ this->out = eap_payload_create_code(code, in->get_identifier(in));
+ in->destroy(in);
+ return NEED_MORE;
+ }
+
+ /* yet another phase2 authentication? */
+ if (this->ph2_method)
+ {
+ type = this->ph2_method->get_type(this->ph2_method, &vendor);
+
+ if (type != received_type || vendor != received_vendor)
+ {
+ this->ph2_method->destroy(this->ph2_method);
+ this->ph2_method = NULL;
+ }
+ }
+
+ if (this->ph2_method == NULL)
+ {
+ if (received_vendor)
+ {
+ DBG1(DBG_IKE, "server requested vendor specific EAP method %d-%d "
+ "(id 0x%02X", received_type, received_vendor,
+ in->get_identifier(in));
+ }
+ else
+ {
+ DBG1(DBG_IKE, "server requested %N authentication (id 0x%02X)",
+ eap_type_names, received_type, in->get_identifier(in));
+ }
+ this->ph2_method = charon->eap->create_instance(charon->eap,
+ received_type, received_vendor,
+ EAP_PEER, this->server, this->peer);
+ if (!this->ph2_method)
+ {
+ DBG1(DBG_IKE, "EAP method not supported");
+ this->out = eap_payload_create_nak(in->get_identifier(in));
+ in->destroy(in);
+ return NEED_MORE;
+ }
+ type = this->ph2_method->get_type(this->ph2_method, &vendor);
+ }
+
+ status = this->ph2_method->process(this->ph2_method, in, &this->out);
+ in->destroy(in);
+
+ switch (status)
+ {
+ case SUCCESS:
+ this->ph2_method->destroy(this->ph2_method);
+ this->ph2_method = NULL;
+ /* fall through to NEED_MORE */
+ case NEED_MORE:
+ return NEED_MORE;
+ case FAILED:
+ default:
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "vendor specific EAP method %d-%d failed",
+ type, vendor);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
+ }
+ return FAILED;
+ }
+}
+
+METHOD(tls_application_t, build, status_t,
+ private_eap_peap_peer_t *this, tls_writer_t *writer)
+{
+ chunk_t data;
+ eap_code_t code;
+ eap_type_t type;
+ u_int32_t vendor;
+
+ if (this->out)
+ {
+ code = this->out->get_code(this->out);
+ type = this->out->get_type(this->out, &vendor);
+ if (code == EAP_REQUEST || code == EAP_RESPONSE)
+ {
+ DBG1(DBG_IKE, "sending tunneled EAP-PEAP AVP [EAP/%N/%N]",
+ eap_code_short_names, code, eap_type_short_names, type);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "sending tunneled EAP-PEAP AVP [EAP/%N]",
+ eap_code_short_names, code);
+ }
+
+ /* get the raw EAP message data */
+ data = this->out->get_data(this->out);
+ DBG3(DBG_IKE, "%B", &data);
+ this->avp->build(this->avp, writer, data);
+
+ this->out->destroy(this->out);
+ this->out = NULL;
+ }
+ return INVALID_STATE;
+}
+
+METHOD(tls_application_t, destroy, void,
+ private_eap_peap_peer_t *this)
+{
+ this->server->destroy(this->server);
+ this->peer->destroy(this->peer);
+ DESTROY_IF(this->ph2_method);
+ DESTROY_IF(this->out);
+ this->avp->destroy(this->avp);
+ free(this);
+}
+
+/**
+ * See header
+ */
+eap_peap_peer_t *eap_peap_peer_create(identification_t *server,
+ identification_t *peer,
+ eap_method_t *eap_method)
+{
+ private_eap_peap_peer_t *this;
+
+ INIT(this,
+ .public = {
+ .application = {
+ .process = _process,
+ .build = _build,
+ .destroy = _destroy,
+ },
+ },
+ .server = server->clone(server),
+ .peer = peer->clone(peer),
+ .ph1_method = eap_method,
+ .avp = eap_peap_avp_create(FALSE),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/eap_peap/eap_peap_peer.h b/src/libcharon/plugins/eap_peap/eap_peap_peer.h
new file mode 100644
index 000000000..a87544209
--- /dev/null
+++ b/src/libcharon/plugins/eap_peap/eap_peap_peer.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011 HSR Hochschule fuer Technik Rapperswil
+ *
+ * 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 eap_peap_peer eap_peap_peer
+ * @{ @ingroup eap_peap
+ */
+
+#ifndef EAP_PEAP_PEER_H_
+#define EAP_PEAP_PEER_H_
+
+typedef struct eap_peap_peer_t eap_peap_peer_t;
+
+#include "tls_application.h"
+
+#include <library.h>
+#include <sa/authenticators/eap/eap_method.h>
+
+/**
+ * TLS application data handler as peer.
+ */
+struct eap_peap_peer_t {
+
+ /**
+ * Implements the TLS application data handler.
+ */
+ tls_application_t application;
+};
+
+/**
+ * Create an eap_peap_peer instance.
+ */
+eap_peap_peer_t *eap_peap_peer_create(identification_t *server,
+ identification_t *peer,
+ eap_method_t *eap_method);
+
+#endif /** EAP_PEAP_PEER_H_ @}*/
diff --git a/src/libcharon/plugins/eap_peap/eap_peap_plugin.c b/src/libcharon/plugins/eap_peap/eap_peap_plugin.c
new file mode 100644
index 000000000..bac5f2d3e
--- /dev/null
+++ b/src/libcharon/plugins/eap_peap/eap_peap_plugin.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011 HSR Hochschule fuer Technik Rapperswil
+ *
+ * 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 "eap_peap_plugin.h"
+
+#include "eap_peap.h"
+
+#include <daemon.h>
+
+METHOD(plugin_t, get_name, char*,
+ eap_peap_plugin_t *this)
+{
+ return "eap-peap";
+}
+
+METHOD(plugin_t, destroy, void,
+ eap_peap_plugin_t *this)
+{
+ charon->eap->remove_method(charon->eap,
+ (eap_constructor_t)eap_peap_create_server);
+ charon->eap->remove_method(charon->eap,
+ (eap_constructor_t)eap_peap_create_peer);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *eap_peap_plugin_create()
+{
+ eap_peap_plugin_t *this;
+
+ INIT(this,
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ );
+
+ charon->eap->add_method(charon->eap, EAP_PEAP, 0, EAP_SERVER,
+ (eap_constructor_t)eap_peap_create_server);
+ charon->eap->add_method(charon->eap, EAP_PEAP, 0, EAP_PEER,
+ (eap_constructor_t)eap_peap_create_peer);
+
+ return &this->plugin;
+}
diff --git a/src/libcharon/plugins/eap_peap/eap_peap_plugin.h b/src/libcharon/plugins/eap_peap/eap_peap_plugin.h
new file mode 100644
index 000000000..75bb504e1
--- /dev/null
+++ b/src/libcharon/plugins/eap_peap/eap_peap_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011 HSR Hochschule fuer Technik Rapperswil
+ *
+ * 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 eap_peap eap_peap
+ * @ingroup cplugins
+ *
+ * @defgroup eap_peap_plugin eap_peap_plugin
+ * @{ @ingroup eap_peap
+ */
+
+#ifndef EAP_PEAP_PLUGIN_H_
+#define EAP_PEAP_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct eap_peap_plugin_t eap_peap_plugin_t;
+
+/**
+ * EAP-PEAP plugin
+ */
+struct eap_peap_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a eap_peap_plugin instance.
+ */
+plugin_t *eap_peap_plugin_create();
+
+#endif /** EAP_PEAP_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/eap_peap/eap_peap_server.c b/src/libcharon/plugins/eap_peap/eap_peap_server.c
new file mode 100644
index 000000000..3fabc3575
--- /dev/null
+++ b/src/libcharon/plugins/eap_peap/eap_peap_server.c
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011 HSR Hochschule fuer Technik Rapperswil
+ *
+ * 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 "eap_peap_server.h"
+#include "eap_peap_avp.h"
+
+#include <debug.h>
+#include <daemon.h>
+
+typedef struct private_eap_peap_server_t private_eap_peap_server_t;
+
+/**
+ * Private data of an eap_peap_server_t object.
+ */
+struct private_eap_peap_server_t {
+
+ /**
+ * Public eap_peap_server_t interface.
+ */
+ eap_peap_server_t public;
+
+ /**
+ * Server identity
+ */
+ identification_t *server;
+
+ /**
+ * Peer identity
+ */
+ identification_t *peer;
+
+ /**
+ * Current EAP-PEAP phase2 state
+ */
+ bool start_phase2;
+
+ /**
+ * Current EAP-PEAP phase2 TNC state
+ */
+ bool start_phase2_tnc;
+
+ /**
+ * Starts phase 2 with EAP Identity request
+ */
+ bool start_phase2_id;
+
+ /**
+ * Final EAP-PEAP phase2 result
+ */
+ eap_code_t phase2_result;
+
+ /**
+ * Outer phase 1 EAP method
+ */
+ eap_method_t *ph1_method;
+
+ /**
+ * Current phase 2 EAP method
+ */
+ eap_method_t *ph2_method;
+
+ /**
+ * Pending outbound EAP message
+ */
+ eap_payload_t *out;
+
+ /**
+ * AVP handler
+ */
+ eap_peap_avp_t *avp;
+};
+
+/**
+ * Start EAP client authentication protocol
+ */
+static status_t start_phase2_auth(private_eap_peap_server_t *this)
+{
+ char *eap_type_str;
+ eap_type_t type;
+
+ eap_type_str = lib->settings->get_str(lib->settings,
+ "charon.plugins.eap-peap.phase2_method", "mschapv2");
+ type = eap_type_from_string(eap_type_str);
+ if (type == 0)
+ {
+ DBG1(DBG_IKE, "unrecognized phase2 method \"%s\"", eap_type_str);
+ return FAILED;
+ }
+ DBG1(DBG_IKE, "phase2 method %N selected", eap_type_names, type);
+ this->ph2_method = charon->eap->create_instance(charon->eap, type, 0,
+ EAP_SERVER, this->server, this->peer);
+ if (this->ph2_method == NULL)
+ {
+ DBG1(DBG_IKE, "%N method not available", eap_type_names, type);
+ return FAILED;
+ }
+
+ /* synchronize EAP message identifiers of inner protocol with outer */
+ this->ph2_method->set_identifier(this->ph2_method,
+ this->ph1_method->get_identifier(this->ph1_method) + 1);
+
+ if (this->ph2_method->initiate(this->ph2_method, &this->out) == NEED_MORE)
+ {
+ return NEED_MORE;
+ }
+ else
+ {
+ DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
+ return FAILED;
+ }
+}
+
+/**
+ * If configured, start EAP-TNC protocol
+ */
+static status_t start_phase2_tnc(private_eap_peap_server_t *this)
+{
+ if (this->start_phase2_tnc && lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap-peap.phase2_tnc", FALSE))
+ {
+ DBG1(DBG_IKE, "phase2 method %N selected", eap_type_names, EAP_TNC);
+ this->ph2_method = charon->eap->create_instance(charon->eap, EAP_TNC,
+ 0, EAP_SERVER, this->server, this->peer);
+ if (this->ph2_method == NULL)
+ {
+ DBG1(DBG_IKE, "%N method not available", eap_type_names, EAP_TNC);
+ return FAILED;
+ }
+ this->start_phase2_tnc = FALSE;
+
+ /* synchronize EAP message identifiers of inner protocol with outer */
+ this->ph2_method->set_identifier(this->ph2_method,
+ this->ph1_method->get_identifier(this->ph1_method) + 1);
+
+ if (this->ph2_method->initiate(this->ph2_method, &this->out) == NEED_MORE)
+ {
+ return NEED_MORE;
+ }
+ else
+ {
+ DBG1(DBG_IKE, "%N method failed", eap_type_names, EAP_TNC);
+ return FAILED;
+ }
+ }
+ return SUCCESS;
+}
+
+METHOD(tls_application_t, process, status_t,
+ private_eap_peap_server_t *this, tls_reader_t *reader)
+{
+ chunk_t data = chunk_empty;
+ status_t status;
+ payload_t *payload;
+ eap_payload_t *in;
+ eap_code_t code;
+ eap_type_t type = EAP_NAK, received_type;
+ u_int32_t vendor, received_vendor;
+
+ status = this->avp->process(this->avp, reader, &data,
+ this->ph1_method->get_identifier(this->ph1_method));
+ switch (status)
+ {
+ case SUCCESS:
+ break;
+ case NEED_MORE:
+ return NEED_MORE;
+ case FAILED:
+ default:
+ return FAILED;
+ }
+
+ in = eap_payload_create_data(data);
+ DBG3(DBG_IKE, "%B", &data);
+ chunk_free(&data);
+ payload = (payload_t*)in;
+
+ if (payload->verify(payload) != SUCCESS)
+ {
+ in->destroy(in);
+ return FAILED;
+ }
+
+ code = in->get_code(in);
+ if (code == EAP_REQUEST || code == EAP_RESPONSE)
+ {
+ received_type = in->get_type(in, &received_vendor);
+ DBG1(DBG_IKE, "received tunneled EAP-PEAP AVP [EAP/%N/%N]",
+ eap_code_short_names, code,
+ eap_type_short_names, received_type);
+ if (code != EAP_RESPONSE)
+ {
+ DBG1(DBG_IKE, "%N expected", eap_code_names, EAP_RESPONSE);
+ in->destroy(in);
+ return FAILED;
+ }
+ }
+ else
+ {
+ DBG1(DBG_IKE, "received tunneled EAP-PEAP AVP [EAP/%N]",
+ eap_code_short_names, code);
+
+ /* if EAP_SUCCESS check if to continue phase2 with EAP-TNC */
+ return (this->phase2_result == EAP_SUCCESS && code == EAP_SUCCESS) ?
+ start_phase2_tnc(this) : FAILED;
+ }
+
+ if (this->ph2_method)
+ {
+ type = this->ph2_method->get_type(this->ph2_method, &vendor);
+
+ if (type != received_type || vendor != received_vendor)
+ {
+ if (received_vendor == 0 && received_type == EAP_NAK)
+ {
+ DBG1(DBG_IKE, "peer does not support %N", eap_type_names, type);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "received invalid EAP response");
+ }
+ in->destroy(in);
+ return FAILED;
+ }
+ }
+
+ if (!received_vendor && received_type == EAP_IDENTITY)
+ {
+ chunk_t eap_id;
+
+ if (this->ph2_method == NULL)
+ {
+ /* Received an EAP Identity response without a matching request */
+ this->ph2_method = charon->eap->create_instance(charon->eap,
+ EAP_IDENTITY, 0, EAP_SERVER,
+ this->server, this->peer);
+ if (this->ph2_method == NULL)
+ {
+ DBG1(DBG_IKE, "%N method not available",
+ eap_type_names, EAP_IDENTITY);
+ return FAILED;
+ }
+ }
+
+ if (this->ph2_method->process(this->ph2_method, in, &this->out) != SUCCESS)
+ {
+
+ DBG1(DBG_IKE, "%N method failed", eap_type_names, EAP_IDENTITY);
+ return FAILED;
+ }
+
+ if (this->ph2_method->get_msk(this->ph2_method, &eap_id) == SUCCESS)
+ {
+ this->peer->destroy(this->peer);
+ this->peer = identification_create_from_data(eap_id);
+ DBG1(DBG_IKE, "received EAP identity '%Y'", this->peer);
+ }
+
+ in->destroy(in);
+ this->ph2_method->destroy(this->ph2_method);
+ this->ph2_method = NULL;
+
+ /* Start Phase 2 of EAP-PEAP authentication */
+ if (lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap-peap.request_peer_auth", FALSE))
+ {
+ return start_phase2_tnc(this);
+ }
+ else
+ {
+ return start_phase2_auth(this);
+ }
+ }
+
+ if (this->ph2_method == 0)
+ {
+ DBG1(DBG_IKE, "no %N phase2 method installed", eap_type_names, EAP_PEAP);
+ in->destroy(in);
+ return FAILED;
+ }
+
+ status = this->ph2_method->process(this->ph2_method, in, &this->out);
+ in->destroy(in);
+
+ switch (status)
+ {
+ case SUCCESS:
+ DBG1(DBG_IKE, "%N phase2 authentication of '%Y' with %N successful",
+ eap_type_names, EAP_PEAP, this->peer,
+ eap_type_names, type);
+ this->ph2_method->destroy(this->ph2_method);
+ this->ph2_method = NULL;
+
+ /* EAP-PEAP requires the sending of an inner EAP_SUCCESS message */
+ this->phase2_result = EAP_SUCCESS;
+ this->out = eap_payload_create_code(this->phase2_result, 1 +
+ this->ph1_method->get_identifier(this->ph1_method));
+ return NEED_MORE;
+ case NEED_MORE:
+ break;
+ case FAILED:
+ default:
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "vendor specific EAP method %d-%d failed",
+ type, vendor);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
+ }
+ /* EAP-PEAP requires the sending of an inner EAP_FAILURE message */
+ this->phase2_result = EAP_FAILURE;
+ this->out = eap_payload_create_code(this->phase2_result, 1 +
+ this->ph1_method->get_identifier(this->ph1_method));
+ return NEED_MORE;
+ }
+ return status;
+}
+
+METHOD(tls_application_t, build, status_t,
+ private_eap_peap_server_t *this, tls_writer_t *writer)
+{
+ chunk_t data;
+ eap_code_t code;
+ eap_type_t type;
+ u_int32_t vendor;
+
+ if (this->ph2_method == NULL && this->start_phase2 && this->start_phase2_id)
+ {
+ /*
+ * Start Phase 2 with an EAP Identity request either piggybacked right
+ * onto the TLS Finished payload or delayed after the reception of an
+ * empty EAP Acknowledge message.
+ */
+ this->ph2_method = charon->eap->create_instance(charon->eap, EAP_IDENTITY,
+ 0, EAP_SERVER, this->server, this->peer);
+ if (this->ph2_method == NULL)
+ {
+ DBG1(DBG_IKE, "%N method not available",
+ eap_type_names, EAP_IDENTITY);
+ return FAILED;
+ }
+
+ /* synchronize EAP message identifiers of inner protocol with outer */
+ this->ph2_method->set_identifier(this->ph2_method,
+ this->ph1_method->get_identifier(this->ph1_method));
+
+ this->ph2_method->initiate(this->ph2_method, &this->out);
+ this->start_phase2 = FALSE;
+ }
+
+ this->start_phase2_id = TRUE;
+
+ if (this->out)
+ {
+ code = this->out->get_code(this->out);
+ type = this->out->get_type(this->out, &vendor);
+ if (code == EAP_REQUEST || code == EAP_RESPONSE)
+ {
+ DBG1(DBG_IKE, "sending tunneled EAP-PEAP AVP [EAP/%N/%N]",
+ eap_code_short_names, code, eap_type_short_names, type);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "sending tunneled EAP-PEAP AVP [EAP/%N]",
+ eap_code_short_names, code);
+ }
+
+ /* get the raw EAP message data */
+ data = this->out->get_data(this->out);
+ DBG3(DBG_IKE, "%B", &data);
+ this->avp->build(this->avp, writer, data);
+
+ this->out->destroy(this->out);
+ this->out = NULL;
+ }
+ return INVALID_STATE;
+}
+
+METHOD(tls_application_t, destroy, void,
+ private_eap_peap_server_t *this)
+{
+ this->server->destroy(this->server);
+ this->peer->destroy(this->peer);
+ DESTROY_IF(this->ph2_method);
+ DESTROY_IF(this->out);
+ this->avp->destroy(this->avp);
+ free(this);
+}
+
+/**
+ * See header
+ */
+eap_peap_server_t *eap_peap_server_create(identification_t *server,
+ identification_t *peer,
+ eap_method_t *eap_method)
+{
+ private_eap_peap_server_t *this;
+
+ INIT(this,
+ .public = {
+ .application = {
+ .process = _process,
+ .build = _build,
+ .destroy = _destroy,
+ },
+ },
+ .server = server->clone(server),
+ .peer = peer->clone(peer),
+ .ph1_method = eap_method,
+ .start_phase2 = TRUE,
+ .start_phase2_tnc = TRUE,
+ .start_phase2_id = lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap-peap.phase2_piggyback", FALSE),
+ .phase2_result = EAP_FAILURE,
+ .avp = eap_peap_avp_create(TRUE),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/eap_peap/eap_peap_server.h b/src/libcharon/plugins/eap_peap/eap_peap_server.h
new file mode 100644
index 000000000..93141d62b
--- /dev/null
+++ b/src/libcharon/plugins/eap_peap/eap_peap_server.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011 HSR Hochschule fuer Technik Rapperswil
+ *
+ * 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 eap_peap_server eap_peap_server
+ * @{ @ingroup eap_peap
+ */
+
+#ifndef EAP_PEAP_SERVER_H_
+#define EAP_PEAP_SERVER_H_
+
+typedef struct eap_peap_server_t eap_peap_server_t;
+
+#include "tls_application.h"
+
+#include <library.h>
+#include <sa/authenticators/eap/eap_method.h>
+
+/**
+ * TLS application data handler as server.
+ */
+struct eap_peap_server_t {
+
+ /**
+ * Implements the TLS application data handler.
+ */
+ tls_application_t application;
+};
+
+/**
+ * Create an eap_peap_server instance.
+ */
+eap_peap_server_t *eap_peap_server_create(identification_t *server,
+ identification_t *peer,
+ eap_method_t *eap_method);
+
+#endif /** EAP_PEAP_SERVER_H_ @}*/
diff --git a/src/libcharon/plugins/eap_radius/Makefile.in b/src/libcharon/plugins/eap_radius/Makefile.in
index 99084e2c1..740c64055 100644
--- a/src/libcharon/plugins/eap_radius/Makefile.in
+++ b/src/libcharon/plugins/eap_radius/Makefile.in
@@ -245,6 +245,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -268,6 +270,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/eap_radius/eap_radius.c b/src/libcharon/plugins/eap_radius/eap_radius.c
index 157034fe5..dfe0e2e09 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius.c
@@ -55,6 +55,11 @@ struct private_eap_radius_t {
u_int32_t vendor;
/**
+ * EAP message identifier
+ */
+ u_int8_t identifier;
+
+ /**
* RADIUS client instance
*/
radius_client_t *client;
@@ -107,7 +112,7 @@ static void add_eap_identity(private_eap_radius_t *this,
hdr = alloca(len);
hdr->code = EAP_RESPONSE;
- hdr->identifier = 0;
+ hdr->identifier = this->identifier;
hdr->length = htons(len);
hdr->type = EAP_IDENTITY;
memcpy(hdr->data, prefix.ptr, prefix.len);
@@ -139,9 +144,12 @@ static bool radius2ike(private_eap_radius_t *this,
if (message.len)
{
*out = payload = eap_payload_create_data(message);
- free(message.ptr);
+
/* apply EAP method selected by RADIUS server */
this->type = payload->get_type(payload, &this->vendor);
+
+ DBG3(DBG_IKE, "%N payload %B", eap_type_names, this->type, &message);
+ free(message.ptr);
return TRUE;
}
return FALSE;
@@ -284,6 +292,8 @@ METHOD(eap_method_t, process, status_t,
request = radius_message_create_request();
request->add(request, RAT_USER_NAME, this->peer->get_encoding(this->peer));
data = in->get_data(in);
+ DBG3(DBG_IKE, "%N payload %B", eap_type_names, this->type, &data);
+
/* fragment data suitable for RADIUS (not more than 253 bytes) */
while (data.len > 253)
{
@@ -351,6 +361,18 @@ METHOD(eap_method_t, get_msk, status_t,
return FAILED;
}
+METHOD(eap_method_t, get_identifier, u_int8_t,
+ private_eap_radius_t *this)
+{
+ return this->identifier;
+}
+
+METHOD(eap_method_t, set_identifier, void,
+ private_eap_radius_t *this, u_int8_t identifier)
+{
+ this->identifier = identifier;
+}
+
METHOD(eap_method_t, is_mutual, bool,
private_eap_radius_t *this)
{
@@ -388,6 +410,8 @@ eap_radius_t *eap_radius_create(identification_t *server, identification_t *peer
.get_type = _get_type,
.is_mutual = _is_mutual,
.get_msk = _get_msk,
+ .get_identifier = _get_identifier,
+ .set_identifier = _set_identifier,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
index 1c24d77d5..c218bd48b 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
@@ -20,6 +20,7 @@
#include "radius_server.h"
#include <daemon.h>
+#include <threading/rwlock.h>
/**
* Default RADIUS server port, when not configured
@@ -42,6 +43,11 @@ struct private_eap_radius_plugin_t {
* List of RADIUS servers
*/
linked_list_t *servers;
+
+ /**
+ * Lock for server list
+ */
+ rwlock_t *lock;
};
/**
@@ -49,20 +55,10 @@ struct private_eap_radius_plugin_t {
*/
static private_eap_radius_plugin_t *instance = NULL;
-METHOD(plugin_t, destroy, void,
- private_eap_radius_plugin_t *this)
-{
- charon->eap->remove_method(charon->eap, (eap_constructor_t)eap_radius_create);
- this->servers->destroy_offset(this->servers,
- offsetof(radius_server_t, destroy));
- free(this);
- instance = NULL;
-}
-
/**
* Load RADIUS servers from configuration
*/
-static bool load_servers(private_eap_radius_plugin_t *this)
+static void load_servers(private_eap_radius_plugin_t *this)
{
enumerator_t *enumerator;
radius_server_t *server;
@@ -78,7 +74,7 @@ static bool load_servers(private_eap_radius_plugin_t *this)
if (!secret)
{
DBG1(DBG_CFG, "no RADUIS secret defined");
- return FALSE;
+ return;
}
nas_identifier = lib->settings->get_str(lib->settings,
"charon.plugins.eap-radius.nas_identifier", "strongSwan");
@@ -86,15 +82,15 @@ static bool load_servers(private_eap_radius_plugin_t *this)
"charon.plugins.eap-radius.port", RADIUS_PORT);
sockets = lib->settings->get_int(lib->settings,
"charon.plugins.eap-radius.sockets", 1);
- server = radius_server_create(address, port, nas_identifier,
+ server = radius_server_create(address, address, port, nas_identifier,
secret, sockets, 0);
if (!server)
{
DBG1(DBG_CFG, "no RADUIS server defined");
- return FALSE;
+ return;
}
this->servers->insert_last(this->servers, server);
- return TRUE;
+ return;
}
enumerator = lib->settings->create_section_enumerator(lib->settings,
@@ -124,7 +120,7 @@ static bool load_servers(private_eap_radius_plugin_t *this)
"charon.plugins.eap-radius.servers.%s.sockets", 1, section);
preference = lib->settings->get_int(lib->settings,
"charon.plugins.eap-radius.servers.%s.preference", 0, section);
- server = radius_server_create(address, port, nas_identifier,
+ server = radius_server_create(section, address, port, nas_identifier,
secret, sockets, preference);
if (!server)
{
@@ -135,14 +131,40 @@ static bool load_servers(private_eap_radius_plugin_t *this)
}
enumerator->destroy(enumerator);
- if (this->servers->get_count(this->servers) == 0)
- {
- DBG1(DBG_CFG, "no valid RADIUS server configuration found");
- return FALSE;
- }
+ DBG1(DBG_CFG, "loaded %d RADIUS server configuration%s",
+ this->servers->get_count(this->servers),
+ this->servers->get_count(this->servers) == 1 ? "" : "s");
+}
+
+METHOD(plugin_t, get_name, char*,
+ private_eap_radius_plugin_t *this)
+{
+ return "eap-radius";
+}
+
+METHOD(plugin_t, reload, bool,
+ private_eap_radius_plugin_t *this)
+{
+ this->lock->write_lock(this->lock);
+ this->servers->destroy_offset(this->servers,
+ offsetof(radius_server_t, destroy));
+ this->servers = linked_list_create();
+ load_servers(this);
+ this->lock->unlock(this->lock);
return TRUE;
}
+METHOD(plugin_t, destroy, void,
+ private_eap_radius_plugin_t *this)
+{
+ charon->eap->remove_method(charon->eap, (eap_constructor_t)eap_radius_create);
+ this->servers->destroy_offset(this->servers,
+ offsetof(radius_server_t, destroy));
+ this->lock->destroy(this->lock);
+ free(this);
+ instance = NULL;
+}
+
/*
* see header file
*/
@@ -153,17 +175,17 @@ plugin_t *eap_radius_plugin_create()
INIT(this,
.public = {
.plugin = {
+ .get_name = _get_name,
+ .reload = _reload,
.destroy = _destroy,
},
},
.servers = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
);
- if (!load_servers(this))
- {
- destroy(this);
- return NULL;
- }
+ load_servers(this);
+
charon->eap->add_method(charon->eap, EAP_RADIUS, 0,
EAP_SERVER, (eap_constructor_t)eap_radius_create);
@@ -179,7 +201,10 @@ enumerator_t *eap_radius_create_server_enumerator()
{
if (instance)
{
- return instance->servers->create_enumerator(instance->servers);
+ instance->lock->read_lock(instance->lock);
+ return enumerator_create_cleaner(
+ instance->servers->create_enumerator(instance->servers),
+ (void*)instance->lock->unlock, instance->lock);
}
return enumerator_create_empty();
}
diff --git a/src/libcharon/plugins/eap_radius/radius_client.c b/src/libcharon/plugins/eap_radius/radius_client.c
index 232b9135e..245308e59 100644
--- a/src/libcharon/plugins/eap_radius/radius_client.c
+++ b/src/libcharon/plugins/eap_radius/radius_client.c
@@ -98,13 +98,14 @@ METHOD(radius_client_t, request, radius_message_t*,
req->add(req, RAT_STATE, this->state);
}
socket = this->server->get_socket(this->server);
- DBG1(DBG_CFG, "sending RADIUS %N to %#H", radius_message_code_names,
- req->get_code(req), this->server->get_address(this->server));
+ DBG1(DBG_CFG, "sending RADIUS %N to server '%s'", radius_message_code_names,
+ req->get_code(req), this->server->get_name(this->server));
res = socket->request(socket, req);
if (res)
{
- DBG1(DBG_CFG, "received RADIUS %N from %#H", radius_message_code_names,
- res->get_code(res), this->server->get_address(this->server));
+ DBG1(DBG_CFG, "received RADIUS %N from server '%s'",
+ radius_message_code_names, res->get_code(res),
+ this->server->get_name(this->server));
save_state(this, res);
if (res->get_code(res) == RMC_ACCESS_ACCEPT)
{
@@ -128,6 +129,7 @@ METHOD(radius_client_t, get_msk, chunk_t,
METHOD(radius_client_t, destroy, void,
private_radius_client_t *this)
{
+ this->server->destroy(this->server);
chunk_clear(&this->msk);
free(this->state.ptr);
free(this);
@@ -159,15 +161,16 @@ radius_client_t *radius_client_create()
/* for two with equal preference, 50-50 chance */
(current == best && random() % 2 == 0))
{
- DBG2(DBG_CFG, "RADIUS server %H is candidate: %d",
- server->get_address(server), current);
+ DBG2(DBG_CFG, "RADIUS server '%s' is candidate: %d",
+ server->get_name(server), current);
best = current;
- this->server = server;
+ DESTROY_IF(this->server);
+ this->server = server->get_ref(server);
}
else
{
- DBG2(DBG_CFG, "RADIUS server %H skipped: %d",
- server->get_address(server), current);
+ DBG2(DBG_CFG, "RADIUS server '%s' skipped: %d",
+ server->get_name(server), current);
}
}
enumerator->destroy(enumerator);
diff --git a/src/libcharon/plugins/eap_radius/radius_server.c b/src/libcharon/plugins/eap_radius/radius_server.c
index f54b8b2cd..3baf39807 100644
--- a/src/libcharon/plugins/eap_radius/radius_server.c
+++ b/src/libcharon/plugins/eap_radius/radius_server.c
@@ -32,11 +32,6 @@ struct private_radius_server_t {
radius_server_t public;
/**
- * RADIUS server address
- */
- host_t *host;
-
- /**
* list of radius sockets, as radius_socket_t
*/
linked_list_t *sockets;
@@ -57,9 +52,9 @@ struct private_radius_server_t {
condvar_t *condvar;
/**
- * RADIUS secret
+ * Server name
*/
- chunk_t secret;
+ char *name;
/**
* NAS-Identifier
@@ -80,6 +75,11 @@ struct private_radius_server_t {
* Retry counter for unreachable servers
*/
int retry;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
};
METHOD(radius_server_t, get_socket, radius_socket_t*,
@@ -147,27 +147,37 @@ METHOD(radius_server_t, get_preference, int,
return pref;
}
-METHOD(radius_server_t, get_address, host_t*,
+METHOD(radius_server_t, get_name, char*,
+ private_radius_server_t *this)
+{
+ return this->name;
+}
+
+METHOD(radius_server_t, get_ref, radius_server_t*,
private_radius_server_t *this)
{
- return this->host;
+ ref_get(&this->ref);
+ return &this->public;
}
+
METHOD(radius_server_t, destroy, void,
private_radius_server_t *this)
{
- DESTROY_IF(this->host);
- this->mutex->destroy(this->mutex);
- this->condvar->destroy(this->condvar);
- this->sockets->destroy_offset(this->sockets,
- offsetof(radius_socket_t, destroy));
- free(this);
+ if (ref_put(&this->ref))
+ {
+ this->mutex->destroy(this->mutex);
+ this->condvar->destroy(this->condvar);
+ this->sockets->destroy_offset(this->sockets,
+ offsetof(radius_socket_t, destroy));
+ free(this);
+ }
}
/**
* See header
*/
-radius_server_t *radius_server_create(char *server, u_int16_t port,
+radius_server_t *radius_server_create(char *name, char *address, u_int16_t port,
char *nas_identifier, char *secret, int sockets, int preference)
{
private_radius_server_t *this;
@@ -179,7 +189,8 @@ radius_server_t *radius_server_create(char *server, u_int16_t port,
.put_socket = _put_socket,
.get_nas_identifier = _get_nas_identifier,
.get_preference = _get_preference,
- .get_address = _get_address,
+ .get_name = _get_name,
+ .get_ref = _get_ref,
.destroy = _destroy,
},
.reachable = TRUE,
@@ -188,18 +199,14 @@ radius_server_t *radius_server_create(char *server, u_int16_t port,
.sockets = linked_list_create(),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
.condvar = condvar_create(CONDVAR_TYPE_DEFAULT),
- .host = host_create_from_dns(server, 0, port),
+ .name = name,
.preference = preference,
+ .ref = 1,
);
- if (!this->host)
- {
- destroy(this);
- return NULL;
- }
while (sockets--)
{
- socket = radius_socket_create(this->host,
+ socket = radius_socket_create(address, port,
chunk_create(secret, strlen(secret)));
if (!socket)
{
diff --git a/src/libcharon/plugins/eap_radius/radius_server.h b/src/libcharon/plugins/eap_radius/radius_server.h
index ba4c94619..c59361c49 100644
--- a/src/libcharon/plugins/eap_radius/radius_server.h
+++ b/src/libcharon/plugins/eap_radius/radius_server.h
@@ -61,11 +61,18 @@ struct radius_server_t {
int (*get_preference)(radius_server_t *this);
/**
- * Get the address of the RADIUS server.
+ * Get the name of the RADIUS server.
*
- * @return address, internal data
+ * @return server name
*/
- host_t* (*get_address)(radius_server_t *this);
+ char* (*get_name)(radius_server_t *this);
+
+ /**
+ * Increase reference count of this server.
+ *
+ * @return this
+ */
+ radius_server_t* (*get_ref)(radius_server_t *this);
/**
* Destroy a radius_server_t.
@@ -76,14 +83,15 @@ struct radius_server_t {
/**
* Create a radius_server instance.
*
- * @param server server address
+ * @param name server name
+ * @param address server address
* @param port server port
* @param nas_identifier NAS-Identifier to use with this server
* @param secret secret to use with this server
* @param sockets number of sockets to create in pool
* @param preference preference boost for this server
*/
-radius_server_t *radius_server_create(char *server, u_int16_t port,
+radius_server_t *radius_server_create(char *name, char *address, u_int16_t port,
char *nas_identifier, char *secret, int sockets, int preference);
#endif /** RADIUS_SERVER_H_ @}*/
diff --git a/src/libcharon/plugins/eap_radius/radius_socket.c b/src/libcharon/plugins/eap_radius/radius_socket.c
index f46c27ede..b3229c288 100644
--- a/src/libcharon/plugins/eap_radius/radius_socket.c
+++ b/src/libcharon/plugins/eap_radius/radius_socket.c
@@ -49,6 +49,16 @@ struct private_radius_socket_t {
int fd;
/**
+ * Server address
+ */
+ char *address;
+
+ /**
+ * Server port
+ */
+ u_int16_t port;
+
+ /**
* current RADIUS identifier
*/
u_int8_t identifier;
@@ -74,6 +84,45 @@ struct private_radius_socket_t {
chunk_t secret;
};
+/**
+ * Check or establish RADIUS connection
+ */
+static bool check_connection(private_radius_socket_t *this)
+{
+ if (this->fd == -1)
+ {
+ host_t *server;
+
+ server = host_create_from_dns(this->address, AF_UNSPEC, this->port);
+ if (!server)
+ {
+ DBG1(DBG_CFG, "resolving RADIUS server address '%s' failed",
+ this->address);
+ return FALSE;
+ }
+ this->fd = socket(server->get_family(server), SOCK_DGRAM, IPPROTO_UDP);
+ if (this->fd == -1)
+ {
+ DBG1(DBG_CFG, "opening RADIUS socket for %#H failed: %s",
+ server, strerror(errno));
+ server->destroy(server);
+ return FALSE;
+ }
+ if (connect(this->fd, server->get_sockaddr(server),
+ *server->get_sockaddr_len(server)) < 0)
+ {
+ DBG1(DBG_CFG, "connecting RADIUS socket to %#H failed: %s",
+ server, strerror(errno));
+ server->destroy(server);
+ close(this->fd);
+ this->fd = -1;
+ return FALSE;
+ }
+ server->destroy(server);
+ }
+ return TRUE;
+}
+
METHOD(radius_socket_t, request, radius_message_t*,
private_radius_socket_t *this, radius_message_t *request)
{
@@ -85,6 +134,11 @@ METHOD(radius_socket_t, request, radius_message_t*,
/* sign the request */
request->sign(request, this->rng, this->signer);
+ if (!check_connection(this))
+ {
+ return NULL;
+ }
+
data = request->get_encoding(request);
/* timeout after 2, 3, 4, 5 seconds */
for (i = 2; i <= 5; i++)
@@ -257,14 +311,18 @@ METHOD(radius_socket_t, destroy, void,
DESTROY_IF(this->hasher);
DESTROY_IF(this->signer);
DESTROY_IF(this->rng);
- close(this->fd);
+ if (this->fd != -1)
+ {
+ close(this->fd);
+ }
free(this);
}
/**
* See header
*/
-radius_socket_t *radius_socket_create(host_t *host, chunk_t secret)
+radius_socket_t *radius_socket_create(char *address, u_int16_t port,
+ chunk_t secret)
{
private_radius_socket_t *this;
@@ -274,23 +332,11 @@ radius_socket_t *radius_socket_create(host_t *host, chunk_t secret)
.decrypt_msk = _decrypt_msk,
.destroy = _destroy,
},
+ .address = address,
+ .port = port,
+ .fd = -1,
);
- this->fd = socket(host->get_family(host), SOCK_DGRAM, IPPROTO_UDP);
- if (this->fd < 0)
- {
- DBG1(DBG_CFG, "opening RADIUS socket failed: %s", strerror(errno));
- free(this);
- return NULL;
- }
- if (connect(this->fd, host->get_sockaddr(host),
- *host->get_sockaddr_len(host)) < 0)
- {
- DBG1(DBG_CFG, "connecting RADIUS socket failed");
- close(this->fd);
- free(this);
- return NULL;
- }
this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
this->signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_MD5_128);
this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
diff --git a/src/libcharon/plugins/eap_radius/radius_socket.h b/src/libcharon/plugins/eap_radius/radius_socket.h
index fe8491a8f..2875008eb 100644
--- a/src/libcharon/plugins/eap_radius/radius_socket.h
+++ b/src/libcharon/plugins/eap_radius/radius_socket.h
@@ -34,7 +34,7 @@ struct radius_socket_t {
/**
* Send a RADIUS request, wait for response.
-
+ *
* The socket fills in RADIUS Message identifier, builds a
* Request-Authenticator and calculates the Message-Authenticator
* attribute.
@@ -66,9 +66,11 @@ struct radius_socket_t {
/**
* Create a radius_socket instance.
*
- * @param host RADIUS server address to connect to
+ * @param address server name
+ * @param port server port
* @param secret RADIUS secret
*/
-radius_socket_t *radius_socket_create(host_t *host, chunk_t secret);
+radius_socket_t *radius_socket_create(char *address, u_int16_t port,
+ chunk_t secret);
#endif /** RADIUS_SOCKET_H_ @}*/
diff --git a/src/libcharon/plugins/eap_sim/Makefile.in b/src/libcharon/plugins/eap_sim/Makefile.in
index 90f203f61..b9ab6656b 100644
--- a/src/libcharon/plugins/eap_sim/Makefile.in
+++ b/src/libcharon/plugins/eap_sim/Makefile.in
@@ -244,6 +244,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -267,6 +269,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/eap_sim/eap_sim_peer.c b/src/libcharon/plugins/eap_sim/eap_sim_peer.c
index a3506f4ba..083bf73a3 100644
--- a/src/libcharon/plugins/eap_sim/eap_sim_peer.c
+++ b/src/libcharon/plugins/eap_sim/eap_sim_peer.c
@@ -56,6 +56,11 @@ struct private_eap_sim_peer_t {
identification_t *reauth;
/**
+ * EAP message identifier
+ */
+ u_int8_t identifier;
+
+ /**
* EAP-SIM crypto helper
*/
simaka_crypto_t *crypto;
@@ -98,7 +103,7 @@ static chunk_t version = chunk_from_chars(0x00,0x01);
* Create a SIM_CLIENT_ERROR
*/
static eap_payload_t* create_client_error(private_eap_sim_peer_t *this,
- u_int8_t identifier, simaka_client_error_t code)
+ simaka_client_error_t code)
{
simaka_message_t *message;
eap_payload_t *out;
@@ -106,7 +111,7 @@ static eap_payload_t* create_client_error(private_eap_sim_peer_t *this,
DBG1(DBG_IKE, "sending client error '%N'", simaka_client_error_names, code);
- message = simaka_message_create(FALSE, identifier, EAP_SIM,
+ message = simaka_message_create(FALSE, this->identifier, EAP_SIM,
SIM_CLIENT_ERROR, this->crypto);
encoded = htons(code);
message->add_attribute(message, AT_CLIENT_ERROR_CODE,
@@ -164,8 +169,7 @@ static status_t process_start(private_eap_sim_peer_t *this,
default:
if (!simaka_attribute_skippable(type))
{
- *out = create_client_error(this, in->get_identifier(in),
- SIM_UNABLE_TO_PROCESS);
+ *out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
enumerator->destroy(enumerator);
return NEED_MORE;
}
@@ -177,8 +181,7 @@ static status_t process_start(private_eap_sim_peer_t *this,
if (!supported)
{
DBG1(DBG_IKE, "server does not support EAP-SIM version number 1");
- *out = create_client_error(this, in->get_identifier(in),
- SIM_UNSUPPORTED_VERSION);
+ *out = create_client_error(this, SIM_UNSUPPORTED_VERSION);
return NEED_MORE;
}
@@ -214,7 +217,7 @@ static status_t process_start(private_eap_sim_peer_t *this,
free(this->nonce.ptr);
rng->allocate_bytes(rng, NONCE_LEN, &this->nonce);
- message = simaka_message_create(FALSE, in->get_identifier(in), EAP_SIM,
+ message = simaka_message_create(FALSE, this->identifier, EAP_SIM,
SIM_START, this->crypto);
if (!this->reauth)
{
@@ -261,8 +264,7 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
default:
if (!simaka_attribute_skippable(type))
{
- *out = create_client_error(this, in->get_identifier(in),
- SIM_UNABLE_TO_PROCESS);
+ *out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
enumerator->destroy(enumerator);
return NEED_MORE;
}
@@ -277,8 +279,7 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
memeq(rands.ptr, rands.ptr + SIM_RAND_LEN, SIM_RAND_LEN))
{
DBG1(DBG_IKE, "no valid AT_RAND received");
- *out = create_client_error(this, in->get_identifier(in),
- SIM_INSUFFICIENT_CHALLENGES);
+ *out = create_client_error(this, SIM_INSUFFICIENT_CHALLENGES);
return NEED_MORE;
}
/* get two or three KCs/SRESes from SIM using RANDs */
@@ -290,8 +291,7 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
rands.ptr, sres.ptr, kc.ptr))
{
DBG1(DBG_IKE, "unable to get EAP-SIM triplet");
- *out = create_client_error(this, in->get_identifier(in),
- SIM_UNABLE_TO_PROCESS);
+ *out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
return NEED_MORE;
}
DBG3(DBG_IKE, "got triplet for RAND %b\n Kc %b\n SRES %b",
@@ -316,8 +316,7 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
* parse() again after key derivation, reading encrypted attributes */
if (!in->verify(in, this->nonce) || !in->parse(in))
{
- *out = create_client_error(this, in->get_identifier(in),
- SIM_UNABLE_TO_PROCESS);
+ *out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
return NEED_MORE;
}
@@ -345,7 +344,7 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
enumerator->destroy(enumerator);
/* build response with AT_MAC, built over "EAP packet | n*SRES" */
- message = simaka_message_create(FALSE, in->get_identifier(in), EAP_SIM,
+ message = simaka_message_create(FALSE, this->identifier, EAP_SIM,
SIM_CHALLENGE, this->crypto);
*out = message->generate(message, sreses);
message->destroy(message);
@@ -379,8 +378,7 @@ static status_t process_reauthentication(private_eap_sim_peer_t *this,
{
DBG1(DBG_IKE, "received %N, but not expected",
simaka_subtype_names, SIM_REAUTHENTICATION);
- *out = create_client_error(this, in->get_identifier(in),
- SIM_UNABLE_TO_PROCESS);
+ *out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
return NEED_MORE;
}
@@ -390,8 +388,7 @@ static status_t process_reauthentication(private_eap_sim_peer_t *this,
/* verify MAC and parse again with decryption key */
if (!in->verify(in, chunk_empty) || !in->parse(in))
{
- *out = create_client_error(this, in->get_identifier(in),
- SIM_UNABLE_TO_PROCESS);
+ *out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
return NEED_MORE;
}
@@ -412,8 +409,7 @@ static status_t process_reauthentication(private_eap_sim_peer_t *this,
default:
if (!simaka_attribute_skippable(type))
{
- *out = create_client_error(this, in->get_identifier(in),
- SIM_UNABLE_TO_PROCESS);
+ *out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
enumerator->destroy(enumerator);
return NEED_MORE;
}
@@ -425,12 +421,11 @@ static status_t process_reauthentication(private_eap_sim_peer_t *this,
if (!nonce.len || !counter.len)
{
DBG1(DBG_IKE, "EAP-SIM/Request/Re-Authentication message incomplete");
- *out = create_client_error(this, in->get_identifier(in),
- SIM_UNABLE_TO_PROCESS);
+ *out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
return NEED_MORE;
}
- message = simaka_message_create(FALSE, in->get_identifier(in), EAP_SIM,
+ message = simaka_message_create(FALSE, this->identifier, EAP_SIM,
SIM_REAUTHENTICATION, this->crypto);
if (counter_too_small(this, counter))
{
@@ -503,40 +498,37 @@ static status_t process_notification(private_eap_sim_peer_t *this,
if (success)
{ /* empty notification reply */
- message = simaka_message_create(FALSE, in->get_identifier(in), EAP_SIM,
+ message = simaka_message_create(FALSE, this->identifier, EAP_SIM,
SIM_NOTIFICATION, this->crypto);
*out = message->generate(message, chunk_empty);
message->destroy(message);
}
else
{
- *out = create_client_error(this, in->get_identifier(in),
- SIM_UNABLE_TO_PROCESS);
+ *out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
}
return NEED_MORE;
}
-/**
- * Implementation of eap_method_t.process
- */
-static status_t process(private_eap_sim_peer_t *this,
- eap_payload_t *in, eap_payload_t **out)
+METHOD(eap_method_t, process, status_t,
+ private_eap_sim_peer_t *this, eap_payload_t *in, eap_payload_t **out)
{
simaka_message_t *message;
status_t status;
+ /* store received EAP message identifier */
+ this->identifier = in->get_identifier(in);
+
message = simaka_message_create_from_payload(in, this->crypto);
if (!message)
{
- *out = create_client_error(this, in->get_identifier(in),
- SIM_UNABLE_TO_PROCESS);
+ *out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
return NEED_MORE;
}
if (!message->parse(message))
{
message->destroy(message);
- *out = create_client_error(this, in->get_identifier(in),
- SIM_UNABLE_TO_PROCESS);
+ *out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
return NEED_MORE;
}
switch (message->get_subtype(message))
@@ -556,8 +548,7 @@ static status_t process(private_eap_sim_peer_t *this,
default:
DBG1(DBG_IKE, "unable to process EAP-SIM subtype %N",
simaka_subtype_names, message->get_subtype(message));
- *out = create_client_error(this, in->get_identifier(in),
- SIM_UNABLE_TO_PROCESS);
+ *out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
status = NEED_MORE;
break;
}
@@ -565,28 +556,22 @@ static status_t process(private_eap_sim_peer_t *this,
return status;
}
-/**
- * Implementation of eap_method_t.initiate
- */
-static status_t initiate(private_eap_sim_peer_t *this, eap_payload_t **out)
+METHOD(eap_method_t, initiate, status_t,
+ private_eap_sim_peer_t *this, eap_payload_t **out)
{
/* peer never initiates */
return FAILED;
}
-/**
- * Implementation of eap_method_t.get_type.
- */
-static eap_type_t get_type(private_eap_sim_peer_t *this, u_int32_t *vendor)
+METHOD(eap_method_t, get_type, eap_type_t,
+ private_eap_sim_peer_t *this, u_int32_t *vendor)
{
*vendor = 0;
return EAP_SIM;
}
-/**
- * Implementation of eap_method_t.get_msk.
- */
-static status_t get_msk(private_eap_sim_peer_t *this, chunk_t *msk)
+METHOD(eap_method_t, get_msk, status_t,
+ private_eap_sim_peer_t *this, chunk_t *msk)
{
if (this->msk.ptr)
{
@@ -596,18 +581,26 @@ static status_t get_msk(private_eap_sim_peer_t *this, chunk_t *msk)
return FAILED;
}
-/**
- * Implementation of eap_method_t.is_mutual.
- */
-static bool is_mutual(private_eap_sim_peer_t *this)
+METHOD(eap_method_t, get_identifier, u_int8_t,
+ private_eap_sim_peer_t *this)
+{
+ return this->identifier;
+}
+
+METHOD(eap_method_t, set_identifier, void,
+ private_eap_sim_peer_t *this, u_int8_t identifier)
+{
+ this->identifier = identifier;
+}
+
+METHOD(eap_method_t, is_mutual, bool,
+ private_eap_sim_peer_t *this)
{
return TRUE;
}
-/**
- * Implementation of eap_method_t.destroy.
- */
-static void destroy(private_eap_sim_peer_t *this)
+METHOD(eap_method_t, destroy, void,
+ private_eap_sim_peer_t *this)
{
this->permanent->destroy(this->permanent);
DESTROY_IF(this->pseudonym);
@@ -625,28 +618,32 @@ static void destroy(private_eap_sim_peer_t *this)
eap_sim_peer_t *eap_sim_peer_create(identification_t *server,
identification_t *peer)
{
- private_eap_sim_peer_t *this = malloc_thing(private_eap_sim_peer_t);
-
- this->public.interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate;
- this->public.interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process;
- this->public.interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
- this->public.interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
- this->public.interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
- this->public.interface.destroy = (void(*)(eap_method_t*))destroy;
+ private_eap_sim_peer_t *this;
+
+ INIT(this,
+ .public = {
+ .interface = {
+ .initiate = _initiate,
+ .process = _process,
+ .get_type = _get_type,
+ .is_mutual = _is_mutual,
+ .get_msk = _get_msk,
+ .get_identifier = _get_identifier,
+ .set_identifier = _set_identifier,
+ .destroy = _destroy,
+ },
+ },
+ .crypto = simaka_crypto_create(),
+ );
- this->crypto = simaka_crypto_create();
if (!this->crypto)
{
free(this);
return NULL;
}
+
this->permanent = peer->clone(peer);
- this->pseudonym = NULL;
- this->reauth = NULL;
this->tries = MAX_TRIES;
- this->version_list = chunk_empty;
- this->nonce = chunk_empty;
- this->msk = chunk_empty;
return &this->public;
}
diff --git a/src/libcharon/plugins/eap_sim/eap_sim_plugin.c b/src/libcharon/plugins/eap_sim/eap_sim_plugin.c
index f0c972253..b15292544 100644
--- a/src/libcharon/plugins/eap_sim/eap_sim_plugin.c
+++ b/src/libcharon/plugins/eap_sim/eap_sim_plugin.c
@@ -20,10 +20,14 @@
#include <daemon.h>
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(eap_sim_plugin_t *this)
+METHOD(plugin_t, get_name, char*,
+ eap_sim_plugin_t *this)
+{
+ return "eap-sim";
+}
+
+METHOD(plugin_t, destroy, void,
+ eap_sim_plugin_t *this)
{
charon->eap->remove_method(charon->eap,
(eap_constructor_t)eap_sim_server_create);
@@ -37,9 +41,15 @@ static void destroy(eap_sim_plugin_t *this)
*/
plugin_t *eap_sim_plugin_create()
{
- eap_sim_plugin_t *this = malloc_thing(eap_sim_plugin_t);
-
- this->plugin.destroy = (void(*)(plugin_t*))destroy;
+ eap_sim_plugin_t *this;
+
+ INIT(this,
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ );
charon->eap->add_method(charon->eap, EAP_SIM, 0, EAP_SERVER,
(eap_constructor_t)eap_sim_server_create);
diff --git a/src/libcharon/plugins/eap_sim/eap_sim_server.c b/src/libcharon/plugins/eap_sim/eap_sim_server.c
index f6d5df09b..d1dfde5d6 100644
--- a/src/libcharon/plugins/eap_sim/eap_sim_server.c
+++ b/src/libcharon/plugins/eap_sim/eap_sim_server.c
@@ -107,10 +107,8 @@ struct private_eap_sim_server_t {
/* version of SIM protocol we speak */
static chunk_t version = chunk_from_chars(0x00,0x01);
-/**
- * Implementation of eap_method_t.initiate
- */
-static status_t initiate(private_eap_sim_server_t *this, eap_payload_t **out)
+METHOD(eap_method_t, initiate, status_t,
+ private_eap_sim_server_t *this, eap_payload_t **out)
{
simaka_message_t *message;
@@ -479,11 +477,8 @@ static status_t process_client_error(private_eap_sim_server_t *this,
return FAILED;
}
-/**
- * Implementation of eap_method_t.process
- */
-static status_t process(private_eap_sim_server_t *this,
- eap_payload_t *in, eap_payload_t **out)
+METHOD(eap_method_t, process, status_t,
+ private_eap_sim_server_t *this, eap_payload_t *in, eap_payload_t **out)
{
simaka_message_t *message;
status_t status;
@@ -522,19 +517,15 @@ static status_t process(private_eap_sim_server_t *this,
return status;
}
-/**
- * Implementation of eap_method_t.get_type.
- */
-static eap_type_t get_type(private_eap_sim_server_t *this, u_int32_t *vendor)
+METHOD(eap_method_t, get_type, eap_type_t,
+ private_eap_sim_server_t *this, u_int32_t *vendor)
{
*vendor = 0;
return EAP_SIM;
}
-/**
- * Implementation of eap_method_t.get_msk.
- */
-static status_t get_msk(private_eap_sim_server_t *this, chunk_t *msk)
+METHOD(eap_method_t, get_msk, status_t,
+ private_eap_sim_server_t *this, chunk_t *msk)
{
if (this->msk.ptr)
{
@@ -544,18 +535,26 @@ static status_t get_msk(private_eap_sim_server_t *this, chunk_t *msk)
return FAILED;
}
-/**
- * Implementation of eap_method_t.is_mutual.
- */
-static bool is_mutual(private_eap_sim_server_t *this)
+METHOD(eap_method_t, get_identifier, u_int8_t,
+ private_eap_sim_server_t *this)
+{
+ return this->identifier;
+}
+
+METHOD(eap_method_t, set_identifier, void,
+ private_eap_sim_server_t *this, u_int8_t identifier)
+{
+ this->identifier = identifier;
+}
+
+METHOD(eap_method_t, is_mutual, bool,
+ private_eap_sim_server_t *this)
{
return TRUE;
}
-/**
- * Implementation of eap_method_t.destroy.
- */
-static void destroy(private_eap_sim_server_t *this)
+METHOD(eap_method_t, destroy, void,
+ private_eap_sim_server_t *this)
{
this->crypto->destroy(this->crypto);
this->permanent->destroy(this->permanent);
@@ -574,29 +573,31 @@ static void destroy(private_eap_sim_server_t *this)
eap_sim_server_t *eap_sim_server_create(identification_t *server,
identification_t *peer)
{
- private_eap_sim_server_t *this = malloc_thing(private_eap_sim_server_t);
+ private_eap_sim_server_t *this;
+
+ INIT(this,
+ .public = {
+ .interface = {
+ .initiate = _initiate,
+ .process = _process,
+ .get_type = _get_type,
+ .is_mutual = _is_mutual,
+ .get_msk = _get_msk,
+ .get_identifier = _get_identifier,
+ .set_identifier = _set_identifier,
+ .destroy = _destroy,
+ },
+ },
+ .crypto = simaka_crypto_create(),
+ );
- this->public.interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate;
- this->public.interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process;
- this->public.interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
- this->public.interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
- this->public.interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
- this->public.interface.destroy = (void(*)(eap_method_t*))destroy;
-
- this->crypto = simaka_crypto_create();
if (!this->crypto)
{
free(this);
return NULL;
}
+
this->permanent = peer->clone(peer);
- this->pseudonym = NULL;
- this->reauth = NULL;
- this->sreses = chunk_empty;
- this->nonce = chunk_empty;
- this->msk = chunk_empty;
- this->counter = chunk_empty;
- this->pending = 0;
this->use_reauth = this->use_pseudonym = this->use_permanent =
lib->settings->get_bool(lib->settings,
"charon.plugins.eap-sim.request_identity", TRUE);
diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.in b/src/libcharon/plugins/eap_sim_file/Makefile.in
index 3cd766a75..5662a1c53 100644
--- a/src/libcharon/plugins/eap_sim_file/Makefile.in
+++ b/src/libcharon/plugins/eap_sim_file/Makefile.in
@@ -245,6 +245,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -268,6 +270,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.c b/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.c
index d132a38f6..5397c418e 100644
--- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.c
+++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.c
@@ -35,11 +35,9 @@ struct private_eap_sim_file_card_t {
eap_sim_file_triplets_t *triplets;
};
-/**
- * Implementation of sim_card_t.get_triplet
- */
-static bool get_triplet(private_eap_sim_file_card_t *this,
- identification_t *id, char *rand, char *sres, char *kc)
+METHOD(sim_card_t, get_triplet, bool,
+ private_eap_sim_file_card_t *this, identification_t *id,
+ char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
{
enumerator_t *enumerator;
identification_t *cand;
@@ -68,18 +66,16 @@ static bool get_triplet(private_eap_sim_file_card_t *this,
return FALSE;
}
-/**
- * Implementation of sim_card_t.get_quintuplet
- */
-static status_t get_quintuplet()
+METHOD(sim_card_t, get_quintuplet, status_t,
+ private_eap_sim_file_card_t *this, identification_t *id,
+ char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN],
+ char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len)
{
return NOT_SUPPORTED;
}
-/**
- * Implementation of eap_sim_file_card_t.destroy.
- */
-static void destroy(private_eap_sim_file_card_t *this)
+METHOD(eap_sim_file_card_t, destroy, void,
+ private_eap_sim_file_card_t *this)
{
free(this);
}
@@ -89,18 +85,23 @@ static void destroy(private_eap_sim_file_card_t *this)
*/
eap_sim_file_card_t *eap_sim_file_card_create(eap_sim_file_triplets_t *triplets)
{
- private_eap_sim_file_card_t *this = malloc_thing(private_eap_sim_file_card_t);
-
- this->public.card.get_triplet = (bool(*)(sim_card_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))get_triplet;
- this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len))get_quintuplet;
- this->public.card.resync = (bool(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false;
- this->public.card.get_pseudonym = (identification_t*(*)(sim_card_t*, identification_t *perm))return_null;
- this->public.card.set_pseudonym = (void(*)(sim_card_t*, identification_t *id, identification_t *pseudonym))nop;
- this->public.card.get_reauth = (identification_t*(*)(sim_card_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))return_null;
- this->public.card.set_reauth = (void(*)(sim_card_t*, identification_t *id, identification_t* next, char mk[HASH_SIZE_SHA1], u_int16_t counter))nop;
- this->public.destroy = (void(*)(eap_sim_file_card_t*))destroy;
-
- this->triplets = triplets;
+ private_eap_sim_file_card_t *this;
+
+ INIT(this,
+ .public = {
+ .card = {
+ .get_triplet = _get_triplet,
+ .get_quintuplet = _get_quintuplet,
+ .resync = (void*)return_false,
+ .get_pseudonym = (void*)return_null,
+ .set_pseudonym = (void*)nop,
+ .get_reauth = (void*)return_null,
+ .set_reauth = (void*)nop,
+ },
+ .destroy = _destroy,
+ },
+ .triplets = triplets,
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_plugin.c b/src/libcharon/plugins/eap_sim_file/eap_sim_file_plugin.c
index 4f25c35ea..0ab5a1848 100644
--- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_plugin.c
+++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_plugin.c
@@ -50,10 +50,14 @@ struct private_eap_sim_file_t {
eap_sim_file_triplets_t *triplets;
};
-/**
- * Implementation of eap_sim_file_t.destroy.
- */
-static void destroy(private_eap_sim_file_t *this)
+METHOD(plugin_t, get_name, char*,
+ private_eap_sim_file_t *this)
+{
+ return "eap-sim-file";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_eap_sim_file_t *this)
{
charon->sim->remove_card(charon->sim, &this->card->card);
charon->sim->remove_provider(charon->sim, &this->provider->provider);
@@ -68,11 +72,19 @@ static void destroy(private_eap_sim_file_t *this)
*/
plugin_t *eap_sim_file_plugin_create()
{
- private_eap_sim_file_t *this = malloc_thing(private_eap_sim_file_t);
-
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+ private_eap_sim_file_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ .triplets = eap_sim_file_triplets_create(TRIPLET_FILE),
+ );
- this->triplets = eap_sim_file_triplets_create(TRIPLET_FILE);
this->provider = eap_sim_file_provider_create(this->triplets);
if (!this->provider)
{
diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.c b/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.c
index 9bee31fc3..38b651404 100644
--- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.c
+++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.c
@@ -35,11 +35,9 @@ struct private_eap_sim_file_provider_t {
eap_sim_file_triplets_t *triplets;
};
-/**
- * Implementation of sim_provider_t.get_triplet
- */
-static bool get_triplet(private_eap_sim_file_provider_t *this,
- identification_t *id, char *rand, char *sres, char *kc)
+METHOD(sim_provider_t, get_triplet, bool,
+ private_eap_sim_file_provider_t *this, identification_t *id,
+ char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
{
enumerator_t *enumerator;
identification_t *cand;
@@ -61,10 +59,8 @@ static bool get_triplet(private_eap_sim_file_provider_t *this,
return FALSE;
}
-/**
- * Implementation of eap_sim_file_provider_t.destroy.
- */
-static void destroy(private_eap_sim_file_provider_t *this)
+METHOD(eap_sim_file_provider_t, destroy, void,
+ private_eap_sim_file_provider_t *this)
{
free(this);
}
@@ -75,18 +71,23 @@ static void destroy(private_eap_sim_file_provider_t *this)
eap_sim_file_provider_t *eap_sim_file_provider_create(
eap_sim_file_triplets_t *triplets)
{
- private_eap_sim_file_provider_t *this = malloc_thing(private_eap_sim_file_provider_t);
-
- this->public.provider.get_triplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))get_triplet;
- this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false;
- this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false;
- this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null;
- this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null;
- this->public.provider.is_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char [HASH_SIZE_SHA1], u_int16_t *counter))return_null;
- this->public.provider.gen_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))return_null;
- this->public.destroy = (void(*)(eap_sim_file_provider_t*))destroy;
+ private_eap_sim_file_provider_t *this;
- this->triplets = triplets;
+ INIT(this,
+ .public = {
+ .provider = {
+ .get_triplet = _get_triplet,
+ .get_quintuplet = (void*)return_false,
+ .resync = (void*)return_false,
+ .is_pseudonym = (void*)return_null,
+ .gen_pseudonym = (void*)return_null,
+ .is_reauth = (void*)return_null,
+ .gen_reauth = (void*)return_null,
+ },
+ .destroy = _destroy,
+ },
+ .triplets = triplets,
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c b/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c
index 6b7d99fb7..c693923fe 100644
--- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c
+++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c
@@ -117,10 +117,8 @@ static bool enumerator_enumerate(triplet_enumerator_t *e, identification_t **ims
return FALSE;
}
-/**
- * Implementation of eap_sim_file_triplets_t.create_enumerator
- */
-static enumerator_t* create_enumerator(private_eap_sim_file_triplets_t *this)
+METHOD(eap_sim_file_triplets_t, create_enumerator, enumerator_t*,
+ private_eap_sim_file_triplets_t *this)
{
triplet_enumerator_t *enumerator = malloc_thing(triplet_enumerator_t);
@@ -230,10 +228,8 @@ static void read_triplets(private_eap_sim_file_triplets_t *this, char *path)
this->triplets->get_count(this->triplets), path);
}
-/**
- * Implementation of eap_sim_file_triplets_t.destroy.
- */
-static void destroy(private_eap_sim_file_triplets_t *this)
+METHOD(eap_sim_file_triplets_t, destroy, void,
+ private_eap_sim_file_triplets_t *this)
{
this->triplets->destroy_function(this->triplets, (void*)triplet_destroy);
this->mutex->destroy(this->mutex);
@@ -245,14 +241,16 @@ static void destroy(private_eap_sim_file_triplets_t *this)
*/
eap_sim_file_triplets_t *eap_sim_file_triplets_create(char *file)
{
- private_eap_sim_file_triplets_t *this = malloc_thing(private_eap_sim_file_triplets_t);
-
- this->public.create_enumerator = (enumerator_t*(*)(eap_sim_file_triplets_t*))create_enumerator;
- this->public.destroy = (void(*)(eap_sim_file_triplets_t*))destroy;
-
- this->triplets = linked_list_create();
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
+ private_eap_sim_file_triplets_t *this;
+ INIT(this,
+ .public = {
+ .create_enumerator = _create_enumerator,
+ .destroy = _destroy,
+ },
+ .triplets = linked_list_create(),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ );
read_triplets(this, file);
return &this->public;
diff --git a/src/libcharon/plugins/eap_sim_pcsc/Makefile.am b/src/libcharon/plugins/eap_sim_pcsc/Makefile.am
new file mode 100644
index 000000000..2d75fe3ad
--- /dev/null
+++ b/src/libcharon/plugins/eap_sim_pcsc/Makefile.am
@@ -0,0 +1,18 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = -rdynamic ${pcsclite_CFLAGS}
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-eap-sim-pcsc.la
+else
+plugin_LTLIBRARIES = libstrongswan-eap-sim-pcsc.la
+endif
+
+libstrongswan_eap_sim_pcsc_la_SOURCES = \
+ eap_sim_pcsc_plugin.h eap_sim_pcsc_plugin.c \
+ eap_sim_pcsc_card.h eap_sim_pcsc_card.c
+
+libstrongswan_eap_sim_pcsc_la_LDFLAGS = -module -avoid-version
+libstrongswan_eap_sim_pcsc_la_LIBADD = ${pcsclite_LIBS}
diff --git a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in
new file mode 100644
index 000000000..a8249a7ac
--- /dev/null
+++ b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in
@@ -0,0 +1,611 @@
+# Makefile.in generated by automake 1.11.1 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.
+# 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libcharon/plugins/eap_sim_pcsc
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.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
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libstrongswan_eap_sim_pcsc_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_libstrongswan_eap_sim_pcsc_la_OBJECTS = eap_sim_pcsc_plugin.lo \
+ eap_sim_pcsc_card.lo
+libstrongswan_eap_sim_pcsc_la_OBJECTS = \
+ $(am_libstrongswan_eap_sim_pcsc_la_OBJECTS)
+libstrongswan_eap_sim_pcsc_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_eap_sim_pcsc_la_LDFLAGS) $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_eap_sim_pcsc_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_eap_sim_pcsc_la_rpath =
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+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)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_eap_sim_pcsc_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_eap_sim_pcsc_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREADLIB = @PTHREADLIB@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+default_pkcs11 = @default_pkcs11@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
+libdir = @libdir@
+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@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+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
+
+AM_CFLAGS = -rdynamic ${pcsclite_CFLAGS}
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-sim-pcsc.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-sim-pcsc.la
+libstrongswan_eap_sim_pcsc_la_SOURCES = \
+ eap_sim_pcsc_plugin.h eap_sim_pcsc_plugin.c \
+ eap_sim_pcsc_card.h eap_sim_pcsc_card.c
+
+libstrongswan_eap_sim_pcsc_la_LDFLAGS = -module -avoid-version
+libstrongswan_eap_sim_pcsc_la_LIBADD = ${pcsclite_LIBS}
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/eap_sim_pcsc/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/eap_sim_pcsc/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+ }
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstrongswan-eap-sim-pcsc.la: $(libstrongswan_eap_sim_pcsc_la_OBJECTS) $(libstrongswan_eap_sim_pcsc_la_DEPENDENCIES)
+ $(libstrongswan_eap_sim_pcsc_la_LINK) $(am_libstrongswan_eap_sim_pcsc_la_rpath) $(libstrongswan_eap_sim_pcsc_la_OBJECTS) $(libstrongswan_eap_sim_pcsc_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_sim_pcsc_card.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_sim_pcsc_plugin.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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-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
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
+ ctags distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-pluginLTLIBRARIES install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.c b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.c
new file mode 100644
index 000000000..d0a2718f3
--- /dev/null
+++ b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.c
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2011 Duncan Salerno
+ *
+ * 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 "eap_sim_pcsc_card.h"
+
+#include <PCSC/wintypes.h>
+#include <PCSC/winscard.h>
+#include <daemon.h>
+
+typedef struct private_eap_sim_pcsc_card_t private_eap_sim_pcsc_card_t;
+
+/**
+ * Private data of an eap_sim_pcsc_card_t object.
+ */
+struct private_eap_sim_pcsc_card_t {
+
+ /**
+ * Public eap_sim_pcsc_card_t interface.
+ */
+ eap_sim_pcsc_card_t public;
+};
+
+/**
+ * Maximum length for an IMSI.
+ */
+#define SIM_IMSI_MAX_LEN 15
+
+/**
+ * Length of the status at the end of response APDUs.
+ */
+#define APDU_STATUS_LEN 2
+
+/**
+ * First byte of status word indicating success.
+ */
+#define APDU_SW1_SUCCESS 0x90
+
+/**
+ * First byte of status word indicating there is response data to be read.
+ */
+#define APDU_SW1_RESPONSE_DATA 0x9f
+
+/**
+ * Decode IMSI EF (Elementary File) into an ASCII string
+ */
+static bool decode_imsi_ef(unsigned char *input, int input_len, char *output)
+{
+ /* Only digits 0-9 valid in IMSIs */
+ static const char bcd_num_digits[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', '\0', '\0', '\0', '\0', '\0', '\0'
+ };
+ int i;
+
+ /* Check length byte matches how many bytes we have, and that input
+ * is correct length for an IMSI */
+ if (input[0] != input_len-1 || input_len < 2 || input_len > 9)
+ {
+ return FALSE;
+ }
+
+ /* Check type byte is IMSI (bottom 3 bits == 001) */
+ if ((input[1] & 0x07) != 0x01)
+ {
+ return FALSE;
+ }
+ *output++ = bcd_num_digits[input[1] >> 4];
+
+ for (i = 2; i < input_len; i++)
+ {
+ *output++ = bcd_num_digits[input[i] & 0xf];
+ *output++ = bcd_num_digits[input[i] >> 4];
+ }
+
+ *output++ = '\0';
+ return TRUE;
+}
+
+METHOD(sim_card_t, get_triplet, bool,
+ private_eap_sim_pcsc_card_t *this, identification_t *id,
+ char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
+{
+ status_t found = FALSE;
+ LONG rv;
+ SCARDCONTEXT hContext;
+ DWORD dwReaders;
+ LPSTR mszReaders;
+ char *cur_reader;
+ char full_nai[128];
+ SCARDHANDLE hCard;
+ enum { DISCONNECTED, CONNECTED, TRANSACTION } hCard_status = DISCONNECTED;
+
+ snprintf(full_nai, sizeof(full_nai), "%Y", id);
+
+ DBG2(DBG_IKE, "looking for triplet: %Y rand %b", id, rand, SIM_RAND_LEN);
+
+ rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ DBG1(DBG_IKE, "SCardEstablishContext: %s", pcsc_stringify_error(rv));
+ return FALSE;
+ }
+
+ rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ DBG1(DBG_IKE, "SCardListReaders: %s", pcsc_stringify_error(rv));
+ return FALSE;
+ }
+ mszReaders = malloc(sizeof(char)*dwReaders);
+
+ rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ DBG1(DBG_IKE, "SCardListReaders: %s", pcsc_stringify_error(rv));
+ return FALSE;
+ }
+
+ /* mszReaders is a multi-string of readers, separated by '\0' and
+ * terminated by an additional '\0' */
+ for (cur_reader = mszReaders; *cur_reader != '\0' && found == FALSE;
+ cur_reader += strlen(cur_reader) + 1)
+ {
+ DWORD dwActiveProtocol = -1;
+ SCARD_IO_REQUEST *pioSendPci;
+ SCARD_IO_REQUEST pioRecvPci;
+ BYTE pbRecvBuffer[64];
+ DWORD dwRecvLength;
+ char imsi[SIM_IMSI_MAX_LEN + 1];
+
+ /* See GSM 11.11 for SIM APDUs */
+ static const BYTE pbSelectMF[] = { 0xa0, 0xa4, 0x00, 0x00, 0x02, 0x3f, 0x00 };
+ static const BYTE pbSelectDFGSM[] = { 0xa0, 0xa4, 0x00, 0x00, 0x02, 0x7f, 0x20 };
+ static const BYTE pbSelectIMSI[] = { 0xa0, 0xa4, 0x00, 0x00, 0x02, 0x6f, 0x07 };
+ static const BYTE pbReadBinary[] = { 0xa0, 0xb0, 0x00, 0x00, 0x09 };
+ BYTE pbRunGSMAlgorithm[5 + SIM_RAND_LEN] = { 0xa0, 0x88, 0x00, 0x00, 0x10 };
+ static const BYTE pbGetResponse[] = { 0xa0, 0xc0, 0x00, 0x00, 0x0c };
+
+ /* If on 2nd or later reader, make sure we end the transaction
+ * and disconnect card in the previous reader */
+ switch (hCard_status)
+ {
+ case TRANSACTION:
+ SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
+ /* FALLTHRU */
+ case CONNECTED:
+ SCardDisconnect(hCard, SCARD_LEAVE_CARD);
+ /* FALLTHRU */
+ case DISCONNECTED:
+ hCard_status = DISCONNECTED;
+ }
+
+ /* Copy RAND into APDU */
+ memcpy(pbRunGSMAlgorithm + 5, rand, SIM_RAND_LEN);
+
+ rv = SCardConnect(hContext, cur_reader, SCARD_SHARE_SHARED,
+ SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ DBG1(DBG_IKE, "SCardConnect: %s", pcsc_stringify_error(rv));
+ continue;
+ }
+ hCard_status = CONNECTED;
+
+ switch(dwActiveProtocol)
+ {
+ case SCARD_PROTOCOL_T0:
+ pioSendPci = SCARD_PCI_T0;
+ break;
+ case SCARD_PROTOCOL_T1:
+ pioSendPci = SCARD_PCI_T1;
+ break;
+ default:
+ DBG1(DBG_IKE, "Unknown SCARD_PROTOCOL");
+ continue;
+ }
+
+ /* Start transaction */
+ rv = SCardBeginTransaction(hCard);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ DBG1(DBG_IKE, "SCardBeginTransaction: %s", pcsc_stringify_error(rv));
+ continue;
+ }
+ hCard_status = TRANSACTION;
+
+ /* APDU: Select MF */
+ dwRecvLength = sizeof(pbRecvBuffer);
+ rv = SCardTransmit(hCard, pioSendPci, pbSelectMF, sizeof(pbSelectMF),
+ &pioRecvPci, pbRecvBuffer, &dwRecvLength);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
+ continue;
+ }
+ if (dwRecvLength < APDU_STATUS_LEN ||
+ pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
+ {
+ DBG1(DBG_IKE, "Select MF failed: %b", pbRecvBuffer, dwRecvLength);
+ continue;
+ }
+
+ /* APDU: Select DF GSM */
+ dwRecvLength = sizeof(pbRecvBuffer);
+ rv = SCardTransmit(hCard, pioSendPci, pbSelectDFGSM, sizeof(pbSelectDFGSM),
+ &pioRecvPci, pbRecvBuffer, &dwRecvLength);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
+ continue;
+ }
+ if (dwRecvLength < APDU_STATUS_LEN ||
+ pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
+ {
+ DBG1(DBG_IKE, "Select DF GSM failed: %b", pbRecvBuffer, dwRecvLength);
+ continue;
+ }
+
+ /* APDU: Select IMSI */
+ dwRecvLength = sizeof(pbRecvBuffer);
+ rv = SCardTransmit(hCard, pioSendPci, pbSelectIMSI, sizeof(pbSelectIMSI),
+ &pioRecvPci, pbRecvBuffer, &dwRecvLength);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
+ continue;
+ }
+ if (dwRecvLength < APDU_STATUS_LEN ||
+ pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
+ {
+ DBG1(DBG_IKE, "Select IMSI failed: %b", pbRecvBuffer, dwRecvLength);
+ continue;
+ }
+
+ /* APDU: Read Binary (of IMSI) */
+ dwRecvLength = sizeof(pbRecvBuffer);
+ rv = SCardTransmit(hCard, pioSendPci, pbReadBinary, sizeof(pbReadBinary),
+ &pioRecvPci, pbRecvBuffer, &dwRecvLength);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
+ continue;
+ }
+ if (dwRecvLength < APDU_STATUS_LEN ||
+ pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_SUCCESS)
+ {
+ DBG1(DBG_IKE, "Select IMSI failed: %b", pbRecvBuffer, dwRecvLength);
+ continue;
+ }
+
+ if (!decode_imsi_ef(pbRecvBuffer, dwRecvLength-APDU_STATUS_LEN, imsi))
+ {
+ DBG1(DBG_IKE, "Couldn't decode IMSI EF: %b",
+ pbRecvBuffer, dwRecvLength);
+ continue;
+ }
+
+ /* The IMSI could be post/prefixed in the full NAI, so just make sure
+ * it's in there */
+ if (!(strlen(full_nai) && strstr(full_nai, imsi)))
+ {
+ DBG1(DBG_IKE, "Not the SIM we're looking for, IMSI: %s", imsi);
+ continue;
+ }
+
+ /* APDU: Run GSM Algorithm */
+ dwRecvLength = sizeof(pbRecvBuffer);
+ rv = SCardTransmit(hCard, pioSendPci,
+ pbRunGSMAlgorithm, sizeof(pbRunGSMAlgorithm),
+ &pioRecvPci, pbRecvBuffer, &dwRecvLength);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
+ continue;
+ }
+ if (dwRecvLength < APDU_STATUS_LEN ||
+ pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
+ {
+ DBG1(DBG_IKE, "Run GSM Algorithm failed: %b",
+ pbRecvBuffer, dwRecvLength);
+ continue;
+ }
+
+ /* APDU: Get Response (of Run GSM Algorithm) */
+ dwRecvLength = sizeof(pbRecvBuffer);
+ rv = SCardTransmit(hCard, pioSendPci, pbGetResponse, sizeof(pbGetResponse),
+ &pioRecvPci, pbRecvBuffer, &dwRecvLength);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ DBG1(DBG_IKE, "SCardTransmit: %s", pcsc_stringify_error(rv));
+ continue;
+ }
+
+ if (dwRecvLength < APDU_STATUS_LEN ||
+ pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_SUCCESS)
+ {
+ DBG1(DBG_IKE, "Get Response failed: %b", pbRecvBuffer, dwRecvLength);
+ continue;
+ }
+
+ /* Extract out Kc and SRES from response */
+ if (dwRecvLength == SIM_SRES_LEN + SIM_KC_LEN + APDU_STATUS_LEN)
+ {
+ memcpy(sres, pbRecvBuffer, SIM_SRES_LEN);
+ memcpy(kc, pbRecvBuffer+4, SIM_KC_LEN);
+ /* This will also cause the loop to exit */
+ found = TRUE;
+ }
+ else
+ {
+ DBG1(DBG_IKE, "Get Response incorrect length: %b",
+ pbRecvBuffer, dwRecvLength);
+ continue;
+ }
+
+ /* Transaction will be ended and card disconnected at the
+ * beginning of this loop or after this loop */
+ }
+
+ /* Make sure we end any previous transaction and disconnect card */
+ switch (hCard_status)
+ {
+ case TRANSACTION:
+ SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
+ /* FALLTHRU */
+ case CONNECTED:
+ SCardDisconnect(hCard, SCARD_LEAVE_CARD);
+ /* FALLTHRU */
+ case DISCONNECTED:
+ hCard_status = DISCONNECTED;
+ }
+
+ rv = SCardReleaseContext(hContext);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ DBG1(DBG_IKE, "SCardReleaseContext: %s", pcsc_stringify_error(rv));
+ }
+
+ free(mszReaders);
+ return found;
+}
+
+METHOD(sim_card_t, get_quintuplet, status_t,
+ private_eap_sim_pcsc_card_t *this, identification_t *id,
+ char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN],
+ char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len)
+{
+ return NOT_SUPPORTED;
+}
+
+METHOD(eap_sim_pcsc_card_t, destroy, void,
+ private_eap_sim_pcsc_card_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header
+ */
+eap_sim_pcsc_card_t *eap_sim_pcsc_card_create()
+{
+ private_eap_sim_pcsc_card_t *this;
+
+ INIT(this,
+ .public = {
+ .card = {
+ .get_triplet = _get_triplet,
+ .get_quintuplet = _get_quintuplet,
+ .resync = (void*)return_false,
+ .get_pseudonym = (void*)return_null,
+ .set_pseudonym = (void*)nop,
+ .get_reauth = (void*)return_null,
+ .set_reauth = (void*)nop,
+ },
+ .destroy = _destroy,
+ },
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.h b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.h
new file mode 100644
index 000000000..e7659656b
--- /dev/null
+++ b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 Duncan Salerno
+ *
+ * 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 eap_sim_pcsc_card eap_sim_pcsc_card
+ * @{ @ingroup eap_sim_pcsc
+ */
+
+#ifndef EAP_SIM_PCSC_CARD_H_
+#define EAP_SIM_PCSC_CARD_H_
+
+#include <sa/authenticators/eap/sim_manager.h>
+
+typedef struct eap_sim_pcsc_card_t eap_sim_pcsc_card_t;
+
+/**
+ * SIM card implementation using a PCSC reader.
+ */
+struct eap_sim_pcsc_card_t {
+
+ /**
+ * Implements sim_card_t interface
+ */
+ sim_card_t card;
+
+ /**
+ * Destroy a eap_sim_pcsc_card_t.
+ */
+ void (*destroy)(eap_sim_pcsc_card_t *this);
+};
+
+/**
+ * Create a eap_sim_pcsc_card instance.
+ */
+eap_sim_pcsc_card_t *eap_sim_pcsc_card_create();
+
+#endif /** EAP_SIM_PCSC_CARD_H_ @}*/
diff --git a/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.c b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.c
new file mode 100644
index 000000000..44096455e
--- /dev/null
+++ b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2011 Duncan Salerno
+ *
+ * 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 "eap_sim_pcsc_plugin.h"
+#include "eap_sim_pcsc_card.h"
+
+#include <daemon.h>
+
+typedef struct private_eap_sim_pcsc_plugin_t private_eap_sim_pcsc_plugin_t;
+
+/**
+ * Private data of an eap_sim_pcsc_t object.
+ */
+struct private_eap_sim_pcsc_plugin_t {
+
+ /**
+ * Public eap_sim_pcsc_plugin_t interface.
+ */
+ eap_sim_pcsc_plugin_t public;
+
+ /**
+ * SIM card
+ */
+ eap_sim_pcsc_card_t *card;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_eap_sim_pcsc_plugin_t *this)
+{
+ return "eap-sim-pcsc";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_eap_sim_pcsc_plugin_t *this)
+{
+ charon->sim->remove_card(charon->sim, &this->card->card);
+ this->card->destroy(this->card);
+ free(this);
+}
+
+/**
+ * See header
+ */
+plugin_t *eap_sim_pcsc_plugin_create()
+{
+ private_eap_sim_pcsc_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ .card = eap_sim_pcsc_card_create(),
+ );
+ charon->sim->add_card(charon->sim, &this->card->card);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.h b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.h
new file mode 100644
index 000000000..a03ca1f9c
--- /dev/null
+++ b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 Duncan Salerno
+ *
+ * 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 eap_sim_pcsc eap_sim_pcsc
+ * @ingroup cplugins
+ *
+ * @defgroup eap_sim_pcsc_plugin eap_sim_pcsc_plugin
+ * @{ @ingroup eap_sim_pcsc
+ */
+
+#ifndef EAP_SIM_PCSC_PLUGIN_H_
+#define EAP_SIM_PCSC_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct eap_sim_pcsc_plugin_t eap_sim_pcsc_plugin_t;
+
+/**
+ * Plugin to provide a SIM card from a PCSC reader.
+ */
+struct eap_sim_pcsc_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** EAP_SIM_PCSC_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
index a48fb652a..98e80bc71 100644
--- a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
@@ -246,6 +246,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -269,6 +271,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c
index 81b9d7b00..06631b1c5 100644
--- a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c
+++ b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c
@@ -42,10 +42,14 @@ struct private_eap_simaka_pseudonym_t {
eap_simaka_pseudonym_provider_t *provider;
};
-/**
- * Implementation of eap_simaka_pseudonym_t.destroy.
- */
-static void destroy(private_eap_simaka_pseudonym_t *this)
+METHOD(plugin_t, get_name, char*,
+ private_eap_simaka_pseudonym_t *this)
+{
+ return "eap-simaka-pseudonym";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_eap_simaka_pseudonym_t *this)
{
charon->sim->remove_card(charon->sim, &this->card->card);
charon->sim->remove_provider(charon->sim, &this->provider->provider);
@@ -61,11 +65,17 @@ plugin_t *eap_simaka_pseudonym_plugin_create()
{
private_eap_simaka_pseudonym_t *this;
- this = malloc_thing(private_eap_simaka_pseudonym_t);
-
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ .provider = eap_simaka_pseudonym_provider_create(),
+ );
- this->provider = eap_simaka_pseudonym_provider_create();
if (!this->provider)
{
free(this);
diff --git a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
index f2af3ae0d..56bc188b0 100644
--- a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
@@ -245,6 +245,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -268,6 +270,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c
index 987a0e109..343e4eefb 100644
--- a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c
+++ b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c
@@ -42,10 +42,14 @@ struct private_eap_simaka_reauth_t {
eap_simaka_reauth_provider_t *provider;
};
-/**
- * Implementation of eap_simaka_reauth_t.destroy.
- */
-static void destroy(private_eap_simaka_reauth_t *this)
+METHOD(plugin_t, get_name, char*,
+ private_eap_simaka_reauth_t *this)
+{
+ return "eap-simaka-reauth";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_eap_simaka_reauth_t *this)
{
charon->sim->remove_card(charon->sim, &this->card->card);
charon->sim->remove_provider(charon->sim, &this->provider->provider);
@@ -59,11 +63,19 @@ static void destroy(private_eap_simaka_reauth_t *this)
*/
plugin_t *eap_simaka_reauth_plugin_create()
{
- private_eap_simaka_reauth_t *this = malloc_thing(private_eap_simaka_reauth_t);
+ private_eap_simaka_reauth_t *this;
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ .provider = eap_simaka_reauth_provider_create(),
+ );
- this->provider = eap_simaka_reauth_provider_create();
if (!this->provider)
{
free(this);
diff --git a/src/libcharon/plugins/eap_simaka_sql/Makefile.in b/src/libcharon/plugins/eap_simaka_sql/Makefile.in
index 9a58a6055..93c7aed03 100644
--- a/src/libcharon/plugins/eap_simaka_sql/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_sql/Makefile.in
@@ -244,6 +244,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -267,6 +269,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_plugin.c b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_plugin.c
index 1cc5352d8..5a528153d 100644
--- a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_plugin.c
+++ b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_plugin.c
@@ -47,6 +47,12 @@ struct private_eap_simaka_sql_t {
database_t *db;
};
+METHOD(plugin_t, get_name, char*,
+ private_eap_simaka_sql_t *this)
+{
+ return "eap-simaka-sql";
+}
+
METHOD(plugin_t, destroy, void,
private_eap_simaka_sql_t *this)
{
@@ -87,6 +93,8 @@ plugin_t *eap_simaka_sql_plugin_create()
INIT(this,
.public = {
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/eap_tls/Makefile.in b/src/libcharon/plugins/eap_tls/Makefile.in
index 9ebb85be9..c58bced06 100644
--- a/src/libcharon/plugins/eap_tls/Makefile.in
+++ b/src/libcharon/plugins/eap_tls/Makefile.in
@@ -243,6 +243,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -266,6 +268,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/eap_tls/eap_tls.c b/src/libcharon/plugins/eap_tls/eap_tls.c
index efe72c437..39e1a60d9 100644
--- a/src/libcharon/plugins/eap_tls/eap_tls.c
+++ b/src/libcharon/plugins/eap_tls/eap_tls.c
@@ -91,6 +91,18 @@ METHOD(eap_method_t, get_msk, status_t,
return FAILED;
}
+METHOD(eap_method_t, get_identifier, u_int8_t,
+ private_eap_tls_t *this)
+{
+ return this->tls_eap->get_identifier(this->tls_eap);
+}
+
+METHOD(eap_method_t, set_identifier, void,
+ private_eap_tls_t *this, u_int8_t identifier)
+{
+ this->tls_eap->set_identifier(this->tls_eap, identifier);
+}
+
METHOD(eap_method_t, is_mutual, bool,
private_eap_tls_t *this)
{
@@ -113,6 +125,7 @@ static eap_tls_t *eap_tls_create(identification_t *server,
private_eap_tls_t *this;
size_t frag_size;
int max_msg_count;
+ bool include_length;
tls_t *tls;
INIT(this,
@@ -123,6 +136,8 @@ static eap_tls_t *eap_tls_create(identification_t *server,
.get_type = _get_type,
.is_mutual = _is_mutual,
.get_msk = _get_msk,
+ .get_identifier = _get_identifier,
+ .set_identifier = _set_identifier,
.destroy = _destroy,
},
},
@@ -132,8 +147,11 @@ static eap_tls_t *eap_tls_create(identification_t *server,
"charon.plugins.eap-tls.fragment_size", MAX_FRAGMENT_LEN);
max_msg_count = lib->settings->get_int(lib->settings,
"charon.plugins.eap-tls.max_message_count", MAX_MESSAGE_COUNT);
+ include_length = lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap-tls.include_length", TRUE);
tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TLS, NULL);
- this->tls_eap = tls_eap_create(EAP_TLS, tls, frag_size, max_msg_count);
+ this->tls_eap = tls_eap_create(EAP_TLS, tls, frag_size, max_msg_count,
+ include_length);
if (!this->tls_eap)
{
free(this);
diff --git a/src/libcharon/plugins/eap_tls/eap_tls_plugin.c b/src/libcharon/plugins/eap_tls/eap_tls_plugin.c
index a7c040bf4..7afb79819 100644
--- a/src/libcharon/plugins/eap_tls/eap_tls_plugin.c
+++ b/src/libcharon/plugins/eap_tls/eap_tls_plugin.c
@@ -19,6 +19,11 @@
#include <daemon.h>
+METHOD(plugin_t, get_name, char*,
+ eap_tls_plugin_t *this)
+{
+ return "eap-tls";
+}
METHOD(plugin_t, destroy, void,
eap_tls_plugin_t *this)
@@ -39,6 +44,8 @@ plugin_t *eap_tls_plugin_create()
INIT(this,
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
);
diff --git a/src/libcharon/plugins/eap_tnc/Makefile.in b/src/libcharon/plugins/eap_tnc/Makefile.in
index cf75585ef..dfc052bf8 100644
--- a/src/libcharon/plugins/eap_tnc/Makefile.in
+++ b/src/libcharon/plugins/eap_tnc/Makefile.in
@@ -243,6 +243,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -266,6 +268,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc.c b/src/libcharon/plugins/eap_tnc/eap_tnc.c
index dd4ed5322..ab3f87688 100644
--- a/src/libcharon/plugins/eap_tnc/eap_tnc.c
+++ b/src/libcharon/plugins/eap_tnc/eap_tnc.c
@@ -92,6 +92,18 @@ METHOD(eap_method_t, get_msk, status_t,
return FAILED;
}
+METHOD(eap_method_t, get_identifier, u_int8_t,
+ private_eap_tnc_t *this)
+{
+ return this->tls_eap->get_identifier(this->tls_eap);
+}
+
+METHOD(eap_method_t, set_identifier, void,
+ private_eap_tnc_t *this, u_int8_t identifier)
+{
+ this->tls_eap->set_identifier(this->tls_eap, identifier);
+}
+
METHOD(eap_method_t, is_mutual, bool,
private_eap_tnc_t *this)
{
@@ -114,6 +126,7 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
private_eap_tnc_t *this;
size_t frag_size;
int max_msg_count;
+ bool include_length;
char* protocol;
tnccs_type_t type;
tnccs_t *tnccs;
@@ -126,6 +139,8 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
.get_type = _get_type,
.is_mutual = _is_mutual,
.get_msk = _get_msk,
+ .get_identifier = _get_identifier,
+ .set_identifier = _set_identifier,
.destroy = _destroy,
},
},
@@ -135,7 +150,9 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
"charon.plugins.eap-tnc.fragment_size", MAX_FRAGMENT_LEN);
max_msg_count = lib->settings->get_int(lib->settings,
"charon.plugins.eap-tnc.max_message_count", MAX_MESSAGE_COUNT);
- protocol = lib->settings->get_str(lib->settings,
+ include_length = lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap-tnc.include_length", TRUE);
+ protocol = lib->settings->get_str(lib->settings,
"charon.plugins.eap-tnc.protocol", "tnccs-1.1");
if (strcaseeq(protocol, "tnccs-2.0"))
{
@@ -156,7 +173,8 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
return NULL;
}
tnccs = charon->tnccs->create_instance(charon->tnccs, type, is_server);
- this->tls_eap = tls_eap_create(EAP_TNC, (tls_t*)tnccs, frag_size, max_msg_count);
+ this->tls_eap = tls_eap_create(EAP_TNC, (tls_t*)tnccs, frag_size,
+ max_msg_count, include_length);
if (!this->tls_eap)
{
free(this);
diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c b/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c
index 7430e4cac..93847e636 100644
--- a/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c
+++ b/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c
@@ -18,6 +18,12 @@
#include <daemon.h>
+METHOD(plugin_t, get_name, char*,
+ eap_tnc_plugin_t *this)
+{
+ return "eap-tnc";
+}
+
METHOD(plugin_t, destroy, void,
eap_tnc_plugin_t *this)
{
@@ -37,6 +43,8 @@ plugin_t *eap_tnc_plugin_create()
INIT(this,
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
);
diff --git a/src/libcharon/plugins/eap_ttls/Makefile.in b/src/libcharon/plugins/eap_ttls/Makefile.in
index ff67686b2..d0d5341e2 100644
--- a/src/libcharon/plugins/eap_ttls/Makefile.in
+++ b/src/libcharon/plugins/eap_ttls/Makefile.in
@@ -246,6 +246,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -269,6 +271,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls.c b/src/libcharon/plugins/eap_ttls/eap_ttls.c
index a62af6ea4..7193bc9f0 100644
--- a/src/libcharon/plugins/eap_ttls/eap_ttls.c
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls.c
@@ -93,6 +93,18 @@ METHOD(eap_method_t, get_msk, status_t,
return FAILED;
}
+METHOD(eap_method_t, get_identifier, u_int8_t,
+ private_eap_ttls_t *this)
+{
+ return this->tls_eap->get_identifier(this->tls_eap);
+}
+
+METHOD(eap_method_t, set_identifier, void,
+ private_eap_ttls_t *this, u_int8_t identifier)
+{
+ this->tls_eap->set_identifier(this->tls_eap, identifier);
+}
+
METHOD(eap_method_t, is_mutual, bool,
private_eap_ttls_t *this)
{
@@ -116,6 +128,7 @@ static eap_ttls_t *eap_ttls_create(identification_t *server,
private_eap_ttls_t *this;
size_t frag_size;
int max_msg_count;
+ bool include_length;
tls_t *tls;
INIT(this,
@@ -125,6 +138,8 @@ static eap_ttls_t *eap_ttls_create(identification_t *server,
.process = _process,
.get_type = _get_type,
.is_mutual = _is_mutual,
+ .get_identifier = _get_identifier,
+ .set_identifier = _set_identifier,
.get_msk = _get_msk,
.destroy = _destroy,
},
@@ -139,8 +154,11 @@ static eap_ttls_t *eap_ttls_create(identification_t *server,
"charon.plugins.eap-ttls.fragment_size", MAX_FRAGMENT_LEN);
max_msg_count = lib->settings->get_int(lib->settings,
"charon.plugins.eap-ttls.max_message_count", MAX_MESSAGE_COUNT);
- tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TTLS, application);
- this->tls_eap = tls_eap_create(EAP_TTLS, tls, frag_size, max_msg_count);
+ include_length = lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap-ttls.include_length", TRUE);
+ tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TTLS, application);
+ this->tls_eap = tls_eap_create(EAP_TTLS, tls, frag_size, max_msg_count,
+ include_length);
if (!this->tls_eap)
{
application->destroy(application);
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c b/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c
index 29b0a9303..931eb2e89 100644
--- a/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c
@@ -64,17 +64,6 @@ struct private_eap_ttls_peer_t {
eap_ttls_avp_t *avp;
};
-/**
- * EAP packet format
- */
-typedef struct __attribute__((packed)) {
- u_int8_t code;
- u_int8_t identifier;
- u_int16_t length;
- u_int8_t type;
- u_int8_t data;
-} eap_packet_t;
-
#define MAX_RADIUS_ATTRIBUTE_SIZE 253
METHOD(tls_application_t, process, status_t,
@@ -174,17 +163,30 @@ METHOD(tls_application_t, process, status_t,
return FAILED;
}
+ /* yet another phase2 authentication? */
+ if (this->method)
+ {
+ type = this->method->get_type(this->method, &vendor);
+
+ if (type != received_type || vendor != received_vendor)
+ {
+ this->method->destroy(this->method);
+ this->method = NULL;
+ }
+ }
+
if (this->method == NULL)
{
if (received_vendor)
{
- DBG1(DBG_IKE, "server requested vendor specific EAP method %d-%d",
- received_type, received_vendor);
+ DBG1(DBG_IKE, "server requested vendor specific EAP method %d-%d "
+ "(id 0x%02X)", received_type, received_vendor,
+ in->get_identifier(in));
}
else
{
- DBG1(DBG_IKE, "server requested %N authentication",
- eap_type_names, received_type);
+ DBG1(DBG_IKE, "server requested %N authentication (id 0x%02X)",
+ eap_type_names, received_type, in->get_identifier(in));
}
this->method = charon->eap->create_instance(charon->eap,
received_type, received_vendor,
@@ -196,18 +198,10 @@ METHOD(tls_application_t, process, status_t,
in->destroy(in);
return NEED_MORE;
}
+ type = this->method->get_type(this->method, &vendor);
this->start_phase2 = FALSE;
}
- type = this->method->get_type(this->method, &vendor);
-
- if (type != received_type || vendor != received_vendor)
- {
- DBG1(DBG_IKE, "received invalid EAP request");
- in->destroy(in);
- return FAILED;
- }
-
status = this->method->process(this->method, in, &this->out);
in->destroy(in);
@@ -216,13 +210,8 @@ METHOD(tls_application_t, process, status_t,
case SUCCESS:
this->method->destroy(this->method);
this->method = NULL;
- return NEED_MORE;
+ /* fall through to NEED_MORE */
case NEED_MORE:
- if (type != EAP_TNC)
- {
- this->method->destroy(this->method);
- this->method = NULL;
- }
return NEED_MORE;
case FAILED:
default:
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c b/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c
index 48e759dcc..cbc3929bb 100644
--- a/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c
@@ -19,6 +19,11 @@
#include <daemon.h>
+METHOD(plugin_t, get_name, char*,
+ eap_ttls_plugin_t *this)
+{
+ return "eap-ttls";
+}
METHOD(plugin_t, destroy, void,
eap_ttls_plugin_t *this)
@@ -39,6 +44,8 @@ plugin_t *eap_ttls_plugin_create()
INIT(this,
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
);
diff --git a/src/libcharon/plugins/farp/Makefile.in b/src/libcharon/plugins/farp/Makefile.in
index 21e8b78db..4ba29472d 100644
--- a/src/libcharon/plugins/farp/Makefile.in
+++ b/src/libcharon/plugins/farp/Makefile.in
@@ -241,6 +241,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -264,6 +266,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/farp/farp_plugin.c b/src/libcharon/plugins/farp/farp_plugin.c
index d83bc1fd2..a30c11962 100644
--- a/src/libcharon/plugins/farp/farp_plugin.c
+++ b/src/libcharon/plugins/farp/farp_plugin.c
@@ -43,6 +43,12 @@ struct private_farp_plugin_t {
farp_spoofer_t *spoofer;
};
+METHOD(plugin_t, get_name, char*,
+ private_farp_plugin_t *this)
+{
+ return "farp";
+}
+
METHOD(plugin_t, destroy, void,
private_farp_plugin_t *this)
{
@@ -62,6 +68,8 @@ plugin_t *farp_plugin_create()
INIT(this,
.public = {
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/ha/Makefile.in b/src/libcharon/plugins/ha/Makefile.in
index 2fcd7cc82..fe72c5c8e 100644
--- a/src/libcharon/plugins/ha/Makefile.in
+++ b/src/libcharon/plugins/ha/Makefile.in
@@ -243,6 +243,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -266,6 +268,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/ha/ha_child.c b/src/libcharon/plugins/ha/ha_child.c
index 1a9425423..707add94d 100644
--- a/src/libcharon/plugins/ha/ha_child.c
+++ b/src/libcharon/plugins/ha/ha_child.c
@@ -91,6 +91,10 @@ METHOD(listener_t, child_keys, bool,
{
m->add_attribute(m, HA_ALG_INTEG, alg);
}
+ if (proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, &alg, NULL))
+ {
+ m->add_attribute(m, HA_ESN, alg);
+ }
m->add_attribute(m, HA_NONCE_I, nonce_i);
m->add_attribute(m, HA_NONCE_R, nonce_r);
if (dh && dh->get_shared_secret(dh, &secret) == SUCCESS)
diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c
index 85dc0f4a4..0d0df8dd1 100644
--- a/src/libcharon/plugins/ha/ha_dispatcher.c
+++ b/src/libcharon/plugins/ha/ha_dispatcher.c
@@ -462,6 +462,7 @@ static void process_child_add(private_ha_dispatcher_t *this,
u_int16_t inbound_cpi = 0, outbound_cpi = 0;
u_int8_t mode = MODE_TUNNEL, ipcomp = 0;
u_int16_t encr = ENCR_UNDEFINED, integ = AUTH_UNDEFINED, len = 0;
+ u_int16_t esn = NO_EXT_SEQ_NUMBERS;
u_int seg_i, seg_o;
chunk_t nonce_i = chunk_empty, nonce_r = chunk_empty, secret = chunk_empty;
chunk_t encr_i, integ_i, encr_r, integ_r;
@@ -512,6 +513,9 @@ static void process_child_add(private_ha_dispatcher_t *this,
case HA_ALG_INTEG:
integ = value.u16;
break;
+ case HA_ESN:
+ esn = value.u16;
+ break;
case HA_NONCE_I:
nonce_i = value.chunk;
break;
@@ -558,6 +562,7 @@ static void process_child_add(private_ha_dispatcher_t *this,
{
proposal->add_algorithm(proposal, ENCRYPTION_ALGORITHM, encr, len);
}
+ proposal->add_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, esn, 0);
keymat = ike_sa->get_keymat(ike_sa);
if (!keymat->derive_child_keys(keymat, proposal, secret.ptr ? &dh : NULL,
diff --git a/src/libcharon/plugins/ha/ha_message.c b/src/libcharon/plugins/ha/ha_message.c
index 7ce9cbe09..f98f78dd4 100644
--- a/src/libcharon/plugins/ha/ha_message.c
+++ b/src/libcharon/plugins/ha/ha_message.c
@@ -234,6 +234,7 @@ METHOD(ha_message_t, add_attribute, void,
case HA_INBOUND_CPI:
case HA_OUTBOUND_CPI:
case HA_SEGMENT:
+ case HA_ESN:
{
u_int16_t val;
@@ -447,6 +448,7 @@ METHOD(enumerator_t, attribute_enumerate, bool,
case HA_INBOUND_CPI:
case HA_OUTBOUND_CPI:
case HA_SEGMENT:
+ case HA_ESN:
{
if (this->buf.len < sizeof(u_int16_t))
{
diff --git a/src/libcharon/plugins/ha/ha_message.h b/src/libcharon/plugins/ha/ha_message.h
index 50e11830f..1f8eabd62 100644
--- a/src/libcharon/plugins/ha/ha_message.h
+++ b/src/libcharon/plugins/ha/ha_message.h
@@ -140,6 +140,8 @@ enum ha_message_attribute_t {
HA_MID,
/** u_int16_t, HA segment */
HA_SEGMENT,
+ /** u_int16_t, Extended Sequence numbers */
+ HA_ESN,
};
/**
diff --git a/src/libcharon/plugins/ha/ha_plugin.c b/src/libcharon/plugins/ha/ha_plugin.c
index 581294e60..b4bde5ea5 100644
--- a/src/libcharon/plugins/ha/ha_plugin.c
+++ b/src/libcharon/plugins/ha/ha_plugin.c
@@ -91,6 +91,12 @@ struct private_ha_plugin_t {
ha_attribute_t *attr;
};
+METHOD(plugin_t, get_name, char*,
+ private_ha_plugin_t *this)
+{
+ return "ha";
+}
+
METHOD(plugin_t, destroy, void,
private_ha_plugin_t *this)
{
@@ -144,6 +150,8 @@ plugin_t *ha_plugin_create()
INIT(this,
.public = {
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/led/Makefile.in b/src/libcharon/plugins/led/Makefile.in
index fa1194fd0..db3a7c702 100644
--- a/src/libcharon/plugins/led/Makefile.in
+++ b/src/libcharon/plugins/led/Makefile.in
@@ -240,6 +240,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -263,6 +265,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/led/led_plugin.c b/src/libcharon/plugins/led/led_plugin.c
index 322d198ff..b6b69b466 100644
--- a/src/libcharon/plugins/led/led_plugin.c
+++ b/src/libcharon/plugins/led/led_plugin.c
@@ -37,6 +37,12 @@ struct private_led_plugin_t {
led_listener_t *listener;
};
+METHOD(plugin_t, get_name, char*,
+ private_led_plugin_t *this)
+{
+ return "led";
+}
+
METHOD(plugin_t, destroy, void,
private_led_plugin_t *this)
{
@@ -55,6 +61,8 @@ plugin_t *led_plugin_create()
INIT(this,
.public = {
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/load_tester/Makefile.in b/src/libcharon/plugins/load_tester/Makefile.in
index c921ec3db..1e9a5fe82 100644
--- a/src/libcharon/plugins/load_tester/Makefile.in
+++ b/src/libcharon/plugins/load_tester/Makefile.in
@@ -246,6 +246,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -269,6 +271,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/load_tester/load_tester_ipsec.c b/src/libcharon/plugins/load_tester/load_tester_ipsec.c
index ef9d7f9ef..fdec5300e 100644
--- a/src/libcharon/plugins/load_tester/load_tester_ipsec.c
+++ b/src/libcharon/plugins/load_tester/load_tester_ipsec.c
@@ -54,8 +54,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,
u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
- u_int16_t cpi, bool encap, bool inbound, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts)
+ u_int16_t cpi, bool encap, bool esn, bool inbound,
+ traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
{
return SUCCESS;
}
diff --git a/src/libcharon/plugins/load_tester/load_tester_plugin.c b/src/libcharon/plugins/load_tester/load_tester_plugin.c
index 8fd65adfa..94115e307 100644
--- a/src/libcharon/plugins/load_tester/load_tester_plugin.c
+++ b/src/libcharon/plugins/load_tester/load_tester_plugin.c
@@ -146,10 +146,14 @@ static job_requeue_t do_load_test(private_load_tester_plugin_t *this)
return JOB_REQUEUE_NONE;
}
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(private_load_tester_plugin_t *this)
+METHOD(plugin_t, get_name, char*,
+ private_load_tester_plugin_t *this)
+{
+ return "load-tester";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_load_tester_plugin_t *this)
{
this->iterations = -1;
this->mutex->lock(this->mutex);
@@ -188,32 +192,39 @@ plugin_t *load_tester_plugin_create()
return NULL;
}
- this = malloc_thing(private_load_tester_plugin_t);
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ .delay = lib->settings->get_int(lib->settings,
+ "charon.plugins.load-tester.delay", 0),
+ .iterations = lib->settings->get_int(lib->settings,
+ "charon.plugins.load-tester.iterations", 1),
+ .initiators = lib->settings->get_int(lib->settings,
+ "charon.plugins.load-tester.initiators", 0),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .condvar = condvar_create(CONDVAR_TYPE_DEFAULT),
+ .config = load_tester_config_create(),
+ .creds = load_tester_creds_create(),
+ .listener = load_tester_listener_create(shutdown_on),
+ );
lib->crypto->add_dh(lib->crypto, MODP_NULL, plugin_name,
(dh_constructor_t)load_tester_diffie_hellman_create);
+ charon->backends->add_backend(charon->backends, &this->config->backend);
+ lib->credmgr->add_set(lib->credmgr, &this->creds->credential_set);
+ charon->bus->add_listener(charon->bus, &this->listener->listener);
- this->delay = lib->settings->get_int(lib->settings,
- "charon.plugins.load-tester.delay", 0);
- this->iterations = lib->settings->get_int(lib->settings,
- "charon.plugins.load-tester.iterations", 1);
- this->initiators = lib->settings->get_int(lib->settings,
- "charon.plugins.load-tester.initiators", 0);
if (lib->settings->get_bool(lib->settings,
"charon.plugins.load-tester.shutdown_when_complete", 0))
{
shutdown_on = this->iterations * this->initiators;
}
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
- this->condvar = condvar_create(CONDVAR_TYPE_DEFAULT);
- this->config = load_tester_config_create();
- this->creds = load_tester_creds_create();
- this->listener = load_tester_listener_create(shutdown_on);
- charon->backends->add_backend(charon->backends, &this->config->backend);
- lib->credmgr->add_set(lib->credmgr, &this->creds->credential_set);
- charon->bus->add_listener(charon->bus, &this->listener->listener);
if (lib->settings->get_bool(lib->settings,
"charon.plugins.load-tester.fake_kernel", FALSE))
diff --git a/src/libcharon/plugins/maemo/Makefile.in b/src/libcharon/plugins/maemo/Makefile.in
index 0ca1fa436..27e72295c 100644
--- a/src/libcharon/plugins/maemo/Makefile.in
+++ b/src/libcharon/plugins/maemo/Makefile.in
@@ -245,6 +245,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -268,6 +270,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/maemo/maemo_plugin.c b/src/libcharon/plugins/maemo/maemo_plugin.c
index d4549f43a..38cb031b5 100644
--- a/src/libcharon/plugins/maemo/maemo_plugin.c
+++ b/src/libcharon/plugins/maemo/maemo_plugin.c
@@ -34,11 +34,16 @@ struct private_maemo_plugin_t {
* service
*/
maemo_service_t *service;
-
};
+METHOD(plugin_t, get_name, char*,
+ private_maemo_plugin_t *this)
+{
+ return "maemo";
+}
+
METHOD(plugin_t, destroy, void,
- private_maemo_plugin_t *this)
+ private_maemo_plugin_t *this)
{
this->service->destroy(this->service);
free(this);
@@ -54,6 +59,8 @@ plugin_t *maemo_plugin_create()
INIT(this,
.public = {
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/medcli/Makefile.in b/src/libcharon/plugins/medcli/Makefile.in
index 372a436a6..83b457b46 100644
--- a/src/libcharon/plugins/medcli/Makefile.in
+++ b/src/libcharon/plugins/medcli/Makefile.in
@@ -243,6 +243,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -266,6 +268,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/medcli/medcli_plugin.c b/src/libcharon/plugins/medcli/medcli_plugin.c
index 6befbf440..469915476 100644
--- a/src/libcharon/plugins/medcli/medcli_plugin.c
+++ b/src/libcharon/plugins/medcli/medcli_plugin.c
@@ -54,10 +54,14 @@ struct private_medcli_plugin_t {
medcli_listener_t *listener;
};
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(private_medcli_plugin_t *this)
+METHOD(plugin_t, get_name, char*,
+ private_medcli_plugin_t *this)
+{
+ return "medcli";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_medcli_plugin_t *this)
{
charon->bus->remove_listener(charon->bus, &this->listener->listener);
charon->backends->remove_backend(charon->backends, &this->config->backend);
@@ -75,9 +79,17 @@ static void destroy(private_medcli_plugin_t *this)
plugin_t *medcli_plugin_create()
{
char *uri;
- private_medcli_plugin_t *this = malloc_thing(private_medcli_plugin_t);
-
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+ private_medcli_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ );
uri = lib->settings->get_str(lib->settings,
"medcli.database", NULL);
diff --git a/src/libcharon/plugins/medsrv/Makefile.in b/src/libcharon/plugins/medsrv/Makefile.in
index 4bb65bd09..068f311a5 100644
--- a/src/libcharon/plugins/medsrv/Makefile.in
+++ b/src/libcharon/plugins/medsrv/Makefile.in
@@ -243,6 +243,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -266,6 +268,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/medsrv/medsrv_plugin.c b/src/libcharon/plugins/medsrv/medsrv_plugin.c
index c150346cb..5df46d04f 100644
--- a/src/libcharon/plugins/medsrv/medsrv_plugin.c
+++ b/src/libcharon/plugins/medsrv/medsrv_plugin.c
@@ -48,10 +48,14 @@ struct private_medsrv_plugin_t {
medsrv_config_t *config;
};
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(private_medsrv_plugin_t *this)
+METHOD(plugin_t, get_name, char*,
+ private_medsrv_plugin_t *this)
+{
+ return "medsrv";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_medsrv_plugin_t *this)
{
charon->backends->remove_backend(charon->backends, &this->config->backend);
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
@@ -67,9 +71,17 @@ static void destroy(private_medsrv_plugin_t *this)
plugin_t *medsrv_plugin_create()
{
char *uri;
- private_medsrv_plugin_t *this = malloc_thing(private_medsrv_plugin_t);
-
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+ private_medsrv_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ );
uri = lib->settings->get_str(lib->settings,
"medsrv.database", NULL);
diff --git a/src/libcharon/plugins/nm/Makefile.in b/src/libcharon/plugins/nm/Makefile.in
index 69af7bf83..308d27229 100644
--- a/src/libcharon/plugins/nm/Makefile.in
+++ b/src/libcharon/plugins/nm/Makefile.in
@@ -242,6 +242,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -265,6 +267,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/nm/nm_plugin.c b/src/libcharon/plugins/nm/nm_plugin.c
index fd0580bd6..f1d3be7a5 100644
--- a/src/libcharon/plugins/nm/nm_plugin.c
+++ b/src/libcharon/plugins/nm/nm_plugin.c
@@ -67,10 +67,14 @@ static job_requeue_t run(private_nm_plugin_t *this)
return JOB_REQUEUE_NONE;
}
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(private_nm_plugin_t *this)
+METHOD(plugin_t, get_name, char*,
+ private_nm_plugin_t *this)
+{
+ return "nm";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_nm_plugin_t *this)
{
if (this->loop)
{
@@ -96,22 +100,29 @@ static void destroy(private_nm_plugin_t *this)
*/
plugin_t *nm_plugin_create()
{
- private_nm_plugin_t *this = malloc_thing(private_nm_plugin_t);
-
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+ private_nm_plugin_t *this;
- this->loop = NULL;
g_type_init ();
if (!g_thread_supported())
{
g_thread_init(NULL);
}
- this->creds = nm_creds_create();
- this->handler = nm_handler_create();
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ .creds = nm_creds_create(),
+ .handler = nm_handler_create(),
+ .plugin = nm_strongswan_plugin_new(this->creds, this->handler),
+ );
+
hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
- this->plugin = nm_strongswan_plugin_new(this->creds, this->handler);
if (!this->plugin)
{
DBG1(DBG_CFG, "DBUS binding failed");
diff --git a/src/libcharon/plugins/smp/Makefile.in b/src/libcharon/plugins/smp/Makefile.in
index 3d2cef13c..e36fa6bb4 100644
--- a/src/libcharon/plugins/smp/Makefile.in
+++ b/src/libcharon/plugins/smp/Makefile.in
@@ -241,6 +241,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -264,6 +266,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/smp/smp.c b/src/libcharon/plugins/smp/smp.c
index 60937f23d..d20f32248 100644
--- a/src/libcharon/plugins/smp/smp.c
+++ b/src/libcharon/plugins/smp/smp.c
@@ -707,10 +707,14 @@ static job_requeue_t dispatch(private_smp_t *this)
return JOB_REQUEUE_DIRECT;
}
-/**
- * Implementation of itnerface_t.destroy.
- */
-static void destroy(private_smp_t *this)
+METHOD(plugin_t, get_name, char*,
+ private_smp_t *this)
+{
+ return "smp";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_smp_t *this)
{
this->job->cancel(this->job);
close(this->socket);
@@ -723,10 +727,18 @@ static void destroy(private_smp_t *this)
plugin_t *smp_plugin_create()
{
struct sockaddr_un unix_addr = { AF_UNIX, IPSEC_PIDDIR "/charon.xml"};
- private_smp_t *this = malloc_thing(private_smp_t);
+ private_smp_t *this;
mode_t old;
- this->public.plugin.destroy = (void (*)(plugin_t*))destroy;
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ );
/* set up unix socket */
this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
diff --git a/src/libcharon/plugins/socket_default/Makefile.in b/src/libcharon/plugins/socket_default/Makefile.in
index b82372e30..95cb04d14 100644
--- a/src/libcharon/plugins/socket_default/Makefile.in
+++ b/src/libcharon/plugins/socket_default/Makefile.in
@@ -244,6 +244,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -267,6 +269,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/socket_default/socket_default_plugin.c b/src/libcharon/plugins/socket_default/socket_default_plugin.c
index b5dea68b6..1bc8244d5 100644
--- a/src/libcharon/plugins/socket_default/socket_default_plugin.c
+++ b/src/libcharon/plugins/socket_default/socket_default_plugin.c
@@ -32,9 +32,14 @@ struct private_socket_default_plugin_t {
* Implements plugin interface
*/
socket_default_plugin_t public;
-
};
+METHOD(plugin_t, get_name, char*,
+ private_socket_default_plugin_t *this)
+{
+ return "socket-default";
+}
+
METHOD(plugin_t, destroy, void,
private_socket_default_plugin_t *this)
{
@@ -53,6 +58,8 @@ plugin_t *socket_default_plugin_create()
INIT(this,
.public = {
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/socket_dynamic/Makefile.in b/src/libcharon/plugins/socket_dynamic/Makefile.in
index 7a49088b2..97e3a713d 100644
--- a/src/libcharon/plugins/socket_dynamic/Makefile.in
+++ b/src/libcharon/plugins/socket_dynamic/Makefile.in
@@ -244,6 +244,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -267,6 +269,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c b/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c
index a6ff14efd..c5ea37a10 100644
--- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c
+++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c
@@ -32,9 +32,14 @@ struct private_socket_dynamic_plugin_t {
* Implements plugin interface
*/
socket_dynamic_plugin_t public;
-
};
+METHOD(plugin_t, get_name, char*,
+ private_socket_dynamic_plugin_t *this)
+{
+ return "socket-dynamic";
+}
+
METHOD(plugin_t, destroy, void,
private_socket_dynamic_plugin_t *this)
{
@@ -53,6 +58,8 @@ plugin_t *socket_dynamic_plugin_create()
INIT(this,
.public = {
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/socket_raw/Makefile.in b/src/libcharon/plugins/socket_raw/Makefile.in
index 744b12fcf..6f1a09c88 100644
--- a/src/libcharon/plugins/socket_raw/Makefile.in
+++ b/src/libcharon/plugins/socket_raw/Makefile.in
@@ -244,6 +244,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -267,6 +269,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/socket_raw/socket_raw_plugin.c b/src/libcharon/plugins/socket_raw/socket_raw_plugin.c
index 17a3a8db7..5bd28bd42 100644
--- a/src/libcharon/plugins/socket_raw/socket_raw_plugin.c
+++ b/src/libcharon/plugins/socket_raw/socket_raw_plugin.c
@@ -32,9 +32,14 @@ struct private_socket_raw_plugin_t {
* Implements plugin interface
*/
socket_raw_plugin_t public;
-
};
+METHOD(plugin_t, get_name, char*,
+ private_socket_raw_plugin_t *this)
+{
+ return "socket-raw";
+}
+
METHOD(plugin_t, destroy, void,
private_socket_raw_plugin_t *this)
{
@@ -53,6 +58,8 @@ plugin_t *socket_raw_plugin_create()
INIT(this,
.public = {
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/sql/Makefile.in b/src/libcharon/plugins/sql/Makefile.in
index 4244d3b5e..d7b43dcc9 100644
--- a/src/libcharon/plugins/sql/Makefile.in
+++ b/src/libcharon/plugins/sql/Makefile.in
@@ -241,6 +241,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -264,6 +266,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/sql/sql_plugin.c b/src/libcharon/plugins/sql/sql_plugin.c
index ad1eb91b1..d915d4696 100644
--- a/src/libcharon/plugins/sql/sql_plugin.c
+++ b/src/libcharon/plugins/sql/sql_plugin.c
@@ -53,6 +53,12 @@ struct private_sql_plugin_t {
sql_logger_t *logger;
};
+METHOD(plugin_t, get_name, char*,
+ private_sql_plugin_t *this)
+{
+ return "sql";
+}
+
METHOD(plugin_t, destroy, void,
private_sql_plugin_t *this)
{
@@ -84,6 +90,8 @@ plugin_t *sql_plugin_create()
INIT(this,
.public = {
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/stroke/Makefile.in b/src/libcharon/plugins/stroke/Makefile.in
index ccf3eeede..fd859daeb 100644
--- a/src/libcharon/plugins/stroke/Makefile.in
+++ b/src/libcharon/plugins/stroke/Makefile.in
@@ -244,6 +244,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -267,6 +269,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c
index ea7d17592..2b3164384 100644
--- a/src/libcharon/plugins/stroke/stroke_config.c
+++ b/src/libcharon/plugins/stroke/stroke_config.c
@@ -409,7 +409,7 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
}
else
{
- DBG1(DBG_CFG, "CA certificate %s not found, discarding CA "
+ DBG1(DBG_CFG, "CA certificate \"%s\" not found, discarding CA "
"constraint", ca);
}
}
diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c
index 3541ab8f9..4943ee670 100644
--- a/src/libcharon/plugins/stroke/stroke_control.c
+++ b/src/libcharon/plugins/stroke/stroke_control.c
@@ -92,48 +92,94 @@ static child_cfg_t* get_child_from_peer(peer_cfg_t *peer_cfg, char *name)
return found;
}
+/**
+ * call the charon controller to initiate the connection
+ */
+static void charon_initiate(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
+ stroke_msg_t *msg, FILE *out)
+{
+ if (msg->output_verbosity < 0)
+ {
+ charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
+ NULL, NULL);
+ }
+ else
+ {
+ stroke_log_info_t info = { msg->output_verbosity, out };
+
+ charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
+ (controller_cb_t)stroke_log, &info);
+ }
+}
+
METHOD(stroke_control_t, initiate, void,
private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
{
+ child_cfg_t *child_cfg = NULL;
peer_cfg_t *peer_cfg;
- child_cfg_t *child_cfg;
- stroke_log_info_t info;
+ enumerator_t *enumerator;
+ bool empty = TRUE;
peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
msg->initiate.name);
- if (peer_cfg == NULL)
- {
- DBG1(DBG_CFG, "no config named '%s'\n", msg->initiate.name);
- return;
- }
- if (peer_cfg->get_ike_version(peer_cfg) != 2)
+ if (peer_cfg)
{
- DBG1(DBG_CFG, "ignoring initiation request for IKEv%d config",
- peer_cfg->get_ike_version(peer_cfg));
- peer_cfg->destroy(peer_cfg);
- return;
- }
+ if (peer_cfg->get_ike_version(peer_cfg) != 2)
+ {
+ DBG1(DBG_CFG, "ignoring initiation request for IKEv%d config",
+ peer_cfg->get_ike_version(peer_cfg));
+ peer_cfg->destroy(peer_cfg);
+ return;
+ }
- child_cfg = get_child_from_peer(peer_cfg, msg->initiate.name);
- if (child_cfg == NULL)
- {
- DBG1(DBG_CFG, "no child config named '%s'\n", msg->initiate.name);
- peer_cfg->destroy(peer_cfg);
- return;
- }
+ child_cfg = get_child_from_peer(peer_cfg, msg->initiate.name);
+ if (child_cfg == NULL)
+ {
+ enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
+ while (enumerator->enumerate(enumerator, &child_cfg))
+ {
+ empty = FALSE;
+ charon_initiate(peer_cfg->get_ref(peer_cfg),
+ child_cfg->get_ref(child_cfg), msg, out);
+ }
+ enumerator->destroy(enumerator);
- if (msg->output_verbosity < 0)
- {
- charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
- NULL, NULL);
+ if (empty)
+ {
+ DBG1(DBG_CFG, "no child config named '%s'", msg->initiate.name);
+ fprintf(out, "no child config named '%s'\n", msg->initiate.name);
+ }
+ peer_cfg->destroy(peer_cfg);
+ return;
+ }
}
else
{
- info.out = out;
- info.level = msg->output_verbosity;
- charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
- (controller_cb_t)stroke_log, &info);
+ enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
+ NULL, NULL, NULL, NULL);
+ while (enumerator->enumerate(enumerator, &peer_cfg))
+ {
+ if (peer_cfg->get_ike_version(peer_cfg) != 2)
+ {
+ continue;
+ }
+ child_cfg = get_child_from_peer(peer_cfg, msg->initiate.name);
+ if (child_cfg)
+ {
+ peer_cfg->get_ref(peer_cfg);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (child_cfg == NULL)
+ {
+ DBG1(DBG_CFG, "no config named '%s'", msg->initiate.name);
+ fprintf(out, "no config named '%s'\n", msg->initiate.name);
+ return;
+ }
}
+ charon_initiate(peer_cfg, child_cfg, msg, out);
}
/**
@@ -470,41 +516,90 @@ METHOD(stroke_control_t, purge_ike, void,
list->destroy(list);
}
+/**
+ * call charon to install a trap
+ */
+static void charon_route(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
+ char *name, FILE *out)
+{
+ if (charon->traps->install(charon->traps, peer_cfg, child_cfg))
+ {
+ fprintf(out, "'%s' routed\n", name);
+ }
+ else
+ {
+ fprintf(out, "routing '%s' failed\n", name);
+ }
+}
+
METHOD(stroke_control_t, route, void,
private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
{
+ child_cfg_t *child_cfg = NULL;
peer_cfg_t *peer_cfg;
- child_cfg_t *child_cfg;
+ enumerator_t *enumerator;
+ bool empty = TRUE;
peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
msg->route.name);
- if (peer_cfg == NULL)
- {
- fprintf(out, "no config named '%s'\n", msg->route.name);
- return;
- }
- if (peer_cfg->get_ike_version(peer_cfg) != 2)
+ if (peer_cfg)
{
- peer_cfg->destroy(peer_cfg);
- return;
- }
+ if (peer_cfg->get_ike_version(peer_cfg) != 2)
+ {
+ DBG1(DBG_CFG, "ignoring initiation request for IKEv%d config",
+ peer_cfg->get_ike_version(peer_cfg));
+ peer_cfg->destroy(peer_cfg);
+ return;
+ }
- child_cfg = get_child_from_peer(peer_cfg, msg->route.name);
- if (child_cfg == NULL)
- {
- fprintf(out, "no child config named '%s'\n", msg->route.name);
- peer_cfg->destroy(peer_cfg);
- return;
- }
+ child_cfg = get_child_from_peer(peer_cfg, msg->route.name);
+ if (child_cfg == NULL)
+ {
+ enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
+ while (enumerator->enumerate(enumerator, &child_cfg))
+ {
+ empty = FALSE;
+ charon_route(peer_cfg, child_cfg, child_cfg->get_name(child_cfg),
+ out);
+ }
+ enumerator->destroy(enumerator);
- if (charon->traps->install(charon->traps, peer_cfg, child_cfg))
- {
- fprintf(out, "configuration '%s' routed\n", msg->route.name);
+ if (empty)
+ {
+ DBG1(DBG_CFG, "no child config named '%s'", msg->route.name);
+ fprintf(out, "no child config named '%s'\n", msg->route.name);
+ }
+ peer_cfg->destroy(peer_cfg);
+ return;
+ }
}
else
{
- fprintf(out, "routing configuration '%s' failed\n", msg->route.name);
+ enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
+ NULL, NULL, NULL, NULL);
+ while (enumerator->enumerate(enumerator, &peer_cfg))
+ {
+ if (peer_cfg->get_ike_version(peer_cfg) != 2)
+ {
+ continue;
+ }
+ child_cfg = get_child_from_peer(peer_cfg, msg->route.name);
+ if (child_cfg)
+ {
+ peer_cfg->get_ref(peer_cfg);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (child_cfg == NULL)
+ {
+ DBG1(DBG_CFG, "no config named '%s'", msg->route.name);
+ fprintf(out, "no config named '%s'\n", msg->route.name);
+ return;
+ }
}
+ charon_route(peer_cfg, child_cfg, msg->route.name, out);
peer_cfg->destroy(peer_cfg);
child_cfg->destroy(child_cfg);
}
diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c
index 83e5a9ad6..baf02a6da 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.c
+++ b/src/libcharon/plugins/stroke/stroke_cred.c
@@ -280,7 +280,7 @@ static void cache_cert(private_stroke_cred_t *this, certificate_t *cert)
chunk = crl->get_authKeyIdentifier(crl);
hex = chunk_to_hex(chunk, NULL, FALSE);
- snprintf(buf, sizeof(buf), "%s/%s.crl", CRL_DIR, hex);
+ snprintf(buf, sizeof(buf), "%s/%s.crl", CRL_DIR, hex.ptr);
free(hex.ptr);
if (cert->get_encoding(cert, CERT_ASN1_DER, &chunk))
@@ -518,7 +518,7 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
DBG1(DBG_CFG, "line %d: expected %%smartcard specifier", line_nr);
return FALSE;
}
- snprintf(smartcard, sizeof(smartcard), "%.*s", sc.len, sc.ptr);
+ snprintf(smartcard, sizeof(smartcard), "%.*s", (int)sc.len, sc.ptr);
smartcard[sizeof(smartcard) - 1] = '\0';
/* parse slot and key id. Three formats are supported:
@@ -536,7 +536,7 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
return FALSE;
}
*pos = '\0';
- strcpy(keyid, pos + 1);
+ strncpy(keyid, pos + 1, sizeof(keyid));
format = SC_FORMAT_SLOT_MODULE_KEYID;
}
else if (sscanf(smartcard, "%%smartcard%u:%s", &slot, keyid) == 2)
@@ -660,13 +660,13 @@ static bool load_private(private_stroke_cred_t *this, chunk_t line, int line_nr,
if (*filename.ptr == '/')
{
/* absolute path name */
- snprintf(path, sizeof(path), "%.*s", filename.len, filename.ptr);
+ snprintf(path, sizeof(path), "%.*s", (int)filename.len, filename.ptr);
}
else
{
/* relative path name */
snprintf(path, sizeof(path), "%s/%.*s", PRIVATE_KEY_DIR,
- filename.len, filename.ptr);
+ (int)filename.len, filename.ptr);
}
/* check for optional passphrase */
@@ -768,6 +768,8 @@ static bool load_shared(private_stroke_cred_t *this, chunk_t line, int line_nr,
if (ugh != NULL)
{
DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
+ shared_key->destroy(shared_key);
+ owners->destroy_offset(owners, offsetof(identification_t, destroy));
return FALSE;
}
if (id.len == 0)
@@ -874,7 +876,8 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level,
DBG1(DBG_CFG, "include pattern too long, ignored");
continue;
}
- snprintf(pattern, sizeof(pattern), "%.*s", line.len, line.ptr);
+ snprintf(pattern, sizeof(pattern), "%.*s",
+ (int)line.len, line.ptr);
}
else
{ /* use directory of current file if relative */
@@ -888,7 +891,7 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level,
continue;
}
snprintf(pattern, sizeof(pattern), "%s/%.*s",
- dir, line.len, line.ptr);
+ dir, (int)line.len, line.ptr);
free(dir);
}
if (glob(pattern, GLOB_ERR, NULL, &buf) != 0)
diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c
index 36311f092..6c42f8f8a 100644
--- a/src/libcharon/plugins/stroke/stroke_list.c
+++ b/src/libcharon/plugins/stroke/stroke_list.c
@@ -402,7 +402,8 @@ METHOD(stroke_list_t, status, void,
if (all)
{
peer_cfg_t *peer_cfg;
- char *plugin, *pool;
+ plugin_t *plugin;
+ char *pool;
host_t *host;
u_int32_t dpd;
time_t since, now;
@@ -431,7 +432,7 @@ METHOD(stroke_list_t, status, void,
enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
while (enumerator->enumerate(enumerator, &plugin))
{
- fprintf(out, "%s ", plugin);
+ fprintf(out, "%s ", plugin->get_name(plugin));
}
enumerator->destroy(enumerator);
fprintf(out, "\n");
@@ -1069,12 +1070,12 @@ static void print_alg(FILE *out, int *len, enum_name_t *alg_names, int alg_type,
{
char alg_name[BUF_LEN];
int alg_name_len;
-
+
alg_name_len = sprintf(alg_name, " %N[%s]", alg_names, alg_type, plugin_name);
if (*len + alg_name_len > CRYPTO_MAX_ALG_LINE)
{
fprintf(out, "\n ");
- *len = 13;
+ *len = 13;
}
fprintf(out, "%s", alg_name);
*len += alg_name_len;
diff --git a/src/libcharon/plugins/stroke/stroke_plugin.c b/src/libcharon/plugins/stroke/stroke_plugin.c
index 2e83d0d28..2884db4bf 100644
--- a/src/libcharon/plugins/stroke/stroke_plugin.c
+++ b/src/libcharon/plugins/stroke/stroke_plugin.c
@@ -36,6 +36,12 @@ struct private_stroke_plugin_t {
stroke_socket_t *socket;
};
+METHOD(plugin_t, get_name, char*,
+ private_stroke_plugin_t *this)
+{
+ return "stroke";
+}
+
METHOD(plugin_t, destroy, void,
private_stroke_plugin_t *this)
{
@@ -53,6 +59,8 @@ plugin_t *stroke_plugin_create()
INIT(this,
.public = {
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c
index 18e77905d..88d0270d8 100644
--- a/src/libcharon/plugins/stroke/stroke_socket.c
+++ b/src/libcharon/plugins/stroke/stroke_socket.c
@@ -122,7 +122,7 @@ static void pop_string(stroke_msg_t *msg, char **string)
/* check for sanity of string pointer and string */
if (string < (char**)msg ||
- string > (char**)msg + sizeof(stroke_msg_t) ||
+ string > (char**)((char*)msg + sizeof(stroke_msg_t)) ||
(unsigned long)*string < (unsigned long)((char*)msg->buffer - (char*)msg) ||
(unsigned long)*string > msg->length)
{
@@ -396,7 +396,7 @@ static void stroke_export(private_stroke_socket_t *this,
{
if (cert->get_encoding(cert, CERT_PEM, &encoded))
{
- fprintf(out, "%.*s", encoded.len, encoded.ptr);
+ fprintf(out, "%.*s", (int)encoded.len, encoded.ptr);
free(encoded.ptr);
}
}
diff --git a/src/libcharon/plugins/tnc_imc/Makefile.in b/src/libcharon/plugins/tnc_imc/Makefile.in
index dc44408ff..c2bc35dc5 100644
--- a/src/libcharon/plugins/tnc_imc/Makefile.in
+++ b/src/libcharon/plugins/tnc_imc/Makefile.in
@@ -243,6 +243,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -266,6 +268,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc.c b/src/libcharon/plugins/tnc_imc/tnc_imc.c
index 174084436..d7fc2c65d 100644
--- a/src/libcharon/plugins/tnc_imc/tnc_imc.c
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc.c
@@ -19,11 +19,12 @@
#include <debug.h>
#include <library.h>
+#include <threading/mutex.h>
typedef struct private_tnc_imc_t private_tnc_imc_t;
/**
- * Private data of an imv_t object.
+ * Private data of an imc_t object.
*/
struct private_tnc_imc_t {
@@ -61,6 +62,11 @@ struct private_tnc_imc_t {
* Number of supported message types
*/
TNC_UInt32 type_count;
+
+ /**
+ * mutex to lock the imc_t object
+ */
+ mutex_t *mutex;
};
METHOD(imc_t, set_id, void,
@@ -85,6 +91,14 @@ METHOD(imc_t, set_message_types, void,
private_tnc_imc_t *this, TNC_MessageTypeList supported_types,
TNC_UInt32 type_count)
{
+ char buf[512];
+ char *pos = buf;
+ int len = sizeof(buf);
+ int written;
+
+ /* lock the imc_t instance */
+ this->mutex->lock(this->mutex);
+
/* Free an existing MessageType list */
free(this->supported_types);
this->supported_types = NULL;
@@ -94,11 +108,27 @@ METHOD(imc_t, set_message_types, void,
if (type_count && supported_types)
{
size_t size = type_count * sizeof(TNC_MessageType);
+ int i;
+ for (i = 0; i < type_count; i++)
+ {
+ written = snprintf(pos, len, " 0x%08x", supported_types[i]);
+ if (written >= len)
+ {
+ break;
+ }
+ pos += written;
+ len -= written;
+ }
this->supported_types = malloc(size);
memcpy(this->supported_types, supported_types, size);
}
- DBG2(DBG_TNC, "IMC %u supports %u message types", this->id, type_count);
+ *pos = '\0';
+ DBG2(DBG_TNC, "IMC %u supports %u message types:%s",
+ this->id, type_count, buf);
+
+ /* lock the imc_t instance */
+ this->mutex->unlock(this->mutex);
}
METHOD(imc_t, type_supported, bool,
@@ -132,6 +162,7 @@ METHOD(imc_t, destroy, void,
private_tnc_imc_t *this)
{
dlclose(this->handle);
+ this->mutex->destroy(this->mutex);
free(this->supported_types);
free(this->name);
free(this->path);
@@ -156,6 +187,7 @@ imc_t* tnc_imc_create(char *name, char *path)
},
.name = name,
.path = path,
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
);
this->handle = dlopen(path, RTLD_LAZY);
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c b/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c
index e18f1b006..25a6a1cc4 100644
--- a/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c
@@ -28,6 +28,12 @@ TNC_Result TNC_TNCC_ReportMessageTypes(TNC_IMCID imc_id,
TNC_MessageTypeList supported_types,
TNC_UInt32 type_count)
{
+ if (!charon->imcs->is_registered(charon->imcs, imc_id))
+ {
+ DBG1(DBG_TNC, "ignoring ReportMessageTypes() from unregistered IMC %u",
+ imc_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
return charon->imcs->set_message_types(charon->imcs, imc_id,
supported_types, type_count);
}
@@ -39,6 +45,12 @@ TNC_Result TNC_TNCC_RequestHandshakeRetry(TNC_IMCID imc_id,
TNC_ConnectionID connection_id,
TNC_RetryReason reason)
{
+ if (!charon->imcs->is_registered(charon->imcs, imc_id))
+ {
+ DBG1(DBG_TNC, "ignoring RequestHandshakeRetry() from unregistered IMC %u",
+ imc_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
return charon->tnccs->request_handshake_retry(charon->tnccs, TRUE, imc_id,
connection_id, reason);
}
@@ -52,6 +64,12 @@ TNC_Result TNC_TNCC_SendMessage(TNC_IMCID imc_id,
TNC_UInt32 msg_len,
TNC_MessageType msg_type)
{
+ if (!charon->imcs->is_registered(charon->imcs, imc_id))
+ {
+ DBG1(DBG_TNC, "ignoring SendMessage() from unregistered IMC %u",
+ imc_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
return charon->tnccs->send_message(charon->tnccs, imc_id, TNC_IMVID_ANY,
connection_id, msg, msg_len, msg_type);
}
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c b/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
index aa20534f5..ccf6aea67 100644
--- a/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
@@ -77,7 +77,7 @@ METHOD(imc_manager_t, remove_, imc_t*,
private_tnc_imc_manager_t *this, TNC_IMCID id)
{
enumerator_t *enumerator;
- imc_t *imc;
+ imc_t *imc, *removed_imc = NULL;
enumerator = this->imcs->create_enumerator(this->imcs);
while (enumerator->enumerate(enumerator, &imc))
@@ -85,11 +85,34 @@ METHOD(imc_manager_t, remove_, imc_t*,
if (id == imc->get_id(imc))
{
this->imcs->remove_at(this->imcs, enumerator);
- return imc;
+ removed_imc = imc;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return removed_imc;
+}
+
+METHOD(imc_manager_t, is_registered, bool,
+ private_tnc_imc_manager_t *this, TNC_IMCID id)
+{
+ enumerator_t *enumerator;
+ imc_t *imc;
+ bool found = FALSE;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc))
+ {
+ if (id == imc->get_id(imc))
+ {
+ found = TRUE;
+ break;
}
}
enumerator->destroy(enumerator);
- return NULL;
+
+ return found;
}
METHOD(imc_manager_t, get_preferred_language, char*,
@@ -160,6 +183,7 @@ METHOD(imc_manager_t, receive_message, void,
TNC_UInt32 message_len,
TNC_MessageType message_type)
{
+ bool type_supported = FALSE;
enumerator_t *enumerator;
imc_t *imc;
@@ -168,11 +192,16 @@ METHOD(imc_manager_t, receive_message, void,
{
if (imc->receive_message && imc->type_supported(imc, message_type))
{
+ type_supported = TRUE;
imc->receive_message(imc->get_id(imc), connection_id,
message, message_len, message_type);
}
}
enumerator->destroy(enumerator);
+ if (!type_supported)
+ {
+ DBG2(DBG_TNC, "message type 0x%08x not supported by any IMC", message_type);
+ }
}
METHOD(imc_manager_t, batch_ending, void,
@@ -222,6 +251,7 @@ imc_manager_t* tnc_imc_manager_create(void)
.public = {
.add = _add,
.remove = _remove_, /* avoid name conflict with stdio.h */
+ .is_registered = _is_registered,
.get_preferred_language = _get_preferred_language,
.notify_connection_change = _notify_connection_change,
.begin_handshake = _begin_handshake,
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c
index 89888040a..bc13b8735 100644
--- a/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c
@@ -130,6 +130,12 @@ static bool load_imcs(char *filename)
}
if (!charon->imcs->add(charon->imcs, imc))
{
+ if (imc->terminate &&
+ imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS)
+ {
+ DBG1(DBG_TNC, "IMC \"%s\" not terminated successfully",
+ imc->get_name(imc));
+ }
imc->destroy(imc);
return FALSE;
}
@@ -141,6 +147,12 @@ static bool load_imcs(char *filename)
return TRUE;
}
+METHOD(plugin_t, get_name, char*,
+ tnc_imc_plugin_t *this)
+{
+ return "tnc-imc";
+}
+
METHOD(plugin_t, destroy, void,
tnc_imc_plugin_t *this)
{
@@ -158,6 +170,8 @@ plugin_t *tnc_imc_plugin_create()
INIT(this,
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
);
diff --git a/src/libcharon/plugins/tnc_imv/Makefile.in b/src/libcharon/plugins/tnc_imv/Makefile.in
index 0324d2eb9..fb96150f4 100644
--- a/src/libcharon/plugins/tnc_imv/Makefile.in
+++ b/src/libcharon/plugins/tnc_imv/Makefile.in
@@ -244,6 +244,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -267,6 +269,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv.c b/src/libcharon/plugins/tnc_imv/tnc_imv.c
index f88b645d6..fe628ee7e 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv.c
@@ -19,6 +19,7 @@
#include <debug.h>
#include <library.h>
+#include <threading/mutex.h>
typedef struct private_tnc_imv_t private_tnc_imv_t;
@@ -61,6 +62,11 @@ struct private_tnc_imv_t {
* Number of supported message types
*/
TNC_UInt32 type_count;
+
+ /**
+ * mutex to lock the imv_t object
+ */
+ mutex_t *mutex;
};
METHOD(imv_t, set_id, void,
@@ -85,6 +91,14 @@ METHOD(imv_t, set_message_types, void,
private_tnc_imv_t *this, TNC_MessageTypeList supported_types,
TNC_UInt32 type_count)
{
+ char buf[512];
+ char *pos = buf;
+ int len = sizeof(buf);
+ int written;
+
+ /* lock the imv_t instance */
+ this->mutex->lock(this->mutex);
+
/* Free an existing MessageType list */
free(this->supported_types);
this->supported_types = NULL;
@@ -95,10 +109,27 @@ METHOD(imv_t, set_message_types, void,
{
size_t size = type_count * sizeof(TNC_MessageType);
+ int i;
+
+ for (i = 0; i < type_count; i++)
+ {
+ written = snprintf(pos, len, " 0x%08x", supported_types[i]);
+ if (written >= len)
+ {
+ break;
+ }
+ pos += written;
+ len -= written;
+ }
this->supported_types = malloc(size);
memcpy(this->supported_types, supported_types, size);
}
- DBG2(DBG_TNC, "IMV %u supports %u message types", this->id, type_count);
+ *pos = '\0';
+ DBG2(DBG_TNC, "IMV %u supports %u message types:%s",
+ this->id, type_count, buf);
+
+ /* lock the imv_t instance */
+ this->mutex->unlock(this->mutex);
}
METHOD(imv_t, type_supported, bool,
@@ -132,6 +163,7 @@ METHOD(imv_t, destroy, void,
private_tnc_imv_t *this)
{
dlclose(this->handle);
+ this->mutex->destroy(this->mutex);
free(this->supported_types);
free(this->name);
free(this->path);
@@ -156,6 +188,7 @@ imv_t* tnc_imv_create(char *name, char *path)
},
.name = name,
.path = path,
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
);
this->handle = dlopen(path, RTLD_LAZY);
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c b/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c
index 0ea52f08e..0ed00b001 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c
@@ -28,6 +28,12 @@ TNC_Result TNC_TNCS_ReportMessageTypes(TNC_IMVID imv_id,
TNC_MessageTypeList supported_types,
TNC_UInt32 type_count)
{
+ if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ {
+ DBG1(DBG_TNC, "ignoring ReportMessageTypes() from unregistered IMV %u",
+ imv_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
return charon->imvs->set_message_types(charon->imvs, imv_id,
supported_types, type_count);
}
@@ -39,6 +45,12 @@ TNC_Result TNC_TNCS_RequestHandshakeRetry(TNC_IMVID imv_id,
TNC_ConnectionID connection_id,
TNC_RetryReason reason)
{
+ if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ {
+ DBG1(DBG_TNC, "ignoring RequestHandshakeRetry() from unregistered IMV %u",
+ imv_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
return charon->tnccs->request_handshake_retry(charon->tnccs, FALSE, imv_id,
connection_id, reason);
}
@@ -52,6 +64,12 @@ TNC_Result TNC_TNCS_SendMessage(TNC_IMVID imv_id,
TNC_UInt32 msg_len,
TNC_MessageType msg_type)
{
+ if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ {
+ DBG1(DBG_TNC, "ignoring SendMessage() from unregistered IMV %u",
+ imv_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
return charon->tnccs->send_message(charon->tnccs, TNC_IMCID_ANY, imv_id,
connection_id, msg, msg_len, msg_type);
}
@@ -65,6 +83,12 @@ TNC_Result TNC_TNCS_ProvideRecommendation(TNC_IMVID imv_id,
TNC_IMV_Action_Recommendation recommendation,
TNC_IMV_Evaluation_Result evaluation)
{
+ if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ {
+ DBG1(DBG_TNC, "ignoring ProvideRecommendation() from unregistered IMV %u",
+ imv_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
return charon->tnccs->provide_recommendation(charon->tnccs, imv_id,
connection_id, recommendation, evaluation);
}
@@ -80,6 +104,12 @@ TNC_Result TNC_TNCS_GetAttribute(TNC_IMVID imv_id,
TNC_BufferReference buffer,
TNC_UInt32 *out_value_len)
{
+ if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ {
+ DBG1(DBG_TNC, "ignoring GetAttribute() from unregistered IMV %u",
+ imv_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
return charon->tnccs->get_attribute(charon->tnccs, imv_id, connection_id,
attribute_id, buffer_len, buffer, out_value_len);
}
@@ -94,6 +124,12 @@ TNC_Result TNC_TNCS_SetAttribute(TNC_IMVID imv_id,
TNC_UInt32 buffer_len,
TNC_BufferReference buffer)
{
+ if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ {
+ DBG1(DBG_TNC, "ignoring SetAttribute() from unregistered IMV %u",
+ imv_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
return charon->tnccs->set_attribute(charon->tnccs, imv_id, connection_id,
attribute_id, buffer_len, buffer);
}
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
index 559de86d0..579ab06ff 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
@@ -84,7 +84,7 @@ METHOD(imv_manager_t, remove_, imv_t*,
private_tnc_imv_manager_t *this, TNC_IMVID id)
{
enumerator_t *enumerator;
- imv_t *imv;
+ imv_t *imv, *removed_imv = NULL;
enumerator = this->imvs->create_enumerator(this->imvs);
while (enumerator->enumerate(enumerator, &imv))
@@ -92,11 +92,34 @@ METHOD(imv_manager_t, remove_, imv_t*,
if (id == imv->get_id(imv))
{
this->imvs->remove_at(this->imvs, enumerator);
- return imv;
+ removed_imv = imv;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return removed_imv;
+}
+
+METHOD(imv_manager_t, is_registered, bool,
+ private_tnc_imv_manager_t *this, TNC_IMVID id)
+{
+ enumerator_t *enumerator;
+ imv_t *imv;
+ bool found = FALSE;
+
+ enumerator = this->imvs->create_enumerator(this->imvs);
+ while (enumerator->enumerate(enumerator, &imv))
+ {
+ if (id == imv->get_id(imv))
+ {
+ found = TRUE;
+ break;
}
}
enumerator->destroy(enumerator);
- return NULL;
+
+ return found;
}
METHOD(imv_manager_t, get_recommendation_policy, recommendation_policy_t,
@@ -112,36 +135,56 @@ METHOD(imv_manager_t, create_recommendations, recommendations_t*,
}
METHOD(imv_manager_t, enforce_recommendation, bool,
- private_tnc_imv_manager_t *this, TNC_IMV_Action_Recommendation rec)
+ private_tnc_imv_manager_t *this, TNC_IMV_Action_Recommendation rec,
+ TNC_IMV_Evaluation_Result eval)
{
char *group;
identification_t *id;
ike_sa_t *ike_sa;
auth_cfg_t *auth;
+ bool no_access = FALSE;
+
+ DBG1(DBG_TNC, "final recommendation is '%N' and evaluation is '%N'",
+ TNC_IMV_Action_Recommendation_names, rec,
+ TNC_IMV_Evaluation_Result_names, eval);
switch (rec)
{
case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
- DBG1(DBG_TNC, "TNC recommendation is allow");
group = "allow";
break;
case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
- DBG1(DBG_TNC, "TNC recommendation is isolate");
group = "isolate";
break;
case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
default:
- DBG1(DBG_TNC, "TNC recommendation is none");
- return FALSE;
+ group = "no access";
+ no_access = TRUE;
+ break;
}
+
ike_sa = charon->bus->get_sa(charon->bus);
- if (ike_sa)
+ if (!ike_sa)
+ {
+ DBG1(DBG_TNC, "policy enforcement point did not find IKE_SA");
+ return FALSE;
+ }
+
+ id = ike_sa->get_other_id(ike_sa);
+ DBG0(DBG_TNC, "policy enforced on peer '%Y' is '%s'", id, group);
+
+ if (no_access)
{
+ return FALSE;
+ }
+ else
+ {
auth = ike_sa->get_auth_cfg(ike_sa, FALSE);
id = identification_create_from_string(group);
auth->add(auth, AUTH_RULE_GROUP, id);
- DBG1(DBG_TNC, "TNC added group membership '%s'", group);
+ DBG1(DBG_TNC, "policy enforcement point added group membership '%s'",
+ group);
}
return TRUE;
}
@@ -208,6 +251,7 @@ METHOD(imv_manager_t, receive_message, void,
TNC_UInt32 message_len,
TNC_MessageType message_type)
{
+ bool type_supported = FALSE;
enumerator_t *enumerator;
imv_t *imv;
@@ -216,11 +260,16 @@ METHOD(imv_manager_t, receive_message, void,
{
if (imv->receive_message && imv->type_supported(imv, message_type))
{
+ type_supported = TRUE;
imv->receive_message(imv->get_id(imv), connection_id,
message, message_len, message_type);
}
}
enumerator->destroy(enumerator);
+ if (!type_supported)
+ {
+ DBG2(DBG_TNC, "message type 0x%08x not supported by any IMV", message_type);
+ }
}
METHOD(imv_manager_t, batch_ending, void,
@@ -271,6 +320,7 @@ imv_manager_t* tnc_imv_manager_create(void)
.public = {
.add = _add,
.remove = _remove_, /* avoid name conflict with stdio.h */
+ .is_registered = _is_registered,
.get_recommendation_policy = _get_recommendation_policy,
.create_recommendations = _create_recommendations,
.enforce_recommendation = _enforce_recommendation,
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
index f238f01ea..45cf95c1b 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
@@ -130,6 +130,12 @@ static bool load_imvs(char *filename)
}
if (!charon->imvs->add(charon->imvs, imv))
{
+ if (imv->terminate &&
+ imv->terminate(imv->get_id(imv)) != TNC_RESULT_SUCCESS)
+ {
+ DBG1(DBG_TNC, "IMV \"%s\" not terminated successfully",
+ imv->get_name(imv));
+ }
imv->destroy(imv);
return FALSE;
}
@@ -141,6 +147,12 @@ static bool load_imvs(char *filename)
return TRUE;
}
+METHOD(plugin_t, get_name, char*,
+ tnc_imv_plugin_t *this)
+{
+ return "tnc-imv";
+}
+
METHOD(plugin_t, destroy, void,
tnc_imv_plugin_t *this)
{
@@ -158,6 +170,8 @@ plugin_t *tnc_imv_plugin_create()
INIT(this,
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
);
diff --git a/src/libcharon/plugins/tnccs_11/Makefile.in b/src/libcharon/plugins/tnccs_11/Makefile.in
index 5ab7ccbca..308dd57ca 100644
--- a/src/libcharon/plugins/tnccs_11/Makefile.in
+++ b/src/libcharon/plugins/tnccs_11/Makefile.in
@@ -247,6 +247,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -270,6 +272,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/tnccs_11/tnccs_11.c b/src/libcharon/plugins/tnccs_11/tnccs_11.c
index 2104bf401..86f1c269f 100644
--- a/src/libcharon/plugins/tnccs_11/tnccs_11.c
+++ b/src/libcharon/plugins/tnccs_11/tnccs_11.c
@@ -77,6 +77,11 @@ struct private_tnccs_11_t {
bool delete_state;
/**
+ * SendMessage() by IMC/IMV only allowed if flag is set
+ */
+ bool send_msg;
+
+ /**
* Flag set by IMC/IMV RequestHandshakeRetry() function
*/
bool request_handshake_retry;
@@ -87,7 +92,7 @@ struct private_tnccs_11_t {
recommendations_t *recs;
};
-METHOD(tnccs_t, send_msg, void,
+METHOD(tnccs_t, send_msg, TNC_Result,
private_tnccs_11_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id,
TNC_BufferReference msg,
TNC_UInt32 msg_len,
@@ -95,6 +100,13 @@ METHOD(tnccs_t, send_msg, void,
{
tnccs_msg_t *tnccs_msg;
+ if (!this->send_msg)
+ {
+ DBG1(DBG_TNC, "%s %u not allowed to call SendMessage()",
+ this->is_server ? "IMV" : "IMC",
+ this->is_server ? imv_id : imc_id);
+ return TNC_RESULT_ILLEGAL_OPERATION;
+ }
tnccs_msg = imc_imv_msg_create(msg_type, chunk_create(msg, msg_len));
/* adding an IMC-IMV Message to TNCCS batch */
@@ -105,6 +117,7 @@ METHOD(tnccs_t, send_msg, void,
}
this->batch->add_msg(this->batch, tnccs_msg);
this->mutex->unlock(this->mutex);
+ return TNC_RESULT_SUCCESS;
}
/**
@@ -126,6 +139,7 @@ static void handle_message(private_tnccs_11_t *this, tnccs_msg_t *msg)
DBG2(DBG_TNC, "handling IMC_IMV message type 0x%08x", msg_type);
+ this->send_msg = TRUE;
if (this->is_server)
{
charon->imvs->receive_message(charon->imvs,
@@ -136,6 +150,7 @@ static void handle_message(private_tnccs_11_t *this, tnccs_msg_t *msg)
charon->imcs->receive_message(charon->imcs,
this->connection_id, msg_body.ptr, msg_body.len,msg_type);
}
+ this->send_msg = FALSE;
break;
}
case TNCCS_MSG_RECOMMENDATION:
@@ -237,6 +252,8 @@ METHOD(tls_t, process, status_t,
}
charon->imvs->notify_connection_change(charon->imvs,
this->connection_id, TNC_CONNECTION_STATE_CREATE);
+ charon->imvs->notify_connection_change(charon->imvs,
+ this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
}
data = chunk_create(buf, buflen);
@@ -284,6 +301,7 @@ METHOD(tls_t, process, status_t,
return FAILED;
}
+ this->send_msg = TRUE;
if (this->is_server)
{
charon->imvs->batch_ending(charon->imvs, this->connection_id);
@@ -292,6 +310,7 @@ METHOD(tls_t, process, status_t,
{
charon->imcs->batch_ending(charon->imcs, this->connection_id);
}
+ this->send_msg = FALSE;
}
batch->destroy(batch);
@@ -369,13 +388,15 @@ METHOD(tls_t, build, status_t,
this->connection_id, TNC_CONNECTION_STATE_CREATE);
charon->imcs->notify_connection_change(charon->imcs,
this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
+ this->send_msg = TRUE;
charon->imcs->begin_handshake(charon->imcs, this->connection_id);
+ this->send_msg = FALSE;
}
/* Do not allow any asynchronous IMCs or IMVs to add additional messages */
this->mutex->lock(this->mutex);
- if (this->is_server && !this->delete_state &&
+ if (this->recs && !this->delete_state &&
(!this->batch || this->fatal_error))
{
check_and_build_recommendation(this);
@@ -435,11 +456,7 @@ METHOD(tls_t, is_complete, bool,
if (this->recs && this->recs->have_recommendation(this->recs, &rec, &eval))
{
- DBG2(DBG_TNC, "Final recommendation is '%N' and evaluation is '%N'",
- TNC_IMV_Action_Recommendation_names, rec,
- TNC_IMV_Evaluation_Result_names, eval);
-
- return charon->imvs->enforce_recommendation(charon->imvs, rec);
+ return charon->imvs->enforce_recommendation(charon->imvs, rec, eval);
}
else
{
@@ -456,17 +473,8 @@ METHOD(tls_t, get_eap_msk, chunk_t,
METHOD(tls_t, destroy, void,
private_tnccs_11_t *this)
{
- if (this->is_server)
- {
- charon->imvs->notify_connection_change(charon->imvs,
- this->connection_id, TNC_CONNECTION_STATE_DELETE);
- }
- else
- {
- charon->imcs->notify_connection_change(charon->imcs,
- this->connection_id, TNC_CONNECTION_STATE_DELETE);
- }
- charon->tnccs->remove_connection(charon->tnccs, this->connection_id);
+ charon->tnccs->remove_connection(charon->tnccs, this->connection_id,
+ this->is_server);
this->mutex->destroy(this->mutex);
DESTROY_IF(this->batch);
free(this);
diff --git a/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c b/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c
index 03905ca37..9ec91f006 100644
--- a/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c
+++ b/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c
@@ -18,6 +18,12 @@
#include <daemon.h>
+METHOD(plugin_t, get_name, char*,
+ tnccs_11_plugin_t *this)
+{
+ return "tnccs-11";
+}
+
METHOD(plugin_t, destroy, void,
tnccs_11_plugin_t *this)
{
@@ -35,11 +41,13 @@ plugin_t *tnccs_11_plugin_create()
INIT(this,
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
);
- charon->tnccs->add_method(charon->tnccs, TNCCS_1_1,
+ charon->tnccs->add_method(charon->tnccs, TNCCS_1_1,
(tnccs_constructor_t)tnccs_11_create);
return &this->plugin;
diff --git a/src/libcharon/plugins/tnccs_20/Makefile.in b/src/libcharon/plugins/tnccs_20/Makefile.in
index 9853be338..bbfcc2760 100644
--- a/src/libcharon/plugins/tnccs_20/Makefile.in
+++ b/src/libcharon/plugins/tnccs_20/Makefile.in
@@ -249,6 +249,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -272,6 +274,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.c b/src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.c
index a46dc0ab9..f0cf14ac1 100644
--- a/src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.c
+++ b/src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.c
@@ -107,7 +107,8 @@ METHOD(pb_tnc_state_machine_t, receive_batch, bool,
}
return FALSE;
case PB_STATE_SERVER_WORKING:
- if (!this->is_server && type == PB_BATCH_SDATA)
+ if (!this->is_server && (type == PB_BATCH_SDATA ||
+ type == PB_BATCH_SRETRY))
{
this->state = PB_STATE_CLIENT_WORKING;
break;
@@ -117,8 +118,7 @@ METHOD(pb_tnc_state_machine_t, receive_batch, bool,
this->state = PB_STATE_DECIDED;
break;
}
- if ((this->is_server && type == PB_BATCH_CRETRY) ||
- (!this->is_server && type == PB_BATCH_SRETRY))
+ if (this->is_server && type == PB_BATCH_CRETRY)
{
break;
}
@@ -198,7 +198,8 @@ METHOD(pb_tnc_state_machine_t, send_batch, bool,
}
return FALSE;
case PB_STATE_SERVER_WORKING:
- if (this->is_server && type == PB_BATCH_SDATA)
+ if (this->is_server && (type == PB_BATCH_SDATA ||
+ type == PB_BATCH_SRETRY))
{
this->state = PB_STATE_CLIENT_WORKING;
break;
@@ -208,7 +209,7 @@ METHOD(pb_tnc_state_machine_t, send_batch, bool,
this->state = PB_STATE_DECIDED;
break;
}
- if (this->is_server && type == PB_BATCH_SRETRY)
+ if (!this->is_server && type == PB_BATCH_CRETRY)
{
break;
}
@@ -219,11 +220,16 @@ METHOD(pb_tnc_state_machine_t, send_batch, bool,
}
return FALSE;
case PB_STATE_CLIENT_WORKING:
- if (!this->is_server && type == PB_BATCH_CDATA)
+ if (!this->is_server && (type == PB_BATCH_CDATA ||
+ type == PB_BATCH_CRETRY))
{
this->state = PB_STATE_SERVER_WORKING;
break;
}
+ if (this->is_server && type == PB_BATCH_SRETRY)
+ {
+ break;
+ }
if (type == PB_BATCH_CLOSE)
{
this->state = PB_STATE_END;
diff --git a/src/libcharon/plugins/tnccs_20/tnccs_20.c b/src/libcharon/plugins/tnccs_20/tnccs_20.c
index d53fd8eb7..9e2081d46 100644
--- a/src/libcharon/plugins/tnccs_20/tnccs_20.c
+++ b/src/libcharon/plugins/tnccs_20/tnccs_20.c
@@ -81,12 +81,17 @@ struct private_tnccs_20_t {
bool request_handshake_retry;
/**
+ * SendMessage() by IMC/IMV only allowed if flag is set
+ */
+ bool send_msg;
+
+ /**
* Set of IMV recommendations (TNC Server only)
*/
recommendations_t *recs;
};
-METHOD(tnccs_t, send_msg, void,
+METHOD(tnccs_t, send_msg, TNC_Result,
private_tnccs_20_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id,
TNC_BufferReference msg,
TNC_UInt32 msg_len,
@@ -97,6 +102,14 @@ METHOD(tnccs_t, send_msg, void,
pb_tnc_msg_t *pb_tnc_msg;
pb_tnc_batch_type_t batch_type;
+ if (!this->send_msg)
+ {
+ DBG1(DBG_TNC, "%s %u not allowed to call SendMessage()",
+ this->is_server ? "IMV" : "IMC",
+ this->is_server ? imv_id : imc_id);
+ return TNC_RESULT_ILLEGAL_OPERATION;
+ }
+
msg_sub_type = msg_type & TNC_SUBTYPE_ANY;
msg_vendor_id = (msg_type >> 8) & TNC_VENDORID_ANY;
@@ -119,6 +132,7 @@ METHOD(tnccs_t, send_msg, void,
pb_tnc_msg->destroy(pb_tnc_msg);
}
this->mutex->unlock(this->mutex);
+ return TNC_RESULT_SUCCESS;
}
/**
@@ -145,6 +159,7 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
DBG2(DBG_TNC, "handling PB-PA message type 0x%08x", msg_type);
+ this->send_msg = TRUE;
if (this->is_server)
{
charon->imvs->receive_message(charon->imvs,
@@ -155,6 +170,7 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
charon->imcs->receive_message(charon->imcs,
this->connection_id, msg_body.ptr, msg_body.len,msg_type);
}
+ this->send_msg = FALSE;
break;
}
case PB_MSG_ASSESSMENT_RESULT:
@@ -289,14 +305,21 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
*/
static void build_retry_batch(private_tnccs_20_t *this)
{
+ pb_tnc_batch_type_t batch_retry_type;
+
+ batch_retry_type = this->is_server ? PB_BATCH_SRETRY : PB_BATCH_CRETRY;
if (this->batch)
{
+ if (this->batch->get_type(this->batch) == batch_retry_type)
+ {
+ /* retry batch has already been created */
+ return;
+ }
DBG1(DBG_TNC, "cancelling PB-TNC %N batch",
pb_tnc_batch_type_names, this->batch->get_type(this->batch));
this->batch->destroy(this->batch);
}
- this->batch = pb_tnc_batch_create(this->is_server,
- this->is_server ? PB_BATCH_SRETRY : PB_BATCH_CRETRY);
+ this->batch = pb_tnc_batch_create(this->is_server, batch_retry_type);
}
METHOD(tls_t, process, status_t,
@@ -319,6 +342,8 @@ METHOD(tls_t, process, status_t,
}
charon->imvs->notify_connection_change(charon->imvs,
this->connection_id, TNC_CONNECTION_STATE_CREATE);
+ charon->imvs->notify_connection_change(charon->imvs,
+ this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
}
data = chunk_create(buf, buflen);
@@ -349,7 +374,9 @@ METHOD(tls_t, process, status_t,
/* Restart the measurements */
charon->imcs->notify_connection_change(charon->imcs,
this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
+ this->send_msg = TRUE;
charon->imcs->begin_handshake(charon->imcs, this->connection_id);
+ this->send_msg = FALSE;
}
enumerator = batch->create_msg_enumerator(batch);
@@ -376,6 +403,7 @@ METHOD(tls_t, process, status_t,
}
}
+ this->send_msg = TRUE;
if (this->is_server)
{
charon->imvs->batch_ending(charon->imvs, this->connection_id);
@@ -384,6 +412,7 @@ METHOD(tls_t, process, status_t,
{
charon->imcs->batch_ending(charon->imcs, this->connection_id);
}
+ this->send_msg = FALSE;
}
switch (status)
@@ -463,6 +492,7 @@ METHOD(tls_t, build, status_t,
private_tnccs_20_t *this, void *buf, size_t *buflen, size_t *msglen)
{
status_t status;
+ pb_tnc_state_t state;
/* Initialize the connection */
if (!this->is_server && !this->connection_id)
@@ -491,11 +521,14 @@ METHOD(tls_t, build, status_t,
this->connection_id, TNC_CONNECTION_STATE_CREATE);
charon->imcs->notify_connection_change(charon->imcs,
this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
+ this->send_msg = TRUE;
charon->imcs->begin_handshake(charon->imcs, this->connection_id);
+ this->send_msg = FALSE;
}
- if (this->is_server && this->fatal_error &&
- this->state_machine->get_state(this->state_machine) == PB_STATE_END)
+ state = this->state_machine->get_state(this->state_machine);
+
+ if (this->is_server && this->fatal_error && state == PB_STATE_END)
{
DBG1(DBG_TNC, "a fatal PB-TNC error occurred, terminating connection");
return FAILED;
@@ -506,7 +539,10 @@ METHOD(tls_t, build, status_t,
if (this->request_handshake_retry)
{
- build_retry_batch(this);
+ if (state != PB_STATE_INIT)
+ {
+ build_retry_batch(this);
+ }
/* Reset the flag for the next handshake retry request */
this->request_handshake_retry = FALSE;
@@ -514,9 +550,6 @@ METHOD(tls_t, build, status_t,
if (!this->batch)
{
- pb_tnc_state_t state;
-
- state = this->state_machine->get_state(this->state_machine);
if (this->is_server)
{
if (state == PB_STATE_SERVER_WORKING)
@@ -606,11 +639,7 @@ METHOD(tls_t, is_complete, bool,
if (this->recs && this->recs->have_recommendation(this->recs, &rec, &eval))
{
- DBG2(DBG_TNC, "Final recommendation is '%N' and evaluation is '%N'",
- TNC_IMV_Action_Recommendation_names, rec,
- TNC_IMV_Evaluation_Result_names, eval);
-
- return charon->imvs->enforce_recommendation(charon->imvs, rec);
+ return charon->imvs->enforce_recommendation(charon->imvs, rec, eval);
}
else
{
@@ -627,17 +656,8 @@ METHOD(tls_t, get_eap_msk, chunk_t,
METHOD(tls_t, destroy, void,
private_tnccs_20_t *this)
{
- if (this->is_server)
- {
- charon->imvs->notify_connection_change(charon->imvs,
- this->connection_id, TNC_CONNECTION_STATE_DELETE);
- }
- else
- {
- charon->imcs->notify_connection_change(charon->imcs,
- this->connection_id, TNC_CONNECTION_STATE_DELETE);
- }
- charon->tnccs->remove_connection(charon->tnccs, this->connection_id);
+ charon->tnccs->remove_connection(charon->tnccs, this->connection_id,
+ this->is_server);
this->state_machine->destroy(this->state_machine);
this->mutex->destroy(this->mutex);
DESTROY_IF(this->batch);
diff --git a/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c b/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c
index 82c78f74c..e6dc699e6 100644
--- a/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c
+++ b/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c
@@ -18,6 +18,12 @@
#include <daemon.h>
+METHOD(plugin_t, get_name, char*,
+ tnccs_20_plugin_t *this)
+{
+ return "tnccs-20";
+}
+
METHOD(plugin_t, destroy, void,
tnccs_20_plugin_t *this)
{
@@ -35,11 +41,13 @@ plugin_t *tnccs_20_plugin_create()
INIT(this,
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
);
- charon->tnccs->add_method(charon->tnccs, TNCCS_2_0,
+ charon->tnccs->add_method(charon->tnccs, TNCCS_2_0,
(tnccs_constructor_t)tnccs_20_create);
return &this->plugin;
diff --git a/src/libcharon/plugins/tnccs_dynamic/Makefile.in b/src/libcharon/plugins/tnccs_dynamic/Makefile.in
index 722da2830..dda1472db 100644
--- a/src/libcharon/plugins/tnccs_dynamic/Makefile.in
+++ b/src/libcharon/plugins/tnccs_dynamic/Makefile.in
@@ -245,6 +245,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -268,6 +270,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c
index dbbf222e0..089a3ed57 100644
--- a/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c
+++ b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c
@@ -18,6 +18,12 @@
#include <daemon.h>
+METHOD(plugin_t, get_name, char*,
+ tnccs_dynamic_plugin_t *this)
+{
+ return "tnccs-dynamic";
+}
+
METHOD(plugin_t, destroy, void,
tnccs_dynamic_plugin_t *this)
{
@@ -35,11 +41,13 @@ plugin_t *tnccs_dynamic_plugin_create()
INIT(this,
.plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
.destroy = _destroy,
},
);
- charon->tnccs->add_method(charon->tnccs, TNCCS_DYNAMIC,
+ charon->tnccs->add_method(charon->tnccs, TNCCS_DYNAMIC,
(tnccs_constructor_t)tnccs_dynamic_create);
return &this->plugin;
diff --git a/src/libcharon/plugins/uci/Makefile.in b/src/libcharon/plugins/uci/Makefile.in
index f7162d800..013ceb7da 100644
--- a/src/libcharon/plugins/uci/Makefile.in
+++ b/src/libcharon/plugins/uci/Makefile.in
@@ -241,6 +241,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -264,6 +266,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/uci/uci_plugin.c b/src/libcharon/plugins/uci/uci_plugin.c
index 4790ef4e7..a6d24c32b 100644
--- a/src/libcharon/plugins/uci/uci_plugin.c
+++ b/src/libcharon/plugins/uci/uci_plugin.c
@@ -58,10 +58,14 @@ struct private_uci_plugin_t {
uci_control_t *control;
};
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(private_uci_plugin_t *this)
+METHOD(plugin_t, get_name, char*,
+ private_uci_plugin_t *this)
+{
+ return "uci";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_uci_plugin_t *this)
{
charon->backends->remove_backend(charon->backends, &this->config->backend);
lib->credmgr->remove_set(lib->credmgr, &this->creds->credential_set);
@@ -77,14 +81,22 @@ static void destroy(private_uci_plugin_t *this)
*/
plugin_t *uci_plugin_create()
{
- private_uci_plugin_t *this = malloc_thing(private_uci_plugin_t);
-
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+ private_uci_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ .parser = uci_parser_create(UCI_PACKAGE),
+ .config = uci_config_create(this->parser),
+ .creds = uci_creds_create(this->parser),
+ .control = uci_control_create(),
+ );
- this->parser = uci_parser_create(UCI_PACKAGE);
- this->config = uci_config_create(this->parser);
- this->creds = uci_creds_create(this->parser);
- this->control = uci_control_create();
charon->backends->add_backend(charon->backends, &this->config->backend);
lib->credmgr->add_set(lib->credmgr, &this->creds->credential_set);
diff --git a/src/libcharon/plugins/unit_tester/Makefile.in b/src/libcharon/plugins/unit_tester/Makefile.in
index 5fa749e56..2fee3da82 100644
--- a/src/libcharon/plugins/unit_tester/Makefile.in
+++ b/src/libcharon/plugins/unit_tester/Makefile.in
@@ -247,6 +247,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -270,6 +272,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/unit_tester/unit_tester.c b/src/libcharon/plugins/unit_tester/unit_tester.c
index 5f6f94e03..ad7dba7a5 100644
--- a/src/libcharon/plugins/unit_tester/unit_tester.c
+++ b/src/libcharon/plugins/unit_tester/unit_tester.c
@@ -92,10 +92,14 @@ static void run_tests(private_unit_tester_t *this)
success, run, failed, skipped);
}
-/**
- * Implementation of 2007_t.destroy
- */
-static void destroy(private_unit_tester_t *this)
+METHOD(plugin_t, get_name, char*,
+ private_unit_tester_t *this)
+{
+ return "unit-tester";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_unit_tester_t *this)
{
free(this);
}
@@ -105,9 +109,17 @@ static void destroy(private_unit_tester_t *this)
*/
plugin_t *unit_tester_plugin_create()
{
- private_unit_tester_t *this = malloc_thing(private_unit_tester_t);
-
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+ private_unit_tester_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ );
run_tests(this);
diff --git a/src/libcharon/plugins/updown/Makefile.in b/src/libcharon/plugins/updown/Makefile.in
index 5dd2dc843..49cffe218 100644
--- a/src/libcharon/plugins/updown/Makefile.in
+++ b/src/libcharon/plugins/updown/Makefile.in
@@ -243,6 +243,8 @@ nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
@@ -266,6 +268,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
diff --git a/src/libcharon/plugins/updown/updown_plugin.c b/src/libcharon/plugins/updown/updown_plugin.c
index 9d0591e62..2ce2d3257 100644
--- a/src/libcharon/plugins/updown/updown_plugin.c
+++ b/src/libcharon/plugins/updown/updown_plugin.c
@@ -36,10 +36,14 @@ struct private_updown_plugin_t {
updown_listener_t *listener;
};
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(private_updown_plugin_t *this)
+METHOD(plugin_t, get_name, char*,
+ private_updown_plugin_t *this)
+{
+ return "updown";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_updown_plugin_t *this)
{
charon->bus->remove_listener(charon->bus, &this->listener->listener);
this->listener->destroy(this->listener);
@@ -51,11 +55,19 @@ static void destroy(private_updown_plugin_t *this)
*/
plugin_t *updown_plugin_create()
{
- private_updown_plugin_t *this = malloc_thing(private_updown_plugin_t);
+ private_updown_plugin_t *this;
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ .listener = updown_listener_create(),
+ );
- this->listener = updown_listener_create();
charon->bus->add_listener(charon->bus, &this->listener->listener);
return &this->public.plugin;
diff --git a/src/libcharon/plugins/whitelist/Makefile.am b/src/libcharon/plugins/whitelist/Makefile.am
new file mode 100644
index 000000000..064a759dd
--- /dev/null
+++ b/src/libcharon/plugins/whitelist/Makefile.am
@@ -0,0 +1,21 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = -rdynamic \
+ -DIPSEC_PIDDIR=\"${piddir}\"
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-whitelist.la
+else
+plugin_LTLIBRARIES = libstrongswan-whitelist.la
+endif
+
+libstrongswan_whitelist_la_SOURCES = whitelist_plugin.h whitelist_plugin.c \
+ whitelist_listener.h whitelist_listener.c whitelist_msg.h \
+ whitelist_control.h whitelist_control.c
+
+libstrongswan_whitelist_la_LDFLAGS = -module -avoid-version
+
+ipsec_PROGRAMS = whitelist
+whitelist_SOURCES = whitelist.c
diff --git a/src/libcharon/plugins/whitelist/Makefile.in b/src/libcharon/plugins/whitelist/Makefile.in
new file mode 100644
index 000000000..37ae5f9c3
--- /dev/null
+++ b/src/libcharon/plugins/whitelist/Makefile.in
@@ -0,0 +1,668 @@
+# Makefile.in generated by automake 1.11.1 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.
+# 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+ipsec_PROGRAMS = whitelist$(EXEEXT)
+subdir = src/libcharon/plugins/whitelist
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.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
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(ipsecdir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+libstrongswan_whitelist_la_LIBADD =
+am_libstrongswan_whitelist_la_OBJECTS = whitelist_plugin.lo \
+ whitelist_listener.lo whitelist_control.lo
+libstrongswan_whitelist_la_OBJECTS = \
+ $(am_libstrongswan_whitelist_la_OBJECTS)
+libstrongswan_whitelist_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_whitelist_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_whitelist_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_whitelist_la_rpath =
+PROGRAMS = $(ipsec_PROGRAMS)
+am_whitelist_OBJECTS = whitelist.$(OBJEXT)
+whitelist_OBJECTS = $(am_whitelist_OBJECTS)
+whitelist_LDADD = $(LDADD)
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+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)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_whitelist_la_SOURCES) $(whitelist_SOURCES)
+DIST_SOURCES = $(libstrongswan_whitelist_la_SOURCES) \
+ $(whitelist_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREADLIB = @PTHREADLIB@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+default_pkcs11 = @default_pkcs11@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
+libdir = @libdir@
+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@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+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
+
+AM_CFLAGS = -rdynamic \
+ -DIPSEC_PIDDIR=\"${piddir}\"
+
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-whitelist.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-whitelist.la
+libstrongswan_whitelist_la_SOURCES = whitelist_plugin.h whitelist_plugin.c \
+ whitelist_listener.h whitelist_listener.c whitelist_msg.h \
+ whitelist_control.h whitelist_control.c
+
+libstrongswan_whitelist_la_LDFLAGS = -module -avoid-version
+whitelist_SOURCES = whitelist.c
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/whitelist/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/whitelist/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+ }
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstrongswan-whitelist.la: $(libstrongswan_whitelist_la_OBJECTS) $(libstrongswan_whitelist_la_DEPENDENCIES)
+ $(libstrongswan_whitelist_la_LINK) $(am_libstrongswan_whitelist_la_rpath) $(libstrongswan_whitelist_la_OBJECTS) $(libstrongswan_whitelist_la_LIBADD) $(LIBS)
+install-ipsecPROGRAMS: $(ipsec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(ipsecdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsecdir)"
+ @list='$(ipsec_PROGRAMS)'; test -n "$(ipsecdir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(ipsecdir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(ipsecdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-ipsecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ipsec_PROGRAMS)'; test -n "$(ipsecdir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(ipsecdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(ipsecdir)" && rm -f $$files
+
+clean-ipsecPROGRAMS:
+ @list='$(ipsec_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+whitelist$(EXEEXT): $(whitelist_OBJECTS) $(whitelist_DEPENDENCIES)
+ @rm -f whitelist$(EXEEXT)
+ $(LINK) $(whitelist_OBJECTS) $(whitelist_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/whitelist.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/whitelist_control.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/whitelist_listener.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/whitelist_plugin.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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(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@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(ipsecdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-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
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-ipsecPROGRAMS clean-libtool \
+ clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-ipsecPROGRAMS install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-ipsecPROGRAMS uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-ipsecPROGRAMS clean-libtool clean-noinstLTLIBRARIES \
+ clean-pluginLTLIBRARIES ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-ipsecPROGRAMS install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-ipsecPROGRAMS \
+ uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/whitelist/whitelist.c b/src/libcharon/plugins/whitelist/whitelist.c
new file mode 100644
index 000000000..5f511f2c5
--- /dev/null
+++ b/src/libcharon/plugins/whitelist/whitelist.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 "whitelist_msg.h"
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <errno.h>
+
+/**
+ * Connect to the daemon, return FD
+ */
+static int make_connection()
+{
+ struct sockaddr_un addr;
+ int fd;
+
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path, WHITELIST_SOCKET);
+
+ fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+ if (fd < 0)
+ {
+ fprintf(stderr, "opening socket failed: %s\n", strerror(errno));
+ return -1;
+ }
+ if (connect(fd, (struct sockaddr *)&addr,
+ offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path)) < 0)
+ {
+ fprintf(stderr, "connecting to %s failed: %s\n",
+ WHITELIST_SOCKET, strerror(errno));
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+/**
+ * Send a single message
+ */
+static int send_msg(int type, char *id)
+{
+ whitelist_msg_t msg = {
+ .type = type,
+ };
+ int fd;
+
+ fd = make_connection();
+ if (fd == -1)
+ {
+ return 2;
+ }
+ snprintf(msg.id, sizeof(msg.id), "%s", id);
+ if (send(fd, &msg, sizeof(msg), 0) != sizeof(msg))
+ {
+ fprintf(stderr, "writing to socket failed: %s\n", strerror(errno));
+ close(fd);
+ return 2;
+ }
+ if (type == WHITELIST_LIST)
+ {
+ while (recv(fd, &msg, sizeof(msg), 0) == sizeof(msg))
+ {
+ if (msg.type != WHITELIST_LIST)
+ {
+ break;
+ }
+ printf("%s\n", msg.id);
+ }
+ }
+ close(fd);
+ return 0;
+}
+
+/**
+ * Send a batch of messages, reading identities from a file
+ */
+static int send_batch(int type, char *file)
+{
+ whitelist_msg_t msg = {
+ .type = type,
+ };
+ FILE *f = stdin;
+ int fd, len;
+
+ fd = make_connection();
+ if (fd == -1)
+ {
+ return 2;
+ }
+ if (file)
+ {
+ f = fopen(file, "r");
+ if (f == NULL)
+ {
+ fprintf(stderr, "opening %s failed: %s\n", file, strerror(errno));
+ close(fd);
+ return 3;
+ }
+ }
+ while (fgets(msg.id, sizeof(msg.id), f))
+ {
+ len = strlen(msg.id);
+ if (len == 0)
+ {
+ continue;
+ }
+ if (msg.id[len-1] == '\n')
+ {
+ msg.id[len-1] = '\0';
+ }
+ if (send(fd, &msg, sizeof(msg), 0) != sizeof(msg))
+ {
+ fprintf(stderr, "writing to socket failed: %s\n", strerror(errno));
+ if (f != stdin)
+ {
+ fclose(f);
+ }
+ close(fd);
+ return 2;
+ }
+ }
+ if (f != stdin)
+ {
+ fclose(f);
+ }
+ close(fd);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc == 3 && strcmp(argv[1], "add") == 0)
+ {
+ return send_msg(WHITELIST_ADD, argv[2]);
+ }
+ if (argc == 3 && strcmp(argv[1], "remove") == 0)
+ {
+ return send_msg(WHITELIST_REMOVE, argv[2]);
+ }
+ if ((argc == 2 || argc == 3) && strcmp(argv[1], "add-from") == 0)
+ {
+ return send_batch(WHITELIST_ADD, argc == 3 ? argv[2] : NULL);
+ }
+ if ((argc == 2 || argc == 3) && strcmp(argv[1], "remove-from") == 0)
+ {
+ return send_batch(WHITELIST_REMOVE, argc == 3 ? argv[2] : NULL);
+ }
+ if ((argc == 2 || argc == 3) && strcmp(argv[1], "flush") == 0)
+ {
+ return send_msg(WHITELIST_FLUSH, argc == 3 ? argv[2] : "%any");
+ }
+ if ((argc == 2 || argc == 3) && strcmp(argv[1], "list") == 0)
+ {
+ return send_msg(WHITELIST_LIST, argc == 3 ? argv[2] : "%any");
+ }
+ if (argc == 2 && strcmp(argv[1], "enable") == 0)
+ {
+ return send_msg(WHITELIST_ENABLE, "");
+ }
+ if (argc == 2 && strcmp(argv[1], "disable") == 0)
+ {
+ return send_msg(WHITELIST_DISABLE, "");
+ }
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s add <identity>\n", argv[0]);
+ fprintf(stderr, " %s remove <identity>\n", argv[0]);
+ fprintf(stderr, " %s add-from <file>\n", argv[0]);
+ fprintf(stderr, " %s remove-from <file>\n", argv[0]);
+ fprintf(stderr, " %s flush [<pattern>]\n", argv[0]);
+ fprintf(stderr, " %s list [<pattern>]\n", argv[0]);
+ fprintf(stderr, " %s enable\n", argv[0]);
+ fprintf(stderr, " %s disable\n", argv[0]);
+ return 1;
+}
diff --git a/src/libcharon/plugins/whitelist/whitelist_control.c b/src/libcharon/plugins/whitelist/whitelist_control.c
new file mode 100644
index 000000000..4a1fc5d87
--- /dev/null
+++ b/src/libcharon/plugins/whitelist/whitelist_control.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 "whitelist_control.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <daemon.h>
+#include <threading/thread.h>
+#include <processing/jobs/callback_job.h>
+
+#include "whitelist_msg.h"
+
+typedef struct private_whitelist_control_t private_whitelist_control_t;
+
+/**
+ * Private data of an whitelist_control_t object.
+ */
+struct private_whitelist_control_t {
+
+ /**
+ * Public whitelist_control_t interface.
+ */
+ whitelist_control_t public;
+
+ /**
+ * Whitelist
+ */
+ whitelist_listener_t *listener;
+
+ /**
+ * Whitelist unix socket file descriptor
+ */
+ int socket;
+
+ /**
+ * Callback job dispatching commands
+ */
+ callback_job_t *job;
+};
+
+/**
+ * Open whitelist unix socket
+ */
+static bool open_socket(private_whitelist_control_t *this)
+{
+ struct sockaddr_un addr;
+ mode_t old;
+
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path, WHITELIST_SOCKET);
+
+ this->socket = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+ if (this->socket == -1)
+ {
+ DBG1(DBG_CFG, "creating whitelist socket failed");
+ return FALSE;
+ }
+ unlink(addr.sun_path);
+ old = umask(~(S_IRWXU | S_IRWXG));
+ if (bind(this->socket, (struct sockaddr*)&addr, sizeof(addr)) < 0)
+ {
+ DBG1(DBG_CFG, "binding whitelist socket failed: %s", strerror(errno));
+ close(this->socket);
+ return FALSE;
+ }
+ umask(old);
+ if (chown(addr.sun_path, charon->uid, charon->gid) != 0)
+ {
+ DBG1(DBG_CFG, "changing whitelist socket permissions failed: %s",
+ strerror(errno));
+ }
+ if (listen(this->socket, 10) < 0)
+ {
+ DBG1(DBG_CFG, "listening on whitelist socket failed: %s", strerror(errno));
+ close(this->socket);
+ unlink(addr.sun_path);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Dispatch a received message
+ */
+static void dispatch(private_whitelist_control_t *this,
+ int fd, whitelist_msg_t *msg)
+{
+ identification_t *id, *current;
+ enumerator_t *enumerator;
+
+ msg->id[sizeof(msg->id)-1] = 0;
+ id = identification_create_from_string(msg->id);
+ switch (msg->type)
+ {
+ case WHITELIST_ADD:
+ this->listener->add(this->listener, id);
+ break;
+ case WHITELIST_REMOVE:
+ this->listener->remove(this->listener, id);
+ break;
+ case WHITELIST_LIST:
+ enumerator = this->listener->create_enumerator(this->listener);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (current->matches(current, id))
+ {
+ snprintf(msg->id, sizeof(msg->id), "%Y", current);
+ if (send(fd, msg, sizeof(*msg), 0) != sizeof(*msg))
+ {
+ DBG1(DBG_CFG, "listing whitelist failed");
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ msg->type = WHITELIST_END;
+ memset(msg->id, 0, sizeof(msg->id));
+ send(fd, msg, sizeof(*msg), 0);
+ break;
+ case WHITELIST_FLUSH:
+ this->listener->flush(this->listener, id);
+ break;
+ case WHITELIST_ENABLE:
+ this->listener->set_active(this->listener, TRUE);
+ break;
+ case WHITELIST_DISABLE:
+ this->listener->set_active(this->listener, FALSE);
+ break;
+ default:
+ DBG1(DBG_CFG, "received unknown whitelist command");
+ break;
+ }
+ id->destroy(id);
+}
+
+/**
+ * Accept whitelist control connections, dispatch
+ */
+static job_requeue_t receive(private_whitelist_control_t *this)
+{
+ struct sockaddr_un addr;
+ int fd, len = sizeof(addr);
+ whitelist_msg_t msg;
+ bool oldstate;
+
+ oldstate = thread_cancelability(TRUE);
+ fd = accept(this->socket, (struct sockaddr*)&addr, &len);
+ thread_cancelability(oldstate);
+
+ if (fd != -1)
+ {
+ while (TRUE)
+ {
+ oldstate = thread_cancelability(TRUE);
+ len = recv(fd, &msg, sizeof(msg), 0);
+ thread_cancelability(oldstate);
+
+ if (len == sizeof(msg))
+ {
+ dispatch(this, fd, &msg);
+ }
+ else
+ {
+ if (len != 0)
+ {
+ DBG1(DBG_CFG, "receiving whitelist msg failed: %s",
+ strerror(errno));
+ }
+ break;
+ }
+ }
+ close(fd);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "accepting whitelist connection failed: %s",
+ strerror(errno));
+ }
+ return JOB_REQUEUE_FAIR;
+}
+
+METHOD(whitelist_control_t, destroy, void,
+ private_whitelist_control_t *this)
+{
+ this->job->cancel(this->job);
+ close(this->socket);
+ free(this);
+}
+
+/**
+ * See header
+ */
+whitelist_control_t *whitelist_control_create(whitelist_listener_t *listener)
+{
+ private_whitelist_control_t *this;
+
+ INIT(this,
+ .public = {
+ .destroy = _destroy,
+ },
+ .listener = listener,
+ );
+
+ if (!open_socket(this))
+ {
+ free(this);
+ return NULL;
+ }
+
+ this->job = callback_job_create((callback_job_cb_t)receive,
+ this, NULL, NULL);
+ lib->processor->queue_job(lib->processor, (job_t*)this->job);
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/whitelist/whitelist_control.h b/src/libcharon/plugins/whitelist/whitelist_control.h
new file mode 100644
index 000000000..dc813414d
--- /dev/null
+++ b/src/libcharon/plugins/whitelist/whitelist_control.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 whitelist_control whitelist_control
+ * @{ @ingroup whitelist
+ */
+
+#ifndef WHITELIST_CONTROL_H_
+#define WHITELIST_CONTROL_H_
+
+#include "whitelist_listener.h"
+
+typedef struct whitelist_control_t whitelist_control_t;
+
+/**
+ * Whitelist UNIX control socket.
+ */
+struct whitelist_control_t {
+
+ /**
+ * Destroy a whitelist_control_t.
+ */
+ void (*destroy)(whitelist_control_t *this);
+};
+
+/**
+ * Create a whitelist_control instance.
+ */
+whitelist_control_t *whitelist_control_create(whitelist_listener_t *listener);
+
+#endif /** WHITELIST_CONTROL_H_ @}*/
diff --git a/src/libcharon/plugins/whitelist/whitelist_listener.c b/src/libcharon/plugins/whitelist/whitelist_listener.c
new file mode 100644
index 000000000..5634e3ef8
--- /dev/null
+++ b/src/libcharon/plugins/whitelist/whitelist_listener.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 "whitelist_listener.h"
+
+#include <daemon.h>
+#include <utils/hashtable.h>
+#include <threading/rwlock.h>
+
+typedef struct private_whitelist_listener_t private_whitelist_listener_t;
+
+/**
+ * Private data of an whitelist_listener_t object.
+ */
+struct private_whitelist_listener_t {
+
+ /**
+ * Public whitelist_listener_t interface.
+ */
+ whitelist_listener_t public;
+
+ /**
+ * Lock for hashtable
+ */
+ rwlock_t *lock;
+
+ /**
+ * Hashtable with whitelisted identities
+ */
+ hashtable_t *ids;
+
+ /**
+ * Whitelist checking enabled
+ */
+ bool enabled;
+};
+
+/**
+ * Hashtable hash function
+ */
+static u_int hash(identification_t *key)
+{
+ return chunk_hash(key->get_encoding(key));
+}
+
+/**
+ * Hashtable equals function
+ */
+static bool equals(identification_t *a, identification_t *b)
+{
+ return a->equals(a, b);
+}
+
+METHOD(listener_t, authorize, bool,
+ private_whitelist_listener_t *this, ike_sa_t *ike_sa,
+ bool final, bool *success)
+{
+ /* check each authentication round */
+ if (this->enabled && !final)
+ {
+ bool whitelisted = FALSE;
+ identification_t *id;
+ auth_cfg_t *auth;
+
+ auth = ike_sa->get_auth_cfg(ike_sa, FALSE);
+ /* for authenticated with EAP, check EAP identity */
+ id = auth->get(auth, AUTH_RULE_EAP_IDENTITY);
+ if (!id)
+ {
+ id = auth->get(auth, AUTH_RULE_IDENTITY);
+ }
+ if (id)
+ {
+ this->lock->read_lock(this->lock);
+ whitelisted = this->ids->get(this->ids, id) != NULL;
+ this->lock->unlock(this->lock);
+ }
+ if (whitelisted)
+ {
+ DBG2(DBG_CFG, "peer identity '%Y' whitelisted", id);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "peer identity '%Y' not whitelisted", id);
+ *success = FALSE;
+ }
+ }
+ return TRUE;
+}
+
+METHOD(whitelist_listener_t, add, void,
+ private_whitelist_listener_t *this, identification_t *id)
+{
+ id = id->clone(id);
+ this->lock->write_lock(this->lock);
+ id = this->ids->put(this->ids, id, id);
+ this->lock->unlock(this->lock);
+ DESTROY_IF(id);
+}
+
+METHOD(whitelist_listener_t, remove_, void,
+ private_whitelist_listener_t *this, identification_t *id)
+{
+ this->lock->write_lock(this->lock);
+ id = this->ids->remove(this->ids, id);
+ this->lock->unlock(this->lock);
+ DESTROY_IF(id);
+}
+
+/**
+ * Enumerator filter, from hashtable (key, value) to single identity
+ */
+static bool whitelist_filter(rwlock_t *lock, identification_t **key,
+ identification_t **id, identification_t **value)
+{
+ *id = *value;
+ return TRUE;
+}
+
+METHOD(whitelist_listener_t, create_enumerator, enumerator_t*,
+ private_whitelist_listener_t *this)
+{
+ this->lock->read_lock(this->lock);
+ return enumerator_create_filter(this->ids->create_enumerator(this->ids),
+ (void*)whitelist_filter, this->lock,
+ (void*)this->lock->unlock);
+}
+
+METHOD(whitelist_listener_t, flush, void,
+ private_whitelist_listener_t *this, identification_t *id)
+{
+ enumerator_t *enumerator;
+ identification_t *key, *value;
+
+ this->lock->write_lock(this->lock);
+ enumerator = this->ids->create_enumerator(this->ids);
+ while (enumerator->enumerate(enumerator, &key, &value))
+ {
+ if (value->matches(value, id))
+ {
+ this->ids->remove_at(this->ids, enumerator);
+ value->destroy(value);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+}
+
+METHOD(whitelist_listener_t, set_active, void,
+ private_whitelist_listener_t *this, bool enable)
+{
+ DBG1(DBG_CFG, "whitelist functionality %s%sabled",
+ (this->enabled == enable) ? "was already " : "", enable ? "en" : "dis");
+ this->enabled = enable;
+}
+
+METHOD(whitelist_listener_t, destroy, void,
+ private_whitelist_listener_t *this)
+{
+ identification_t *key, *value;
+ enumerator_t *enumerator;
+
+ enumerator = this->ids->create_enumerator(this->ids);
+ while (enumerator->enumerate(enumerator, &key, &value))
+ {
+ value->destroy(value);
+ }
+ enumerator->destroy(enumerator);
+ this->ids->destroy(this->ids);
+ this->lock->destroy(this->lock);
+ free(this);
+}
+
+/**
+ * See header
+ */
+whitelist_listener_t *whitelist_listener_create()
+{
+ private_whitelist_listener_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .authorize = _authorize,
+ },
+ .add = _add,
+ .remove = _remove_,
+ .create_enumerator = _create_enumerator,
+ .flush = _flush,
+ .set_active = _set_active,
+ .destroy = _destroy,
+ },
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ .ids = hashtable_create((hashtable_hash_t)hash,
+ (hashtable_equals_t)equals, 32),
+ .enabled = lib->settings->get_bool(lib->settings,
+ "charon.plugins.whitelist.enable", FALSE),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/whitelist/whitelist_listener.h b/src/libcharon/plugins/whitelist/whitelist_listener.h
new file mode 100644
index 000000000..ac9475245
--- /dev/null
+++ b/src/libcharon/plugins/whitelist/whitelist_listener.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 whitelist_listener whitelist_listener
+ * @{ @ingroup whitelist
+ */
+
+#ifndef WHITELIST_LISTENER_H_
+#define WHITELIST_LISTENER_H_
+
+#include <bus/listeners/listener.h>
+
+typedef struct whitelist_listener_t whitelist_listener_t;
+
+/**
+ * Listener checking connecting peer against a whitelist.
+ */
+struct whitelist_listener_t {
+
+ /**
+ * Implements listener_t interface.
+ */
+ listener_t listener;
+
+ /**
+ * Add a peer identity to the whitelist.
+ *
+ * @param id identity to whitelist
+ */
+ void (*add)(whitelist_listener_t *this, identification_t *id);
+
+ /**
+ * Remove a peer identity from the whitelist.
+ *
+ * @param id identity to remove from whitelist
+ */
+ void (*remove)(whitelist_listener_t *this, identification_t *id);
+
+ /**
+ * Create an enumerator over whitelisted peer identities.
+ *
+ * The enumerator read-locks the whitelist, do not call add/remove while
+ * it is alive.
+ *
+ * @return enumerator over identification_t*
+ */
+ enumerator_t* (*create_enumerator)(whitelist_listener_t *this);
+
+ /**
+ * Flush identities from whitelist matching id.
+ *
+ * @param id id to match
+ */
+ void (*flush)(whitelist_listener_t *this, identification_t *id);
+
+ /**
+ * Enable/Disable whitelist checking.
+ *
+ * @param enable TRUE to enable, FALSE to disable
+ */
+ void (*set_active)(whitelist_listener_t *this, bool enable);
+
+ /**
+ * Destroy a whitelist_listener_t.
+ */
+ void (*destroy)(whitelist_listener_t *this);
+};
+
+/**
+ * Create a whitelist_listener instance.
+ */
+whitelist_listener_t *whitelist_listener_create();
+
+#endif /** WHITELIST_LISTENER_H_ @}*/
diff --git a/src/libcharon/plugins/whitelist/whitelist_msg.h b/src/libcharon/plugins/whitelist/whitelist_msg.h
new file mode 100644
index 000000000..65b922996
--- /dev/null
+++ b/src/libcharon/plugins/whitelist/whitelist_msg.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 whitelist_msg whitelist_msg
+ * @{ @ingroup whitelist
+ */
+
+#ifndef WHITELIST_MSG_H_
+#define WHITELIST_MSG_H_
+
+#define WHITELIST_SOCKET IPSEC_PIDDIR "/charon.wlst"
+
+typedef struct whitelist_msg_t whitelist_msg_t;
+
+/**
+ * Message type.
+ */
+enum {
+ /* add whitelist entry */
+ WHITELIST_ADD = 1,
+ /* remove whitelist entry */
+ WHITELIST_REMOVE = 2,
+ /* list identities matching id, gets responded with LIST messages */
+ WHITELIST_LIST = 3,
+ /* indicates end of list in a series of LIST messages */
+ WHITELIST_END = 4,
+ /* flush identities matching id */
+ WHITELIST_FLUSH = 5,
+ /* enable whitelist checking */
+ WHITELIST_ENABLE = 6,
+ /* disable whitelist checking */
+ WHITELIST_DISABLE = 7,
+};
+
+/**
+ * Message to exchange over whitelist
+ */
+struct whitelist_msg_t {
+ /** message type */
+ int type;
+ /** null terminated identity */
+ char id[128];
+};
+
+#endif /** WHITELIST_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/whitelist/whitelist_plugin.c b/src/libcharon/plugins/whitelist/whitelist_plugin.c
new file mode 100644
index 000000000..fca9d293f
--- /dev/null
+++ b/src/libcharon/plugins/whitelist/whitelist_plugin.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 "whitelist_plugin.h"
+
+#include "whitelist_listener.h"
+#include "whitelist_control.h"
+
+#include <daemon.h>
+
+typedef struct private_whitelist_plugin_t private_whitelist_plugin_t;
+
+/**
+ * private data of whitelist plugin
+ */
+struct private_whitelist_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ whitelist_plugin_t public;
+
+ /**
+ * Listener checking whitelist entries during authorization
+ */
+ whitelist_listener_t *listener;
+
+ /**
+ * Whitelist control socket
+ */
+ whitelist_control_t *control;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_whitelist_plugin_t *this)
+{
+ return "whitelist";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_whitelist_plugin_t *this)
+{
+ charon->bus->remove_listener(charon->bus, &this->listener->listener);
+ this->listener->destroy(this->listener);
+ DESTROY_IF(this->control);
+ free(this);
+}
+
+/**
+ * Plugin constructor
+ */
+plugin_t *whitelist_plugin_create()
+{
+ private_whitelist_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ .listener = whitelist_listener_create(),
+ );
+ this->control = whitelist_control_create(this->listener);
+
+ charon->bus->add_listener(charon->bus, &this->listener->listener);
+
+ return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/whitelist/whitelist_plugin.h b/src/libcharon/plugins/whitelist/whitelist_plugin.h
new file mode 100644
index 000000000..243313376
--- /dev/null
+++ b/src/libcharon/plugins/whitelist/whitelist_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 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 whitelist whitelist
+ * @ingroup cplugins
+ *
+ * @defgroup whitelist_plugin whitelist_plugin
+ * @{ @ingroup whitelist
+ */
+
+#ifndef WHITELIST_PLUGIN_H_
+#define WHITELIST_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct whitelist_plugin_t whitelist_plugin_t;
+
+/**
+ * Peer identity whitelisting plugin.
+ */
+struct whitelist_plugin_t {
+
+ /**
+ * Implements plugin interface.
+ */
+ plugin_t plugin;
+};
+
+#endif /** WHITELIST_PLUGIN_H_ @}*/