summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins')
-rw-r--r--src/libcharon/plugins/addrblock/Makefile.in4
-rw-r--r--src/libcharon/plugins/addrblock/addrblock_validator.c9
-rw-r--r--src/libcharon/plugins/android/Makefile.in4
-rw-r--r--src/libcharon/plugins/android/android_creds.c2
-rw-r--r--src/libcharon/plugins/android/android_service.c4
-rw-r--r--src/libcharon/plugins/dhcp/Makefile.in4
-rw-r--r--src/libcharon/plugins/dhcp/dhcp_socket.c7
-rw-r--r--src/libcharon/plugins/eap_aka/Makefile.in4
-rw-r--r--src/libcharon/plugins/eap_aka_3gpp2/Makefile.in4
-rw-r--r--src/libcharon/plugins/eap_gtc/Makefile.in4
-rw-r--r--src/libcharon/plugins/eap_identity/Makefile.in4
-rw-r--r--src/libcharon/plugins/eap_md5/Makefile.in4
-rw-r--r--src/libcharon/plugins/eap_mschapv2/Makefile.in4
-rw-r--r--src/libcharon/plugins/eap_radius/Makefile.in4
-rw-r--r--src/libcharon/plugins/eap_sim/Makefile.in4
-rw-r--r--src/libcharon/plugins/eap_sim_file/Makefile.in4
-rw-r--r--src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in4
-rw-r--r--src/libcharon/plugins/eap_simaka_reauth/Makefile.in4
-rw-r--r--src/libcharon/plugins/eap_simaka_sql/Makefile.in4
-rw-r--r--src/libcharon/plugins/eap_tls/Makefile.in4
-rw-r--r--src/libcharon/plugins/eap_tnc/Makefile.in4
-rw-r--r--src/libcharon/plugins/eap_tnc/eap_tnc.c26
-rw-r--r--src/libcharon/plugins/eap_ttls/Makefile.in4
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls_peer.c1
-rw-r--r--src/libcharon/plugins/farp/Makefile.in4
-rw-r--r--src/libcharon/plugins/ha/Makefile.in4
-rw-r--r--src/libcharon/plugins/ha/ha_ctl.c9
-rw-r--r--src/libcharon/plugins/ha/ha_dispatcher.c8
-rw-r--r--src/libcharon/plugins/ha/ha_segments.c14
-rw-r--r--src/libcharon/plugins/ha/ha_socket.c8
-rw-r--r--src/libcharon/plugins/ha/ha_tunnel.c4
-rw-r--r--src/libcharon/plugins/led/Makefile.in4
-rw-r--r--src/libcharon/plugins/load_tester/Makefile.in4
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_config.c4
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_ipsec.c2
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_plugin.c4
-rw-r--r--src/libcharon/plugins/maemo/Makefile.am6
-rw-r--r--src/libcharon/plugins/maemo/Makefile.in11
-rw-r--r--src/libcharon/plugins/maemo/maemo_service.c15
-rw-r--r--src/libcharon/plugins/maemo/org.strongswan.charon.service4
-rw-r--r--src/libcharon/plugins/maemo/org.strongswan.charon.service.in4
-rw-r--r--src/libcharon/plugins/medcli/Makefile.in4
-rw-r--r--src/libcharon/plugins/medcli/medcli_config.c8
-rw-r--r--src/libcharon/plugins/medsrv/Makefile.in4
-rw-r--r--src/libcharon/plugins/nm/Makefile.in4
-rw-r--r--src/libcharon/plugins/nm/nm_creds.c6
-rw-r--r--src/libcharon/plugins/nm/nm_service.c4
-rw-r--r--src/libcharon/plugins/smp/Makefile.in4
-rw-r--r--src/libcharon/plugins/socket_default/Makefile.in4
-rw-r--r--src/libcharon/plugins/socket_dynamic/Makefile.in4
-rw-r--r--src/libcharon/plugins/socket_raw/Makefile.in4
-rw-r--r--src/libcharon/plugins/sql/Makefile.in4
-rw-r--r--src/libcharon/plugins/sql/sql_config.c169
-rw-r--r--src/libcharon/plugins/sql/sql_cred.c246
-rw-r--r--src/libcharon/plugins/sql/sql_plugin.c18
-rw-r--r--src/libcharon/plugins/stroke/Makefile.am3
-rw-r--r--src/libcharon/plugins/stroke/Makefile.in10
-rw-r--r--src/libcharon/plugins/stroke/stroke_ca.c76
-rw-r--r--src/libcharon/plugins/stroke/stroke_config.c103
-rw-r--r--src/libcharon/plugins/stroke/stroke_control.c189
-rw-r--r--src/libcharon/plugins/stroke/stroke_control.h7
-rw-r--r--src/libcharon/plugins/stroke/stroke_cred.c409
-rw-r--r--src/libcharon/plugins/stroke/stroke_list.c130
-rw-r--r--src/libcharon/plugins/stroke/stroke_plugin.c18
-rw-r--r--src/libcharon/plugins/stroke/stroke_shared_key.c140
-rw-r--r--src/libcharon/plugins/stroke/stroke_shared_key.h60
-rw-r--r--src/libcharon/plugins/stroke/stroke_socket.c23
-rw-r--r--src/libcharon/plugins/tnc_imc/Makefile.am7
-rw-r--r--src/libcharon/plugins/tnc_imc/Makefile.in18
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc.c207
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc.h36
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c83
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_manager.c238
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_manager.h32
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c141
-rw-r--r--src/libcharon/plugins/tnc_imv/Makefile.am8
-rw-r--r--src/libcharon/plugins/tnc_imv/Makefile.in21
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv.c208
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv.h36
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c137
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_manager.c295
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_manager.h32
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c137
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c415
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.h33
-rw-r--r--src/libcharon/plugins/tnccs_11/Makefile.am16
-rw-r--r--src/libcharon/plugins/tnccs_11/Makefile.in92
-rw-r--r--src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c323
-rw-r--r--src/libcharon/plugins/tnccs_11/batch/tnccs_batch.h100
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c242
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h71
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.c191
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.h80
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/tnccs_msg.c140
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/tnccs_msg.h102
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.c137
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h64
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c149
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.h64
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c186
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h64
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.c118
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.h54
-rw-r--r--src/libcharon/plugins/tnccs_11/tnccs_11.c515
-rw-r--r--src/libcharon/plugins/tnccs_20/Makefile.am21
-rw-r--r--src/libcharon/plugins/tnccs_20/Makefile.in121
-rw-r--r--src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c543
-rw-r--r--src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.h126
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.c180
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.h76
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.c172
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.h60
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_error_msg.c346
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_error_msg.h127
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_experimental_msg.c102
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_experimental_msg.h53
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.c175
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.h60
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.c293
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.h123
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.c216
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.h69
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c259
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.h96
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_tnc_msg.c75
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_tnc_msg.h128
-rw-r--r--src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.c287
-rw-r--r--src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.h88
-rw-r--r--src/libcharon/plugins/tnccs_20/tnccs_20.c575
-rw-r--r--src/libcharon/plugins/tnccs_dynamic/Makefile.am17
-rw-r--r--src/libcharon/plugins/tnccs_dynamic/Makefile.in607
-rw-r--r--src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic.c146
-rw-r--r--src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic.h36
-rw-r--r--src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c47
-rw-r--r--src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h42
-rw-r--r--src/libcharon/plugins/uci/Makefile.in4
-rw-r--r--src/libcharon/plugins/uci/uci_config.c4
-rw-r--r--src/libcharon/plugins/unit_tester/Makefile.in4
-rw-r--r--src/libcharon/plugins/updown/Makefile.in4
139 files changed, 10656 insertions, 1299 deletions
diff --git a/src/libcharon/plugins/addrblock/Makefile.in b/src/libcharon/plugins/addrblock/Makefile.in
index 426d1a689..018318a59 100644
--- a/src/libcharon/plugins/addrblock/Makefile.in
+++ b/src/libcharon/plugins/addrblock/Makefile.in
@@ -223,9 +223,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +262,8 @@ 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@
diff --git a/src/libcharon/plugins/addrblock/addrblock_validator.c b/src/libcharon/plugins/addrblock/addrblock_validator.c
index 44ef38d85..12cf0c941 100644
--- a/src/libcharon/plugins/addrblock/addrblock_validator.c
+++ b/src/libcharon/plugins/addrblock/addrblock_validator.c
@@ -1,8 +1,6 @@
/*
- * Copyright (C) 2010 Martin Willi
- * Copyright (C) 2010 revosec AG
- * Copyright (C) 2009 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2010 Martin Willi, revosec AG
+ * Copyright (C) 2009 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
@@ -90,7 +88,8 @@ 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, auth_cfg_t *auth)
+ certificate_t *issuer, bool online, int pathlen, bool anchor,
+ auth_cfg_t *auth)
{
if (subject->get_type(subject) == CERT_X509 &&
issuer->get_type(issuer) == CERT_X509)
diff --git a/src/libcharon/plugins/android/Makefile.in b/src/libcharon/plugins/android/Makefile.in
index d80868798..7d6eb2b9c 100644
--- a/src/libcharon/plugins/android/Makefile.in
+++ b/src/libcharon/plugins/android/Makefile.in
@@ -223,9 +223,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +262,8 @@ 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@
diff --git a/src/libcharon/plugins/android/android_creds.c b/src/libcharon/plugins/android/android_creds.c
index aa7fc6f92..601c91e7b 100644
--- a/src/libcharon/plugins/android/android_creds.c
+++ b/src/libcharon/plugins/android/android_creds.c
@@ -235,7 +235,7 @@ METHOD(android_creds_t, set_username_password, void,
DESTROY_IF(this->user);
this->user = id->clone(id);
free(this->pass);
- this->pass = password ? strdup(password) : NULL;
+ this->pass = strdupnull(password);
this->lock->unlock(this->lock);
}
diff --git a/src/libcharon/plugins/android/android_service.c b/src/libcharon/plugins/android/android_service.c
index f9a8e1ea1..487567f2a 100644
--- a/src/libcharon/plugins/android/android_service.c
+++ b/src/libcharon/plugins/android/android_service.c
@@ -291,8 +291,8 @@ static job_requeue_t initiate(private_android_service_t *this)
peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
child_cfg = child_cfg_create("android", &lifetime, NULL, TRUE, MODE_TUNNEL,
- ACTION_NONE, ACTION_NONE, FALSE, 0, 0,
- NULL, NULL);
+ ACTION_NONE, ACTION_NONE, ACTION_NONE, FALSE,
+ 0, 0, NULL, NULL, 0);
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
ts = traffic_selector_create_dynamic(0, 0, 65535);
child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
diff --git a/src/libcharon/plugins/dhcp/Makefile.in b/src/libcharon/plugins/dhcp/Makefile.in
index e843c42e8..8046fc052 100644
--- a/src/libcharon/plugins/dhcp/Makefile.in
+++ b/src/libcharon/plugins/dhcp/Makefile.in
@@ -220,9 +220,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -261,6 +259,8 @@ 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@
diff --git a/src/libcharon/plugins/dhcp/dhcp_socket.c b/src/libcharon/plugins/dhcp/dhcp_socket.c
index e1e83d648..8851c1b79 100644
--- a/src/libcharon/plugins/dhcp/dhcp_socket.c
+++ b/src/libcharon/plugins/dhcp/dhcp_socket.c
@@ -459,7 +459,7 @@ static void handle_offer(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen)
{
dhcp_transaction_t *transaction = NULL;
enumerator_t *enumerator;
- host_t *offer, *server;
+ host_t *offer, *server = NULL;
offer = host_create_from_chunk(AF_INET,
chunk_from_thing(dhcp->your_address), 0);
@@ -500,7 +500,7 @@ static void handle_offer(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen)
chunk_create((char*)&option->data[pos], 4));
}
}
- if (option->type == DHCP_SERVER_ID && option->len == 4)
+ if (!server && option->type == DHCP_SERVER_ID && option->len == 4)
{
server = host_create_from_chunk(AF_INET,
chunk_create(option->data, 4), DHCP_SERVER_PORT);
@@ -515,12 +515,11 @@ static void handle_offer(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen)
}
DBG1(DBG_CFG, "received DHCP OFFER %H from %H", offer, server);
transaction->set_address(transaction, offer->clone(offer));
- transaction->set_server(transaction, server->clone(server));
+ transaction->set_server(transaction, server);
}
this->mutex->unlock(this->mutex);
this->condvar->broadcast(this->condvar);
offer->destroy(offer);
- server->destroy(server);
}
/**
diff --git a/src/libcharon/plugins/eap_aka/Makefile.in b/src/libcharon/plugins/eap_aka/Makefile.in
index c0750786d..4a23f9010 100644
--- a/src/libcharon/plugins/eap_aka/Makefile.in
+++ b/src/libcharon/plugins/eap_aka/Makefile.in
@@ -223,9 +223,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +262,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
index 41f69546e..ad1ae1906 100644
--- a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
+++ b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
@@ -224,9 +224,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -265,6 +263,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_gtc/Makefile.in b/src/libcharon/plugins/eap_gtc/Makefile.in
index 02d659197..142a35e50 100644
--- a/src/libcharon/plugins/eap_gtc/Makefile.in
+++ b/src/libcharon/plugins/eap_gtc/Makefile.in
@@ -221,9 +221,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -262,6 +260,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_identity/Makefile.in b/src/libcharon/plugins/eap_identity/Makefile.in
index 46011694a..5c1e07ade 100644
--- a/src/libcharon/plugins/eap_identity/Makefile.in
+++ b/src/libcharon/plugins/eap_identity/Makefile.in
@@ -223,9 +223,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +262,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_md5/Makefile.in b/src/libcharon/plugins/eap_md5/Makefile.in
index 2e307147f..4e01d96cc 100644
--- a/src/libcharon/plugins/eap_md5/Makefile.in
+++ b/src/libcharon/plugins/eap_md5/Makefile.in
@@ -221,9 +221,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -262,6 +260,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_mschapv2/Makefile.in b/src/libcharon/plugins/eap_mschapv2/Makefile.in
index 635cfe6ec..495ccf441 100644
--- a/src/libcharon/plugins/eap_mschapv2/Makefile.in
+++ b/src/libcharon/plugins/eap_mschapv2/Makefile.in
@@ -223,9 +223,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +262,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_radius/Makefile.in b/src/libcharon/plugins/eap_radius/Makefile.in
index 1d771d9a4..99084e2c1 100644
--- a/src/libcharon/plugins/eap_radius/Makefile.in
+++ b/src/libcharon/plugins/eap_radius/Makefile.in
@@ -224,9 +224,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -265,6 +263,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_sim/Makefile.in b/src/libcharon/plugins/eap_sim/Makefile.in
index d05930bbd..90f203f61 100644
--- a/src/libcharon/plugins/eap_sim/Makefile.in
+++ b/src/libcharon/plugins/eap_sim/Makefile.in
@@ -223,9 +223,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +262,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.in b/src/libcharon/plugins/eap_sim_file/Makefile.in
index 46a584265..3cd766a75 100644
--- a/src/libcharon/plugins/eap_sim_file/Makefile.in
+++ b/src/libcharon/plugins/eap_sim_file/Makefile.in
@@ -224,9 +224,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -265,6 +263,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
index 2d8556a59..a48fb652a 100644
--- a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
@@ -225,9 +225,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -266,6 +264,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
index e59015f82..f2af3ae0d 100644
--- a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
@@ -224,9 +224,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -265,6 +263,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_simaka_sql/Makefile.in b/src/libcharon/plugins/eap_simaka_sql/Makefile.in
index 3c66d2f36..9a58a6055 100644
--- a/src/libcharon/plugins/eap_simaka_sql/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_sql/Makefile.in
@@ -223,9 +223,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +262,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_tls/Makefile.in b/src/libcharon/plugins/eap_tls/Makefile.in
index e4b78faf8..9ebb85be9 100644
--- a/src/libcharon/plugins/eap_tls/Makefile.in
+++ b/src/libcharon/plugins/eap_tls/Makefile.in
@@ -222,9 +222,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +261,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_tnc/Makefile.in b/src/libcharon/plugins/eap_tnc/Makefile.in
index fb7108a8a..cf75585ef 100644
--- a/src/libcharon/plugins/eap_tnc/Makefile.in
+++ b/src/libcharon/plugins/eap_tnc/Makefile.in
@@ -222,9 +222,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +261,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc.c b/src/libcharon/plugins/eap_tnc/eap_tnc.c
index f0bff0e1f..dd4ed5322 100644
--- a/src/libcharon/plugins/eap_tnc/eap_tnc.c
+++ b/src/libcharon/plugins/eap_tnc/eap_tnc.c
@@ -18,7 +18,7 @@
#include <tls_eap.h>
#include <daemon.h>
-#include <library.h>
+#include <debug.h>
typedef struct private_eap_tnc_t private_eap_tnc_t;
@@ -114,6 +114,8 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
private_eap_tnc_t *this;
size_t frag_size;
int max_msg_count;
+ char* protocol;
+ tnccs_type_t type;
tnccs_t *tnccs;
INIT(this,
@@ -133,7 +135,27 @@ 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);
- tnccs = charon->tnccs->create_instance(charon->tnccs, TNCCS_1_1, is_server);
+ protocol = lib->settings->get_str(lib->settings,
+ "charon.plugins.eap-tnc.protocol", "tnccs-1.1");
+ if (strcaseeq(protocol, "tnccs-2.0"))
+ {
+ type = TNCCS_2_0;
+ }
+ else if (strcaseeq(protocol, "tnccs-1.1"))
+ {
+ type = TNCCS_1_1;
+ }
+ else if (strcaseeq(protocol, "tnccs-dynamic") && is_server)
+ {
+ type = TNCCS_DYNAMIC;
+ }
+ else
+ {
+ DBG1(DBG_TNC, "TNCCS protocol '%s' not supported", protocol);
+ free(this);
+ 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);
if (!this->tls_eap)
{
diff --git a/src/libcharon/plugins/eap_ttls/Makefile.in b/src/libcharon/plugins/eap_ttls/Makefile.in
index 2cdd7701d..ff67686b2 100644
--- a/src/libcharon/plugins/eap_ttls/Makefile.in
+++ b/src/libcharon/plugins/eap_ttls/Makefile.in
@@ -225,9 +225,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -266,6 +264,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c b/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c
index 10d08ca2a..29b0a9303 100644
--- a/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c
@@ -196,6 +196,7 @@ METHOD(tls_application_t, process, status_t,
in->destroy(in);
return NEED_MORE;
}
+ this->start_phase2 = FALSE;
}
type = this->method->get_type(this->method, &vendor);
diff --git a/src/libcharon/plugins/farp/Makefile.in b/src/libcharon/plugins/farp/Makefile.in
index bfd50d6da..21e8b78db 100644
--- a/src/libcharon/plugins/farp/Makefile.in
+++ b/src/libcharon/plugins/farp/Makefile.in
@@ -220,9 +220,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -261,6 +259,8 @@ 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@
diff --git a/src/libcharon/plugins/ha/Makefile.in b/src/libcharon/plugins/ha/Makefile.in
index 3600eb7c6..2fcd7cc82 100644
--- a/src/libcharon/plugins/ha/Makefile.in
+++ b/src/libcharon/plugins/ha/Makefile.in
@@ -222,9 +222,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +261,8 @@ 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@
diff --git a/src/libcharon/plugins/ha/ha_ctl.c b/src/libcharon/plugins/ha/ha_ctl.c
index 980c0551a..15f7824f9 100644
--- a/src/libcharon/plugins/ha/ha_ctl.c
+++ b/src/libcharon/plugins/ha/ha_ctl.c
@@ -21,8 +21,8 @@
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
-#include <pthread.h>
+#include <threading/thread.h>
#include <processing/jobs/callback_job.h>
#define HA_FIFO IPSEC_PIDDIR "/charon.ha"
@@ -60,13 +60,14 @@ struct private_ha_ctl_t {
*/
static job_requeue_t dispatch_fifo(private_ha_ctl_t *this)
{
- int fifo, old;
+ int fifo;
+ bool oldstate;
char buf[8];
u_int segment;
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
+ oldstate = thread_cancelability(TRUE);
fifo = open(HA_FIFO, O_RDONLY);
- pthread_setcancelstate(old, NULL);
+ thread_cancelability(oldstate);
if (fifo == -1)
{
DBG1(DBG_CFG, "opening HA fifo failed: %s", strerror(errno));
diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c
index b46a221bd..85dc0f4a4 100644
--- a/src/libcharon/plugins/ha/ha_dispatcher.c
+++ b/src/libcharon/plugins/ha/ha_dispatcher.c
@@ -596,9 +596,9 @@ static void process_child_add(private_ha_dispatcher_t *this,
if (initiator)
{
if (child_sa->install(child_sa, encr_r, integ_r, inbound_spi,
- inbound_cpi, TRUE, local_ts, remote_ts) != SUCCESS ||
+ inbound_cpi, TRUE, TRUE, local_ts, remote_ts) != SUCCESS ||
child_sa->install(child_sa, encr_i, integ_i, outbound_spi,
- outbound_cpi, FALSE, local_ts, remote_ts) != SUCCESS)
+ outbound_cpi, FALSE, TRUE, local_ts, remote_ts) != SUCCESS)
{
failed = TRUE;
}
@@ -606,9 +606,9 @@ static void process_child_add(private_ha_dispatcher_t *this,
else
{
if (child_sa->install(child_sa, encr_i, integ_i, inbound_spi,
- inbound_cpi, TRUE, local_ts, remote_ts) != SUCCESS ||
+ inbound_cpi, TRUE, TRUE, local_ts, remote_ts) != SUCCESS ||
child_sa->install(child_sa, encr_r, integ_r, outbound_spi,
- outbound_cpi, FALSE, local_ts, remote_ts) != SUCCESS)
+ outbound_cpi, FALSE, TRUE, local_ts, remote_ts) != SUCCESS)
{
failed = TRUE;
}
diff --git a/src/libcharon/plugins/ha/ha_segments.c b/src/libcharon/plugins/ha/ha_segments.c
index 19e0f692e..7c7bef851 100644
--- a/src/libcharon/plugins/ha/ha_segments.c
+++ b/src/libcharon/plugins/ha/ha_segments.c
@@ -15,11 +15,10 @@
#include "ha_segments.h"
-#include <pthread.h>
-
#include <threading/mutex.h>
#include <threading/condvar.h>
#include <utils/linked_list.h>
+#include <threading/thread.h>
#include <processing/jobs/callback_job.h>
#define DEFAULT_HEARTBEAT_DELAY 1000
@@ -255,16 +254,15 @@ METHOD(listener_t, alert_hook, bool,
*/
static job_requeue_t watchdog(private_ha_segments_t *this)
{
- int oldstate;
- bool timeout;
+ bool timeout, oldstate;
this->mutex->lock(this->mutex);
- pthread_cleanup_push((void*)this->mutex->unlock, this->mutex);
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
+ thread_cleanup_push((void*)this->mutex->unlock, this->mutex);
+ oldstate = thread_cancelability(TRUE);
timeout = this->condvar->timed_wait(this->condvar, this->mutex,
this->heartbeat_timeout);
- pthread_setcancelstate(oldstate, NULL);
- pthread_cleanup_pop(TRUE);
+ thread_cancelability(oldstate);
+ thread_cleanup_pop(TRUE);
if (timeout)
{
DBG1(DBG_CFG, "no heartbeat received, taking all segments");
diff --git a/src/libcharon/plugins/ha/ha_socket.c b/src/libcharon/plugins/ha/ha_socket.c
index 614c70ed3..086178442 100644
--- a/src/libcharon/plugins/ha/ha_socket.c
+++ b/src/libcharon/plugins/ha/ha_socket.c
@@ -20,10 +20,10 @@
#include <sys/socket.h>
#include <errno.h>
#include <unistd.h>
-#include <pthread.h>
#include <daemon.h>
#include <utils/host.h>
+#include <threading/thread.h>
#include <processing/jobs/callback_job.h>
typedef struct private_ha_socket_t private_ha_socket_t;
@@ -121,12 +121,12 @@ METHOD(ha_socket_t, pull, ha_message_t*,
{
ha_message_t *message;
char buf[1024];
- int oldstate;
+ bool oldstate;
ssize_t len;
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
+ oldstate = thread_cancelability(TRUE);
len = recv(this->fd, buf, sizeof(buf), 0);
- pthread_setcancelstate(oldstate, NULL);
+ thread_cancelability(oldstate);
if (len <= 0)
{
switch (errno)
diff --git a/src/libcharon/plugins/ha/ha_tunnel.c b/src/libcharon/plugins/ha/ha_tunnel.c
index fef84a430..299053ec1 100644
--- a/src/libcharon/plugins/ha/ha_tunnel.c
+++ b/src/libcharon/plugins/ha/ha_tunnel.c
@@ -223,8 +223,8 @@ static void setup_tunnel(private_ha_tunnel_t *this,
peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, FALSE);
child_cfg = child_cfg_create("ha", &lifetime, NULL, TRUE, MODE_TRANSPORT,
- ACTION_NONE, ACTION_NONE, FALSE, 0, 0,
- NULL, NULL);
+ ACTION_NONE, ACTION_NONE, ACTION_NONE, FALSE,
+ 0, 0, NULL, NULL, 0);
ts = traffic_selector_create_dynamic(IPPROTO_UDP, HA_PORT, HA_PORT);
child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
ts = traffic_selector_create_dynamic(IPPROTO_ICMP, 0, 65535);
diff --git a/src/libcharon/plugins/led/Makefile.in b/src/libcharon/plugins/led/Makefile.in
index a4e529d89..fa1194fd0 100644
--- a/src/libcharon/plugins/led/Makefile.in
+++ b/src/libcharon/plugins/led/Makefile.in
@@ -219,9 +219,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -260,6 +258,8 @@ 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@
diff --git a/src/libcharon/plugins/load_tester/Makefile.in b/src/libcharon/plugins/load_tester/Makefile.in
index 85db9a10b..c921ec3db 100644
--- a/src/libcharon/plugins/load_tester/Makefile.in
+++ b/src/libcharon/plugins/load_tester/Makefile.in
@@ -225,9 +225,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -266,6 +264,8 @@ 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@
diff --git a/src/libcharon/plugins/load_tester/load_tester_config.c b/src/libcharon/plugins/load_tester/load_tester_config.c
index a230aa3f5..71391d593 100644
--- a/src/libcharon/plugins/load_tester/load_tester_config.c
+++ b/src/libcharon/plugins/load_tester/load_tester_config.c
@@ -224,8 +224,8 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
}
child_cfg = child_cfg_create("load-test", &lifetime, NULL, TRUE, MODE_TUNNEL,
- ACTION_NONE, ACTION_NONE, FALSE, 0, 0,
- NULL, NULL);
+ ACTION_NONE, ACTION_NONE, ACTION_NONE, FALSE,
+ 0, 0, NULL, NULL, 0);
proposal = proposal_create_from_string(PROTO_ESP, "aes128-sha1");
child_cfg->add_proposal(child_cfg, proposal);
ts = traffic_selector_create_dynamic(0, 0, 65535);
diff --git a/src/libcharon/plugins/load_tester/load_tester_ipsec.c b/src/libcharon/plugins/load_tester/load_tester_ipsec.c
index aece95e12..ef9d7f9ef 100644
--- a/src/libcharon/plugins/load_tester/load_tester_ipsec.c
+++ b/src/libcharon/plugins/load_tester/load_tester_ipsec.c
@@ -52,7 +52,7 @@ METHOD(kernel_ipsec_t, get_cpi, status_t,
METHOD(kernel_ipsec_t, add_sa, status_t,
private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,
- lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
+ 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)
diff --git a/src/libcharon/plugins/load_tester/load_tester_plugin.c b/src/libcharon/plugins/load_tester/load_tester_plugin.c
index cb9b80c7f..8fd65adfa 100644
--- a/src/libcharon/plugins/load_tester/load_tester_plugin.c
+++ b/src/libcharon/plugins/load_tester/load_tester_plugin.c
@@ -28,6 +28,8 @@
#include <threading/condvar.h>
#include <threading/mutex.h>
+static const char *plugin_name = "load_tester";
+
typedef struct private_load_tester_plugin_t private_load_tester_plugin_t;
/**
@@ -189,7 +191,7 @@ plugin_t *load_tester_plugin_create()
this = malloc_thing(private_load_tester_plugin_t);
this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
- lib->crypto->add_dh(lib->crypto, MODP_NULL,
+ lib->crypto->add_dh(lib->crypto, MODP_NULL, plugin_name,
(dh_constructor_t)load_tester_diffie_hellman_create);
this->delay = lib->settings->get_int(lib->settings,
diff --git a/src/libcharon/plugins/maemo/Makefile.am b/src/libcharon/plugins/maemo/Makefile.am
index ed6c76c0f..0bf7fad5d 100644
--- a/src/libcharon/plugins/maemo/Makefile.am
+++ b/src/libcharon/plugins/maemo/Makefile.am
@@ -19,5 +19,9 @@ libstrongswan_maemo_la_LIBADD = ${maemo_LIBS}
dbusservice_DATA = org.strongswan.charon.service
-EXTRA_DIST = $(dbusservice_DATA)
+org.strongswan.charon.service: $(srcdir)/org.strongswan.charon.service.in
+ sed -e 's|[@]LIBEXECDIR[@]|$(libexecdir)|' $< >$@
+
+EXTRA_DIST = org.strongswan.charon.service.in
+CLEANFILES = $(dbusservice_DATA)
diff --git a/src/libcharon/plugins/maemo/Makefile.in b/src/libcharon/plugins/maemo/Makefile.in
index 978950d22..0ca1fa436 100644
--- a/src/libcharon/plugins/maemo/Makefile.in
+++ b/src/libcharon/plugins/maemo/Makefile.in
@@ -224,9 +224,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -265,6 +263,8 @@ 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@
@@ -288,7 +288,8 @@ libstrongswan_maemo_la_SOURCES = \
libstrongswan_maemo_la_LDFLAGS = -module -avoid-version
libstrongswan_maemo_la_LIBADD = ${maemo_LIBS}
dbusservice_DATA = org.strongswan.charon.service
-EXTRA_DIST = $(dbusservice_DATA)
+EXTRA_DIST = org.strongswan.charon.service.in
+CLEANFILES = $(dbusservice_DATA)
all: all-am
.SUFFIXES:
@@ -528,6 +529,7 @@ install-strip:
mostlyclean-generic:
clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
@@ -626,6 +628,9 @@ uninstall-am: uninstall-dbusserviceDATA uninstall-pluginLTLIBRARIES
uninstall-pluginLTLIBRARIES
+org.strongswan.charon.service: $(srcdir)/org.strongswan.charon.service.in
+ sed -e 's|[@]LIBEXECDIR[@]|$(libexecdir)|' $< >$@
+
# 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/maemo/maemo_service.c b/src/libcharon/plugins/maemo/maemo_service.c
index efd914a00..0e9fd8ccc 100644
--- a/src/libcharon/plugins/maemo/maemo_service.c
+++ b/src/libcharon/plugins/maemo/maemo_service.c
@@ -115,12 +115,11 @@ METHOD(listener_t, ike_updown, bool,
return TRUE;
}
-METHOD(listener_t, child_state_change, bool,
- private_maemo_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
- child_sa_state_t state)
+METHOD(listener_t, ike_state_change, bool,
+ private_maemo_service_t *this, ike_sa_t *ike_sa, ike_sa_state_t state)
{
/* this call back is only registered during initiation */
- if (this->ike_sa == ike_sa && state == CHILD_DESTROYING)
+ if (this->ike_sa == ike_sa && state == IKE_DESTROYING)
{
change_status(this, VPN_STATUS_CONNECTION_FAILED);
return FALSE;
@@ -138,7 +137,7 @@ METHOD(listener_t, child_updown, bool,
{
/* disable hooks registered to catch initiation failures */
this->public.listener.ike_updown = NULL;
- this->public.listener.child_state_change = NULL;
+ this->public.listener.ike_state_change = NULL;
change_status(this, VPN_STATUS_CONNECTED);
}
else
@@ -347,7 +346,7 @@ static gboolean initiate_connection(private_maemo_service_t *this,
child_cfg = child_cfg_create(this->current, &lifetime, NULL /* updown */,
TRUE, MODE_TUNNEL, ACTION_NONE, ACTION_NONE,
- FALSE, 0, 0, NULL, NULL);
+ ACTION_NONE, FALSE, 0, 0, NULL, NULL, 0);
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
ts = traffic_selector_create_dynamic(0, 0, 65535);
child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
@@ -371,7 +370,7 @@ static gboolean initiate_connection(private_maemo_service_t *this,
this->ike_sa = ike_sa;
this->status = VPN_STATUS_CONNECTING;
this->public.listener.ike_updown = _ike_updown;
- this->public.listener.child_state_change = _child_state_change;
+ this->public.listener.ike_state_change = _ike_state_change;
charon->bus->add_listener(charon->bus, &this->public.listener);
if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS)
@@ -464,7 +463,7 @@ maemo_service_t *maemo_service_create()
.public = {
.listener = {
.ike_updown = _ike_updown,
- .child_state_change = _child_state_change,
+ .ike_state_change = _ike_state_change,
.child_updown = _child_updown,
.ike_rekey = _ike_rekey,
},
diff --git a/src/libcharon/plugins/maemo/org.strongswan.charon.service b/src/libcharon/plugins/maemo/org.strongswan.charon.service
deleted file mode 100644
index 7dd31ed60..000000000
--- a/src/libcharon/plugins/maemo/org.strongswan.charon.service
+++ /dev/null
@@ -1,4 +0,0 @@
-[D-BUS Service]
-Name=org.strongswan.charon
-Exec=/usr/bin/run-standalone.sh /usr/libexec/ipsec/charon
-User=root
diff --git a/src/libcharon/plugins/maemo/org.strongswan.charon.service.in b/src/libcharon/plugins/maemo/org.strongswan.charon.service.in
new file mode 100644
index 000000000..8fa83af93
--- /dev/null
+++ b/src/libcharon/plugins/maemo/org.strongswan.charon.service.in
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=org.strongswan.charon
+Exec=/usr/bin/run-standalone.sh @LIBEXECDIR@/ipsec/charon
+User=root
diff --git a/src/libcharon/plugins/medcli/Makefile.in b/src/libcharon/plugins/medcli/Makefile.in
index 6dcbc99dd..372a436a6 100644
--- a/src/libcharon/plugins/medcli/Makefile.in
+++ b/src/libcharon/plugins/medcli/Makefile.in
@@ -222,9 +222,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +261,8 @@ 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@
diff --git a/src/libcharon/plugins/medcli/medcli_config.c b/src/libcharon/plugins/medcli/medcli_config.c
index 870d87c7e..b5672dba9 100644
--- a/src/libcharon/plugins/medcli/medcli_config.c
+++ b/src/libcharon/plugins/medcli/medcli_config.c
@@ -182,8 +182,8 @@ static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *nam
peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
child_cfg = child_cfg_create(name, &lifetime, NULL, TRUE, MODE_TUNNEL,
- ACTION_NONE, ACTION_NONE, FALSE, 0, 0,
- NULL, NULL);
+ ACTION_NONE, ACTION_NONE, ACTION_NONE, FALSE,
+ 0, 0, NULL, NULL, 0);
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
child_cfg->add_traffic_selector(child_cfg, TRUE, ts_from_string(local_net));
child_cfg->add_traffic_selector(child_cfg, FALSE, ts_from_string(remote_net));
@@ -261,8 +261,8 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
this->current->add_auth_cfg(this->current, auth, FALSE);
child_cfg = child_cfg_create(name, &lifetime, NULL, TRUE, MODE_TUNNEL,
- ACTION_NONE, ACTION_NONE, FALSE, 0, 0,
- NULL, NULL);
+ ACTION_NONE, ACTION_NONE, ACTION_NONE, FALSE,
+ 0, 0, NULL, NULL, 0);
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
child_cfg->add_traffic_selector(child_cfg, TRUE, ts_from_string(local_net));
child_cfg->add_traffic_selector(child_cfg, FALSE, ts_from_string(remote_net));
diff --git a/src/libcharon/plugins/medsrv/Makefile.in b/src/libcharon/plugins/medsrv/Makefile.in
index f6db7d834..4bb65bd09 100644
--- a/src/libcharon/plugins/medsrv/Makefile.in
+++ b/src/libcharon/plugins/medsrv/Makefile.in
@@ -222,9 +222,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +261,8 @@ 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@
diff --git a/src/libcharon/plugins/nm/Makefile.in b/src/libcharon/plugins/nm/Makefile.in
index 2f5c20971..69af7bf83 100644
--- a/src/libcharon/plugins/nm/Makefile.in
+++ b/src/libcharon/plugins/nm/Makefile.in
@@ -221,9 +221,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -262,6 +260,8 @@ 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@
diff --git a/src/libcharon/plugins/nm/nm_creds.c b/src/libcharon/plugins/nm/nm_creds.c
index 638787019..ea98c056d 100644
--- a/src/libcharon/plugins/nm/nm_creds.c
+++ b/src/libcharon/plugins/nm/nm_creds.c
@@ -400,7 +400,7 @@ static void set_username_password(private_nm_creds_t *this, identification_t *id
DESTROY_IF(this->user);
this->user = id->clone(id);
free(this->pass);
- this->pass = password ? strdup(password) : NULL;
+ this->pass = strdupnull(password);
this->lock->unlock(this->lock);
}
@@ -411,7 +411,7 @@ static void set_key_password(private_nm_creds_t *this, char *password)
{
this->lock->write_lock(this->lock);
free(this->keypass);
- this->keypass = password ? strdup(password) : NULL;
+ this->keypass = strdupnull(password);
this->lock->unlock(this->lock);
}
@@ -423,7 +423,7 @@ static void set_pin(private_nm_creds_t *this, chunk_t keyid, char *pin)
this->lock->write_lock(this->lock);
free(this->keypass);
free(this->keyid.ptr);
- this->keypass = pin ? strdup(pin) : NULL;
+ this->keypass = strdupnull(pin);
this->keyid = chunk_clone(keyid);
this->lock->unlock(this->lock);
}
diff --git a/src/libcharon/plugins/nm/nm_service.c b/src/libcharon/plugins/nm/nm_service.c
index 72c5bbbb5..4300b57cf 100644
--- a/src/libcharon/plugins/nm/nm_service.c
+++ b/src/libcharon/plugins/nm/nm_service.c
@@ -518,8 +518,8 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
child_cfg = child_cfg_create(priv->name, &lifetime,
NULL, TRUE, MODE_TUNNEL, /* updown, hostaccess */
- ACTION_NONE, ACTION_NONE, ipcomp, 0, 0,
- NULL, NULL);
+ ACTION_NONE, ACTION_NONE, ACTION_NONE, ipcomp,
+ 0, 0, NULL, NULL, 0);
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
ts = traffic_selector_create_dynamic(0, 0, 65535);
child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
diff --git a/src/libcharon/plugins/smp/Makefile.in b/src/libcharon/plugins/smp/Makefile.in
index f24e2d1e7..3d2cef13c 100644
--- a/src/libcharon/plugins/smp/Makefile.in
+++ b/src/libcharon/plugins/smp/Makefile.in
@@ -220,9 +220,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -261,6 +259,8 @@ 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@
diff --git a/src/libcharon/plugins/socket_default/Makefile.in b/src/libcharon/plugins/socket_default/Makefile.in
index bd85386b2..b82372e30 100644
--- a/src/libcharon/plugins/socket_default/Makefile.in
+++ b/src/libcharon/plugins/socket_default/Makefile.in
@@ -223,9 +223,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +262,8 @@ 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@
diff --git a/src/libcharon/plugins/socket_dynamic/Makefile.in b/src/libcharon/plugins/socket_dynamic/Makefile.in
index 8e0790671..7a49088b2 100644
--- a/src/libcharon/plugins/socket_dynamic/Makefile.in
+++ b/src/libcharon/plugins/socket_dynamic/Makefile.in
@@ -223,9 +223,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +262,8 @@ 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@
diff --git a/src/libcharon/plugins/socket_raw/Makefile.in b/src/libcharon/plugins/socket_raw/Makefile.in
index 5f4cba131..744b12fcf 100644
--- a/src/libcharon/plugins/socket_raw/Makefile.in
+++ b/src/libcharon/plugins/socket_raw/Makefile.in
@@ -223,9 +223,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +262,8 @@ 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@
diff --git a/src/libcharon/plugins/sql/Makefile.in b/src/libcharon/plugins/sql/Makefile.in
index 7c4521785..4244d3b5e 100644
--- a/src/libcharon/plugins/sql/Makefile.in
+++ b/src/libcharon/plugins/sql/Makefile.in
@@ -220,9 +220,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -261,6 +259,8 @@ 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@
diff --git a/src/libcharon/plugins/sql/sql_config.c b/src/libcharon/plugins/sql/sql_config.c
index a47d93f7b..dc016012c 100644
--- a/src/libcharon/plugins/sql/sql_config.c
+++ b/src/libcharon/plugins/sql/sql_config.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006-2008 Martin Willi
+ * Copyright (C) 2010 Andreas Steffen
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -38,13 +39,13 @@ struct private_sql_config_t {
};
/**
- * forward declaration
+ * Forward declaration
*/
static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
identification_t *me, identification_t *other);
/**
- * build a traffic selector from a SQL query
+ * Build a traffic selector from an SQL query
*/
static traffic_selector_t *build_traffic_selector(private_sql_config_t *this,
enumerator_t *e, bool *local)
@@ -119,24 +120,62 @@ static void add_traffic_selectors(private_sql_config_t *this,
}
/**
- * build a Child configuration from a SQL query
+ * Add ESP proposals to a child config
+ */
+static void add_esp_proposals(private_sql_config_t *this,
+ child_cfg_t *child, int id)
+{
+ enumerator_t *e;
+ proposal_t *proposal;
+ char *prop;
+ bool use_default = TRUE;
+
+ e = this->db->query(this->db,
+ "SELECT proposal "
+ "FROM proposals JOIN child_config_proposal ON id = prop "
+ "WHERE child_cfg = ? ORDER BY prio",
+ DB_INT, id, DB_TEXT);
+ if (e)
+ {
+ while (e->enumerate(e, &prop))
+ {
+ proposal = proposal_create_from_string(PROTO_ESP, prop);
+ if (!proposal)
+ {
+ DBG1(DBG_CFG, "could not create ESP proposal from '%s'", prop);
+ break;
+ }
+ child->add_proposal(child, proposal);
+ use_default = FALSE;
+ }
+ e->destroy(e);
+ }
+ if (use_default)
+ {
+ child->add_proposal(child, proposal_create_default(PROTO_ESP));
+ }
+}
+
+/**
+ * Build a child config from an SQL query
*/
static child_cfg_t *build_child_cfg(private_sql_config_t *this, enumerator_t *e)
{
- int id, lifetime, rekeytime, jitter, hostaccess, mode, dpd, close, ipcomp;
+ int id, lifetime, rekeytime, jitter, hostaccess, mode, ipcomp, reqid;
+ int start, dpd, close;
char *name, *updown;
child_cfg_t *child_cfg;
- if (e->enumerate(e, &id, &name, &lifetime, &rekeytime, &jitter,
- &updown, &hostaccess, &mode, &dpd, &close, &ipcomp))
+ if (e->enumerate(e, &id, &name, &lifetime, &rekeytime, &jitter, &updown,
+ &hostaccess, &mode, &start, &dpd, &close, &ipcomp, &reqid))
{
lifetime_cfg_t lft = {
.time = { .life = lifetime, .rekey = rekeytime, .jitter = jitter }
};
child_cfg = child_cfg_create(name, &lft, updown, hostaccess, mode,
- dpd, close, ipcomp, 0, 0, NULL, NULL);
- /* TODO: read proposal from db */
- child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
+ start, dpd, close, ipcomp, 0, reqid,
+ NULL, NULL, 0);
+ add_esp_proposals(this, child_cfg, id);
add_traffic_selectors(this, child_cfg, id);
return child_cfg;
}
@@ -152,13 +191,13 @@ static void add_child_cfgs(private_sql_config_t *this, peer_cfg_t *peer, int id)
child_cfg_t *child_cfg;
e = this->db->query(this->db,
- "SELECT id, name, lifetime, rekeytime, jitter, "
- "updown, hostaccess, mode, dpd_action, close_action, ipcomp "
+ "SELECT id, name, lifetime, rekeytime, jitter, updown, hostaccess, "
+ "mode, start_action, dpd_action, close_action, ipcomp, reqid "
"FROM child_configs JOIN peer_config_child_config ON id = child_cfg "
"WHERE peer_cfg = ?",
DB_INT, id,
- DB_INT, DB_TEXT, DB_INT, DB_INT, DB_INT,
- DB_TEXT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT);
+ DB_INT, DB_TEXT, DB_INT, DB_INT, DB_INT, DB_TEXT, DB_INT,
+ DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT);
if (e)
{
while ((child_cfg = build_child_cfg(this, e)))
@@ -170,29 +209,65 @@ static void add_child_cfgs(private_sql_config_t *this, peer_cfg_t *peer, int id)
}
/**
- * build a ike configuration from a SQL query
+ * Add IKE proposals to an IKE config
+ */
+static void add_ike_proposals(private_sql_config_t *this,
+ ike_cfg_t *ike_cfg, int id)
+{
+ enumerator_t *e;
+ proposal_t *proposal;
+ char *prop;
+ bool use_default = TRUE;
+
+ e = this->db->query(this->db,
+ "SELECT proposal "
+ "FROM proposals JOIN ike_config_proposal ON id = prop "
+ "WHERE ike_cfg = ? ORDER BY prio",
+ DB_INT, id, DB_TEXT);
+ if (e)
+ {
+ while (e->enumerate(e, &prop))
+ {
+ proposal = proposal_create_from_string(PROTO_IKE, prop);
+ if (!proposal)
+ {
+ DBG1(DBG_CFG, "could not create IKE proposal from '%s'", prop);
+ break;
+ }
+ ike_cfg->add_proposal(ike_cfg, proposal);
+ use_default = FALSE;
+ }
+ e->destroy(e);
+ }
+ if (use_default)
+ {
+ ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
+ }
+}
+
+/**
+ * Build an IKE config from an SQL query
*/
static ike_cfg_t *build_ike_cfg(private_sql_config_t *this, enumerator_t *e,
host_t *my_host, host_t *other_host)
{
- int certreq, force_encap;
+ int id, certreq, force_encap;
char *local, *remote;
- while (e->enumerate(e, &certreq, &force_encap, &local, &remote))
+ while (e->enumerate(e, &id, &certreq, &force_encap, &local, &remote))
{
ike_cfg_t *ike_cfg;
ike_cfg = ike_cfg_create(certreq, force_encap,
local, IKEV2_UDP_PORT, remote, IKEV2_UDP_PORT);
- /* TODO: read proposal from db */
- ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
+ add_ike_proposals(this, ike_cfg, id);
return ike_cfg;
}
return NULL;
}
/**
- * Query a IKE config by its id
+ * Query an IKE config by its id
*/
static ike_cfg_t* get_ike_cfg_by_id(private_sql_config_t *this, int id)
{
@@ -200,10 +275,10 @@ static ike_cfg_t* get_ike_cfg_by_id(private_sql_config_t *this, int id)
ike_cfg_t *ike_cfg = NULL;
e = this->db->query(this->db,
- "SELECT certreq, force_encap, local, remote "
+ "SELECT id, certreq, force_encap, local, remote "
"FROM ike_configs WHERE id = ?",
DB_INT, id,
- DB_INT, DB_INT, DB_TEXT, DB_TEXT);
+ DB_INT, DB_INT, DB_INT, DB_TEXT, DB_TEXT);
if (e)
{
ike_cfg = build_ike_cfg(this, e, NULL, NULL);
@@ -246,7 +321,7 @@ static peer_cfg_t *get_peer_cfg_by_id(private_sql_config_t *this, int id)
}
/**
- * build a peer configuration from a SQL query
+ * Build a peer config from an SQL query
*/
static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
identification_t *me, identification_t *other)
@@ -325,10 +400,8 @@ static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
return NULL;
}
-/**
- * implements backend_t.get_peer_cfg_by_name.
- */
-static peer_cfg_t *get_peer_cfg_by_name(private_sql_config_t *this, char *name)
+METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
+ private_sql_config_t *this, char *name)
{
enumerator_t *e;
peer_cfg_t *peer_cfg = NULL;
@@ -398,11 +471,8 @@ static void ike_enumerator_destroy(ike_enumerator_t *this)
free(this);
}
-/**
- * Implementation of backend_t.create_ike_cfg_enumerator.
- */
-static enumerator_t* create_ike_cfg_enumerator(private_sql_config_t *this,
- host_t *me, host_t *other)
+METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
+ private_sql_config_t *this, host_t *me, host_t *other)
{
ike_enumerator_t *e = malloc_thing(ike_enumerator_t);
@@ -414,9 +484,9 @@ static enumerator_t* create_ike_cfg_enumerator(private_sql_config_t *this,
e->public.destroy = (void*)ike_enumerator_destroy;
e->inner = this->db->query(this->db,
- "SELECT certreq, force_encap, local, remote "
+ "SELECT id, certreq, force_encap, local, remote "
"FROM ike_configs",
- DB_INT, DB_INT, DB_TEXT, DB_TEXT);
+ DB_INT, DB_INT, DB_INT, DB_TEXT, DB_TEXT);
if (!e->inner)
{
free(e);
@@ -466,12 +536,8 @@ static void peer_enumerator_destroy(peer_enumerator_t *this)
free(this);
}
-/**
- * Implementation of backend_t.create_peer_cfg_enumerator.
- */
-static enumerator_t* create_peer_cfg_enumerator(private_sql_config_t *this,
- identification_t *me,
- identification_t *other)
+METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
+ private_sql_config_t *this, identification_t *me, identification_t *other)
{
peer_enumerator_t *e = malloc_thing(peer_enumerator_t);
@@ -508,10 +574,8 @@ static enumerator_t* create_peer_cfg_enumerator(private_sql_config_t *this,
return &e->public;
}
-/**
- * Implementation of sql_config_t.destroy.
- */
-static void destroy(private_sql_config_t *this)
+METHOD(sql_config_t, destroy, void,
+ private_sql_config_t *this)
{
free(this);
}
@@ -521,14 +585,19 @@ static void destroy(private_sql_config_t *this)
*/
sql_config_t *sql_config_create(database_t *db)
{
- private_sql_config_t *this = malloc_thing(private_sql_config_t);
-
- this->public.backend.create_peer_cfg_enumerator = (enumerator_t*(*)(backend_t*, identification_t *me, identification_t *other))create_peer_cfg_enumerator;
- this->public.backend.create_ike_cfg_enumerator = (enumerator_t*(*)(backend_t*, host_t *me, host_t *other))create_ike_cfg_enumerator;
- this->public.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name;
- this->public.destroy = (void(*)(sql_config_t*))destroy;
+ private_sql_config_t *this;
- this->db = db;
+ INIT(this,
+ .public = {
+ .backend = {
+ .create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
+ .create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
+ .get_peer_cfg_by_name = _get_peer_cfg_by_name,
+ },
+ .destroy = _destroy,
+ },
+ .db = db
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/sql/sql_cred.c b/src/libcharon/plugins/sql/sql_cred.c
index 12f4ab045..117eec921 100644
--- a/src/libcharon/plugins/sql/sql_cred.c
+++ b/src/libcharon/plugins/sql/sql_cred.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2010 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -37,6 +38,7 @@ struct private_sql_cred_t {
database_t *db;
};
+
/**
* enumerator over private keys
*/
@@ -49,11 +51,8 @@ typedef struct {
private_key_t *current;
} private_enumerator_t;
-/**
- * Implementation of private_enumerator_t.public.enumerate
- */
-static bool private_enumerator_enumerate(private_enumerator_t *this,
- private_key_t **key)
+METHOD(enumerator_t, private_enumerator_enumerate, bool,
+ private_enumerator_t *this, private_key_t **key)
{
chunk_t blob;
int type;
@@ -62,7 +61,7 @@ static bool private_enumerator_enumerate(private_enumerator_t *this,
while (this->inner->enumerate(this->inner, &type, &blob))
{
this->current = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
- BUILD_BLOB_ASN1_DER, blob,
+ BUILD_BLOB_PEM, blob,
BUILD_END);
if (this->current)
{
@@ -74,29 +73,25 @@ static bool private_enumerator_enumerate(private_enumerator_t *this,
return FALSE;
}
-/**
- * Implementation of private_enumerator_t.public.destroy
- */
-static void private_enumerator_destroy(private_enumerator_t *this)
+METHOD(enumerator_t, private_enumerator_destroy, void,
+ private_enumerator_t *this)
{
DESTROY_IF(this->current);
this->inner->destroy(this->inner);
free(this);
}
-/**
- * Implementation of credential_set_t.create_private_enumerator.
- */
-static enumerator_t* create_private_enumerator(private_sql_cred_t *this,
- key_type_t type,
- identification_t *id)
+METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
+ private_sql_cred_t *this, key_type_t type, identification_t *id)
{
private_enumerator_t *e;
- e = malloc_thing(private_enumerator_t);
- e->current = NULL;
- e->public.enumerate = (void*)private_enumerator_enumerate;
- e->public.destroy = (void*)private_enumerator_destroy;
+ INIT(e,
+ .public = {
+ .enumerate = (void*)_private_enumerator_enumerate,
+ .destroy = _private_enumerator_destroy,
+ },
+ );
if (id && id->get_type(id) != ID_ANY)
{
e->inner = this->db->query(this->db,
@@ -123,6 +118,7 @@ static enumerator_t* create_private_enumerator(private_sql_cred_t *this,
return &e->public;
}
+
/**
* enumerator over certificates
*/
@@ -135,11 +131,8 @@ typedef struct {
certificate_t *current;
} cert_enumerator_t;
-/**
- * Implementation of cert_enumerator_t.public.enumerate
- */
-static bool cert_enumerator_enumerate(cert_enumerator_t *this,
- certificate_t **cert)
+METHOD(enumerator_t, cert_enumerator_enumerate, bool,
+ cert_enumerator_t *this, certificate_t **cert)
{
chunk_t blob;
int type;
@@ -148,7 +141,7 @@ static bool cert_enumerator_enumerate(cert_enumerator_t *this,
while (this->inner->enumerate(this->inner, &type, &blob))
{
this->current = lib->creds->create(lib->creds, CRED_CERTIFICATE, type,
- BUILD_BLOB_ASN1_DER, blob,
+ BUILD_BLOB_PEM, blob,
BUILD_END);
if (this->current)
{
@@ -160,29 +153,26 @@ static bool cert_enumerator_enumerate(cert_enumerator_t *this,
return FALSE;
}
-/**
- * Implementation of cert_enumerator_t.public.destroy
- */
-static void cert_enumerator_destroy(cert_enumerator_t *this)
+METHOD(enumerator_t, cert_enumerator_destroy, void,
+ cert_enumerator_t *this)
{
DESTROY_IF(this->current);
this->inner->destroy(this->inner);
free(this);
}
-/**
- * Implementation of credential_set_t.create_cert_enumerator.
- */
-static enumerator_t* create_cert_enumerator(private_sql_cred_t *this,
- certificate_type_t cert, key_type_t key,
- identification_t *id, bool trusted)
+METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
+ private_sql_cred_t *this, certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted)
{
cert_enumerator_t *e;
- e = malloc_thing(cert_enumerator_t);
- e->current = NULL;
- e->public.enumerate = (void*)cert_enumerator_enumerate;
- e->public.destroy = (void*)cert_enumerator_destroy;
+ INIT(e,
+ .public = {
+ .enumerate = (void*)_cert_enumerator_enumerate,
+ .destroy = _cert_enumerator_destroy,
+ },
+ );
if (id && id->get_type(id) != ID_ANY)
{
e->inner = this->db->query(this->db,
@@ -213,6 +203,7 @@ static enumerator_t* create_cert_enumerator(private_sql_cred_t *this,
return &e->public;
}
+
/**
* enumerator over shared keys
*/
@@ -229,12 +220,9 @@ typedef struct {
shared_key_t *current;
} shared_enumerator_t;
-/**
- * Implementation of shared_enumerator_t.public.enumerate
- */
-static bool shared_enumerator_enumerate(shared_enumerator_t *this,
- shared_key_t **shared,
- id_match_t *me, id_match_t *other)
+METHOD(enumerator_t, shared_enumerator_enumerate, bool,
+ shared_enumerator_t *this, shared_key_t **shared,
+ id_match_t *me, id_match_t *other)
{
chunk_t blob;
int type;
@@ -261,31 +249,28 @@ static bool shared_enumerator_enumerate(shared_enumerator_t *this,
return FALSE;
}
-/**
- * Implementation of shared_enumerator_t.public.destroy
- */
-static void shared_enumerator_destroy(shared_enumerator_t *this)
+METHOD(enumerator_t, shared_enumerator_destroy, void,
+ shared_enumerator_t *this)
{
DESTROY_IF(this->current);
this->inner->destroy(this->inner);
free(this);
}
-/**
- * Implementation of credential_set_t.create_shared_enumerator.
- */
-static enumerator_t* create_shared_enumerator(private_sql_cred_t *this,
- shared_key_type_t type,
- identification_t *me, identification_t *other)
+METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
+ private_sql_cred_t *this, shared_key_type_t type,
+ identification_t *me, identification_t *other)
{
shared_enumerator_t *e;
- e = malloc_thing(shared_enumerator_t);
- e->me = me;
- e->other = other;
- e->current = NULL;
- e->public.enumerate = (void*)shared_enumerator_enumerate;
- e->public.destroy = (void*)shared_enumerator_destroy;
+ INIT(e,
+ .public = {
+ .enumerate = (void*)_shared_enumerator_enumerate,
+ .destroy = _shared_enumerator_destroy,
+ },
+ .me = me,
+ .other = other,
+ );
if (!me && !other)
{
e->inner = this->db->query(this->db,
@@ -329,36 +314,141 @@ static enumerator_t* create_shared_enumerator(private_sql_cred_t *this,
return &e->public;
}
+
/**
- * Implementation of credential_set_t.cache_cert.
+ * enumerator over CDPs
*/
-static void cache_cert(private_sql_cred_t *this, certificate_t *cert)
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** inner SQL enumerator */
+ enumerator_t *inner;
+ /** currently enumerated string */
+ char *current;
+} cdp_enumerator_t;
+
+/**
+ * types of CDPs
+ */
+typedef enum {
+ /** any available CDP */
+ CDP_TYPE_ANY = 0,
+ /** CRL */
+ CDP_TYPE_CRL,
+ /** OCSP Responder */
+ CDP_TYPE_OCSP,
+} cdp_type_t;
+
+METHOD(enumerator_t, cdp_enumerator_enumerate, bool,
+ cdp_enumerator_t *this, char **uri)
+{
+ char *text;
+
+ free(this->current);
+ while (this->inner->enumerate(this->inner, &text))
+ {
+ *uri = this->current = strdup(text);
+ return TRUE;
+ }
+ this->current = NULL;
+ return FALSE;
+}
+
+METHOD(enumerator_t, cdp_enumerator_destroy, void,
+ cdp_enumerator_t *this)
+{
+ free(this->current);
+ this->inner->destroy(this->inner);
+ free(this);
+}
+
+METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*,
+ private_sql_cred_t *this, certificate_type_t type, identification_t *id)
+{
+ cdp_enumerator_t *e;
+ cdp_type_t cdp_type;
+
+ switch (type)
+ { /* we serve CRLs and OCSP responders */
+ case CERT_X509_CRL:
+ cdp_type = CDP_TYPE_CRL;
+ break;
+ case CERT_X509_OCSP_RESPONSE:
+ cdp_type = CDP_TYPE_OCSP;
+ break;
+ case CERT_ANY:
+ cdp_type = CDP_TYPE_ANY;
+ break;
+ default:
+ return NULL;
+ }
+ INIT(e,
+ .public = {
+ .enumerate = (void*)_cdp_enumerator_enumerate,
+ .destroy = _cdp_enumerator_destroy,
+ },
+ );
+ if (id && id->get_type(id) != ID_ANY)
+ {
+ e->inner = this->db->query(this->db,
+ "SELECT dp.uri FROM certificate_distribution_points AS dp "
+ "JOIN certificate_authorities AS ca ON ca.id = dp.ca "
+ "JOIN certificates AS c ON c.id = ca.certificate "
+ "JOIN certificate_identity AS ci ON c.id = ci.certificate "
+ "JOIN identities AS i ON ci.identity = i.id "
+ "WHERE i.type = ? AND i.data = ? AND (? OR dp.type = ?)",
+ DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id),
+ DB_INT, cdp_type == CDP_TYPE_ANY, DB_INT, cdp_type,
+ DB_TEXT);
+ }
+ else
+ {
+ e->inner = this->db->query(this->db,
+ "SELECT dp.uri FROM certificate_distribution_points AS dp "
+ "WHERE (? OR dp.type = ?)",
+ DB_INT, cdp_type == CDP_TYPE_ANY, DB_INT, cdp_type,
+ DB_TEXT);
+ }
+ if (!e->inner)
+ {
+ free(e);
+ return NULL;
+ }
+ return &e->public;
+}
+
+METHOD(credential_set_t, cache_cert, void,
+ private_sql_cred_t *this, certificate_t *cert)
{
/* TODO: implement CRL caching to database */
}
-/**
- * Implementation of sql_cred_t.destroy.
- */
-static void destroy(private_sql_cred_t *this)
+METHOD(sql_cred_t, destroy, void,
+ private_sql_cred_t *this)
{
free(this);
}
+
/**
* Described in header.
*/
sql_cred_t *sql_cred_create(database_t *db)
{
- private_sql_cred_t *this = malloc_thing(private_sql_cred_t);
-
- this->public.set.create_private_enumerator = (void*)create_private_enumerator;
- this->public.set.create_cert_enumerator = (void*)create_cert_enumerator;
- this->public.set.create_shared_enumerator = (void*)create_shared_enumerator;
- this->public.set.create_cdp_enumerator = (void*)return_null;
- this->public.set.cache_cert = (void*)cache_cert;
- this->public.destroy = (void(*)(sql_cred_t*))destroy;
-
- this->db = db;
+ private_sql_cred_t *this;
+
+ INIT(this,
+ .public = {
+ .set = {
+ .create_private_enumerator = _create_private_enumerator,
+ .create_cert_enumerator = _create_cert_enumerator,
+ .create_shared_enumerator = _create_shared_enumerator,
+ .create_cdp_enumerator = _create_cdp_enumerator,
+ .cache_cert = _cache_cert,
+ },
+ .destroy = _destroy,
+ },
+ .db = db,
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/sql/sql_plugin.c b/src/libcharon/plugins/sql/sql_plugin.c
index 7b0a198d1..ad1eb91b1 100644
--- a/src/libcharon/plugins/sql/sql_plugin.c
+++ b/src/libcharon/plugins/sql/sql_plugin.c
@@ -53,10 +53,8 @@ struct private_sql_plugin_t {
sql_logger_t *logger;
};
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(private_sql_plugin_t *this)
+METHOD(plugin_t, destroy, void,
+ private_sql_plugin_t *this)
{
charon->backends->remove_backend(charon->backends, &this->config->backend);
lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
@@ -83,11 +81,15 @@ plugin_t *sql_plugin_create()
return NULL;
}
- this = malloc_thing(private_sql_plugin_t);
-
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+ INIT(this,
+ .public = {
+ .plugin = {
+ .destroy = _destroy,
+ },
+ },
+ .db = lib->db->create(lib->db, uri),
+ );
- this->db = lib->db->create(lib->db, uri);
if (!this->db)
{
DBG1(DBG_CFG, "sql plugin failed to connect to database");
diff --git a/src/libcharon/plugins/stroke/Makefile.am b/src/libcharon/plugins/stroke/Makefile.am
index 40888a40b..e561224e9 100644
--- a/src/libcharon/plugins/stroke/Makefile.am
+++ b/src/libcharon/plugins/stroke/Makefile.am
@@ -21,7 +21,6 @@ libstrongswan_stroke_la_SOURCES = \
stroke_cred.h stroke_cred.c \
stroke_ca.h stroke_ca.c \
stroke_attribute.h stroke_attribute.c \
- stroke_list.h stroke_list.c \
- stroke_shared_key.h stroke_shared_key.c
+ stroke_list.h stroke_list.c
libstrongswan_stroke_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/stroke/Makefile.in b/src/libcharon/plugins/stroke/Makefile.in
index e6e98838b..ccf3eeede 100644
--- a/src/libcharon/plugins/stroke/Makefile.in
+++ b/src/libcharon/plugins/stroke/Makefile.in
@@ -77,7 +77,7 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
libstrongswan_stroke_la_LIBADD =
am_libstrongswan_stroke_la_OBJECTS = stroke_plugin.lo stroke_socket.lo \
stroke_config.lo stroke_control.lo stroke_cred.lo stroke_ca.lo \
- stroke_attribute.lo stroke_list.lo stroke_shared_key.lo
+ stroke_attribute.lo stroke_list.lo
libstrongswan_stroke_la_OBJECTS = \
$(am_libstrongswan_stroke_la_OBJECTS)
libstrongswan_stroke_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -223,9 +223,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +262,8 @@ 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@
@@ -292,8 +292,7 @@ libstrongswan_stroke_la_SOURCES = \
stroke_cred.h stroke_cred.c \
stroke_ca.h stroke_ca.c \
stroke_attribute.h stroke_attribute.c \
- stroke_list.h stroke_list.c \
- stroke_shared_key.h stroke_shared_key.c
+ stroke_list.h stroke_list.c
libstrongswan_stroke_la_LDFLAGS = -module -avoid-version
all: all-am
@@ -386,7 +385,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_cred.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_list.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_plugin.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_shared_key.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_socket.Plo@am__quote@
.c.o:
diff --git a/src/libcharon/plugins/stroke/stroke_ca.c b/src/libcharon/plugins/stroke/stroke_ca.c
index 9a3ae0ab9..69e13deb9 100644
--- a/src/libcharon/plugins/stroke/stroke_ca.c
+++ b/src/libcharon/plugins/stroke/stroke_ca.c
@@ -113,6 +113,7 @@ static void ca_section_destroy(ca_section_t *this)
this->crl->destroy_function(this->crl, free);
this->ocsp->destroy_function(this->ocsp, free);
this->hashes->destroy_offset(this->hashes, offsetof(identification_t, destroy));
+ this->cert->destroy(this->cert);
free(this->certuribase);
free(this->name);
free(this);
@@ -207,11 +208,8 @@ static enumerator_t *create_inner_cdp_hashandurl(ca_section_t *section, cdp_data
return enumerator;
}
-/**
- * Implementation of credential_set_t.create_cdp_enumerator.
- */
-static enumerator_t *create_cdp_enumerator(private_stroke_ca_t *this,
- certificate_type_t type, identification_t *id)
+METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*,
+ private_stroke_ca_t *this, certificate_type_t type, identification_t *id)
{
cdp_data_t *data;
@@ -235,10 +233,9 @@ static enumerator_t *create_cdp_enumerator(private_stroke_ca_t *this,
(type == CERT_X509) ? (void*)create_inner_cdp_hashandurl : (void*)create_inner_cdp,
data, (void*)cdp_data_destroy);
}
-/**
- * Implementation of stroke_ca_t.add.
- */
-static void add(private_stroke_ca_t *this, stroke_msg_t *msg)
+
+METHOD(stroke_ca_t, add, void,
+ private_stroke_ca_t *this, stroke_msg_t *msg)
{
certificate_t *cert;
ca_section_t *ca;
@@ -279,10 +276,8 @@ static void add(private_stroke_ca_t *this, stroke_msg_t *msg)
}
}
-/**
- * Implementation of stroke_ca_t.del.
- */
-static void del(private_stroke_ca_t *this, stroke_msg_t *msg)
+METHOD(stroke_ca_t, del, void,
+ private_stroke_ca_t *this, stroke_msg_t *msg)
{
enumerator_t *enumerator;
ca_section_t *ca = NULL;
@@ -336,10 +331,8 @@ static void list_uris(linked_list_t *list, char *label, FILE *out)
enumerator->destroy(enumerator);
}
-/**
- * Implementation of stroke_ca_t.check_for_hash_and_url.
- */
-static void check_for_hash_and_url(private_stroke_ca_t *this, certificate_t* cert)
+METHOD(stroke_ca_t, check_for_hash_and_url, void,
+ private_stroke_ca_t *this, certificate_t* cert)
{
ca_section_t *section;
enumerator_t *enumerator;
@@ -376,10 +369,8 @@ static void check_for_hash_and_url(private_stroke_ca_t *this, certificate_t* cer
hasher->destroy(hasher);
}
-/**
- * Implementation of stroke_ca_t.list.
- */
-static void list(private_stroke_ca_t *this, stroke_msg_t *msg, FILE *out)
+METHOD(stroke_ca_t, list, void,
+ private_stroke_ca_t *this, stroke_msg_t *msg, FILE *out)
{
bool first = TRUE;
ca_section_t *section;
@@ -426,10 +417,8 @@ static void list(private_stroke_ca_t *this, stroke_msg_t *msg, FILE *out)
this->lock->unlock(this->lock);
}
-/**
- * Implementation of stroke_ca_t.destroy
- */
-static void destroy(private_stroke_ca_t *this)
+METHOD(stroke_ca_t, destroy, void,
+ private_stroke_ca_t *this)
{
this->sections->destroy_function(this->sections, (void*)ca_section_destroy);
this->lock->destroy(this->lock);
@@ -441,22 +430,27 @@ static void destroy(private_stroke_ca_t *this)
*/
stroke_ca_t *stroke_ca_create(stroke_cred_t *cred)
{
- private_stroke_ca_t *this = malloc_thing(private_stroke_ca_t);
-
- this->public.set.create_private_enumerator = (void*)return_null;
- this->public.set.create_cert_enumerator = (void*)return_null;
- this->public.set.create_shared_enumerator = (void*)return_null;
- this->public.set.create_cdp_enumerator = (void*)create_cdp_enumerator;
- this->public.set.cache_cert = (void*)nop;
- this->public.add = (void(*)(stroke_ca_t*, stroke_msg_t *msg))add;
- this->public.del = (void(*)(stroke_ca_t*, stroke_msg_t *msg))del;
- this->public.list = (void(*)(stroke_ca_t*, stroke_msg_t *msg, FILE *out))list;
- this->public.check_for_hash_and_url = (void(*)(stroke_ca_t*, certificate_t*))check_for_hash_and_url;
- this->public.destroy = (void(*)(stroke_ca_t*))destroy;
-
- this->sections = linked_list_create();
- this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
- this->cred = cred;
+ private_stroke_ca_t *this;
+
+ INIT(this,
+ .public = {
+ .set = {
+ .create_private_enumerator = (void*)return_null,
+ .create_cert_enumerator = (void*)return_null,
+ .create_shared_enumerator = (void*)return_null,
+ .create_cdp_enumerator = _create_cdp_enumerator,
+ .cache_cert = (void*)nop,
+ },
+ .add = _add,
+ .del = _del,
+ .list = _list,
+ .check_for_hash_and_url = _check_for_hash_and_url,
+ .destroy = _destroy,
+ },
+ .sections = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ .cred = cred,
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c
index 165212a5e..ea7d17592 100644
--- a/src/libcharon/plugins/stroke/stroke_config.c
+++ b/src/libcharon/plugins/stroke/stroke_config.c
@@ -53,12 +53,8 @@ struct private_stroke_config_t {
stroke_cred_t *cred;
};
-/**
- * Implementation of backend_t.create_peer_cfg_enumerator.
- */
-static enumerator_t* create_peer_cfg_enumerator(private_stroke_config_t *this,
- identification_t *me,
- identification_t *other)
+METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
+ private_stroke_config_t *this, identification_t *me, identification_t *other)
{
this->mutex->lock(this->mutex);
return enumerator_create_cleaner(this->list->create_enumerator(this->list),
@@ -74,11 +70,8 @@ static bool ike_filter(void *data, peer_cfg_t **in, ike_cfg_t **out)
return TRUE;
}
-/**
- * Implementation of backend_t.create_ike_cfg_enumerator.
- */
-static enumerator_t* create_ike_cfg_enumerator(private_stroke_config_t *this,
- host_t *me, host_t *other)
+METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
+ private_stroke_config_t *this, host_t *me, host_t *other)
{
this->mutex->lock(this->mutex);
return enumerator_create_filter(this->list->create_enumerator(this->list),
@@ -86,10 +79,8 @@ static enumerator_t* create_ike_cfg_enumerator(private_stroke_config_t *this,
(void*)this->mutex->unlock);
}
-/**
- * implements backend_t.get_peer_cfg_by_name.
- */
-static peer_cfg_t *get_peer_cfg_by_name(private_stroke_config_t *this, char *name)
+METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
+ private_stroke_config_t *this, char *name)
{
enumerator_t *e1, *e2;
peer_cfg_t *current, *found = NULL;
@@ -438,13 +429,38 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
enumerator->destroy(enumerator);
}
+ /* certificatePolicies */
+ if (end->cert_policy)
+ {
+ enumerator_t *enumerator;
+ char *policy;
+
+ enumerator = enumerator_create_token(end->cert_policy, ",", " ");
+ while (enumerator->enumerate(enumerator, &policy))
+ {
+ cfg->add(cfg, AUTH_RULE_CERT_POLICY, strdup(policy));
+ }
+ enumerator->destroy(enumerator);
+ }
+
/* authentication metod (class, actually) */
if (streq(auth, "pubkey") ||
- streq(auth, "rsasig") || streq(auth, "rsa") ||
- streq(auth, "ecdsasig") || streq(auth, "ecdsa"))
+ strneq(auth, "rsa", strlen("rsa")) ||
+ strneq(auth, "ecdsa", strlen("ecdsa")))
{
+ u_int strength;
+
cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
build_crl_policy(cfg, local, msg->add_conn.crl_policy);
+
+ if (sscanf(auth, "rsa-%d", &strength) == 1)
+ {
+ cfg->add(cfg, AUTH_RULE_RSA_STRENGTH, (uintptr_t)strength);
+ }
+ if (sscanf(auth, "ecdsa-%d", &strength) == 1)
+ {
+ cfg->add(cfg, AUTH_RULE_ECDSA_STRENGTH, (uintptr_t)strength);
+ }
}
else if (streq(auth, "psk") || streq(auth, "secret"))
{
@@ -808,9 +824,9 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
child_cfg = child_cfg_create(
msg->add_conn.name, &lifetime,
msg->add_conn.me.updown, msg->add_conn.me.hostaccess,
- msg->add_conn.mode, dpd, dpd, msg->add_conn.ipcomp,
+ msg->add_conn.mode, ACTION_NONE, dpd, dpd, msg->add_conn.ipcomp,
msg->add_conn.inactivity, msg->add_conn.reqid,
- &mark_in, &mark_out);
+ &mark_in, &mark_out, msg->add_conn.tfc);
child_cfg->set_mipv6_options(child_cfg, msg->add_conn.proxy_mode,
msg->add_conn.install_policy);
add_ts(this, &msg->add_conn.me, child_cfg, TRUE);
@@ -821,10 +837,8 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
return child_cfg;
}
-/**
- * Implementation of stroke_config_t.add.
- */
-static void add(private_stroke_config_t *this, stroke_msg_t *msg)
+METHOD(stroke_config_t, add, void,
+ private_stroke_config_t *this, stroke_msg_t *msg)
{
ike_cfg_t *ike_cfg, *existing_ike;
peer_cfg_t *peer_cfg, *existing;
@@ -884,10 +898,8 @@ static void add(private_stroke_config_t *this, stroke_msg_t *msg)
}
}
-/**
- * Implementation of stroke_config_t.del.
- */
-static void del(private_stroke_config_t *this, stroke_msg_t *msg)
+METHOD(stroke_config_t, del, void,
+ private_stroke_config_t *this, stroke_msg_t *msg)
{
enumerator_t *enumerator, *children;
peer_cfg_t *peer;
@@ -938,10 +950,8 @@ static void del(private_stroke_config_t *this, stroke_msg_t *msg)
}
}
-/**
- * Implementation of stroke_config_t.destroy
- */
-static void destroy(private_stroke_config_t *this)
+METHOD(stroke_config_t, destroy, void,
+ private_stroke_config_t *this)
{
this->list->destroy_offset(this->list, offsetof(peer_cfg_t, destroy));
this->mutex->destroy(this->mutex);
@@ -953,19 +963,24 @@ static void destroy(private_stroke_config_t *this)
*/
stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred)
{
- private_stroke_config_t *this = malloc_thing(private_stroke_config_t);
-
- this->public.backend.create_peer_cfg_enumerator = (enumerator_t*(*)(backend_t*, identification_t *me, identification_t *other))create_peer_cfg_enumerator;
- this->public.backend.create_ike_cfg_enumerator = (enumerator_t*(*)(backend_t*, host_t *me, host_t *other))create_ike_cfg_enumerator;
- this->public.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name;
- this->public.add = (void(*)(stroke_config_t*, stroke_msg_t *msg))add;
- this->public.del = (void(*)(stroke_config_t*, stroke_msg_t *msg))del;
- this->public.destroy = (void(*)(stroke_config_t*))destroy;
-
- this->list = linked_list_create();
- this->mutex = mutex_create(MUTEX_TYPE_RECURSIVE);
- this->ca = ca;
- this->cred = cred;
+ private_stroke_config_t *this;
+
+ INIT(this,
+ .public = {
+ .backend = {
+ .create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
+ .create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
+ .get_peer_cfg_by_name = _get_peer_cfg_by_name,
+ },
+ .add = _add,
+ .del = _del,
+ .destroy = _destroy,
+ },
+ .list = linked_list_create(),
+ .mutex = mutex_create(MUTEX_TYPE_RECURSIVE),
+ .ca = ca,
+ .cred = cred,
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c
index e0398ba78..3541ab8f9 100644
--- a/src/libcharon/plugins/stroke/stroke_control.c
+++ b/src/libcharon/plugins/stroke/stroke_control.c
@@ -17,6 +17,8 @@
#include <daemon.h>
#include <processing/jobs/delete_ike_sa_job.h>
+#include <processing/jobs/rekey_ike_sa_job.h>
+#include <processing/jobs/rekey_child_sa_job.h>
typedef struct private_stroke_control_t private_stroke_control_t;
@@ -90,10 +92,8 @@ static child_cfg_t* get_child_from_peer(peer_cfg_t *peer_cfg, char *name)
return found;
}
-/**
- * Implementation of stroke_control_t.initiate.
- */
-static void initiate(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
+METHOD(stroke_control_t, initiate, void,
+ private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
{
peer_cfg_t *peer_cfg;
child_cfg_t *child_cfg;
@@ -137,76 +137,89 @@ static void initiate(private_stroke_control_t *this, stroke_msg_t *msg, FILE *ou
}
/**
- * Implementation of stroke_control_t.terminate.
+ * Parse a terminate/rekey specifier
*/
-static void terminate(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
+static bool parse_specifier(char *string, u_int32_t *id,
+ char **name, bool *child, bool *all)
{
- char *string, *pos = NULL, *name = NULL;
- u_int32_t id = 0;
- bool child, all = FALSE;
int len;
- ike_sa_t *ike_sa;
- enumerator_t *enumerator;
- linked_list_t *ike_list, *child_list;
- stroke_log_info_t info;
- uintptr_t del;
+ char *pos = NULL;
- string = msg->terminate.name;
+ *id = 0;
+ *name = NULL;
+ *all = FALSE;
len = strlen(string);
if (len < 1)
{
- DBG1(DBG_CFG, "error parsing string");
- return;
+ return FALSE;
}
switch (string[len-1])
{
case '}':
- child = TRUE;
+ *child = TRUE;
pos = strchr(string, '{');
break;
case ']':
- child = FALSE;
+ *child = FALSE;
pos = strchr(string, '[');
break;
default:
- name = string;
- child = FALSE;
+ *name = string;
+ *child = FALSE;
break;
}
- if (name)
+ if (*name)
{
/* is a single name */
}
else if (pos == string + len - 2)
{ /* is name[] or name{} */
string[len-2] = '\0';
- name = string;
+ *name = string;
}
else
{
if (!pos)
{
- DBG1(DBG_CFG, "error parsing string");
- return;
+ return FALSE;
}
if (*(pos + 1) == '*')
{ /* is name[*] */
- all = TRUE;
+ *all = TRUE;
*pos = '\0';
- name = string;
+ *name = string;
}
else
{ /* is name[123] or name{23} */
- id = atoi(pos + 1);
- if (id == 0)
+ *id = atoi(pos + 1);
+ if (*id == 0)
{
- DBG1(DBG_CFG, "error parsing string");
- return;
+ return FALSE;
}
}
}
+ return TRUE;
+}
+
+METHOD(stroke_control_t, terminate, void,
+ private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
+{
+ char *name;
+ u_int32_t id;
+ bool child, all;
+ ike_sa_t *ike_sa;
+ enumerator_t *enumerator;
+ linked_list_t *ike_list, *child_list;
+ stroke_log_info_t info;
+ uintptr_t del;
+
+ if (!parse_specifier(msg->terminate.name, &id, &name, &child, &all))
+ {
+ DBG1(DBG_CFG, "error parsing specifier string");
+ return;
+ }
info.out = out;
info.level = msg->output_verbosity;
@@ -293,11 +306,68 @@ static void terminate(private_stroke_control_t *this, stroke_msg_t *msg, FILE *o
child_list->destroy(child_list);
}
-/**
- * Implementation of stroke_control_t.terminate_srcip.
- */
-static void terminate_srcip(private_stroke_control_t *this,
- stroke_msg_t *msg, FILE *out)
+METHOD(stroke_control_t, rekey, void,
+ private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
+{
+ char *name;
+ u_int32_t id;
+ bool child, all, finished = FALSE;
+ ike_sa_t *ike_sa;
+ enumerator_t *enumerator;
+
+ if (!parse_specifier(msg->terminate.name, &id, &name, &child, &all))
+ {
+ DBG1(DBG_CFG, "error parsing specifier string");
+ return;
+ }
+ enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ while (enumerator->enumerate(enumerator, &ike_sa))
+ {
+ child_sa_t *child_sa;
+ iterator_t *children;
+
+ if (child)
+ {
+ children = ike_sa->create_child_sa_iterator(ike_sa);
+ while (children->iterate(children, (void**)&child_sa))
+ {
+ if ((name && streq(name, child_sa->get_name(child_sa))) ||
+ (id && id == child_sa->get_reqid(child_sa)))
+ {
+ lib->processor->queue_job(lib->processor,
+ (job_t*)rekey_child_sa_job_create(
+ child_sa->get_reqid(child_sa),
+ child_sa->get_protocol(child_sa),
+ child_sa->get_spi(child_sa, TRUE)));
+ if (!all)
+ {
+ finished = TRUE;
+ break;
+ }
+ }
+ }
+ children->destroy(children);
+ }
+ else if ((name && streq(name, ike_sa->get_name(ike_sa))) ||
+ (id && id == ike_sa->get_unique_id(ike_sa)))
+ {
+ lib->processor->queue_job(lib->processor,
+ (job_t*)rekey_ike_sa_job_create(ike_sa->get_id(ike_sa), FALSE));
+ if (!all)
+ {
+ finished = TRUE;
+ }
+ }
+ if (finished)
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(stroke_control_t, terminate_srcip, void,
+ private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
{
enumerator_t *enumerator;
ike_sa_t *ike_sa;
@@ -362,10 +432,8 @@ static void terminate_srcip(private_stroke_control_t *this,
DESTROY_IF(end);
}
-/**
- * Implementation of stroke_control_t.purge_ike
- */
-static void purge_ike(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
+METHOD(stroke_control_t, purge_ike, void,
+ private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
{
enumerator_t *enumerator;
iterator_t *iterator;
@@ -402,10 +470,8 @@ static void purge_ike(private_stroke_control_t *this, stroke_msg_t *msg, FILE *o
list->destroy(list);
}
-/**
- * Implementation of stroke_control_t.route.
- */
-static void route(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
+METHOD(stroke_control_t, route, void,
+ private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
{
peer_cfg_t *peer_cfg;
child_cfg_t *child_cfg;
@@ -443,10 +509,8 @@ static void route(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
child_cfg->destroy(child_cfg);
}
-/**
- * Implementation of stroke_control_t.unroute.
- */
-static void unroute(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
+METHOD(stroke_control_t, unroute, void,
+ private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
{
child_sa_t *child_sa;
enumerator_t *enumerator;
@@ -468,10 +532,8 @@ static void unroute(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out
fprintf(out, "configuration '%s' not found\n", msg->unroute.name);
}
-/**
- * Implementation of stroke_control_t.destroy
- */
-static void destroy(private_stroke_control_t *this)
+METHOD(stroke_control_t, destroy, void,
+ private_stroke_control_t *this)
{
free(this);
}
@@ -481,15 +543,20 @@ static void destroy(private_stroke_control_t *this)
*/
stroke_control_t *stroke_control_create()
{
- private_stroke_control_t *this = malloc_thing(private_stroke_control_t);
-
- this->public.initiate = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))initiate;
- this->public.terminate = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))terminate;
- this->public.terminate_srcip = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))terminate_srcip;
- this->public.purge_ike = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))purge_ike;
- this->public.route = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))route;
- this->public.unroute = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))unroute;
- this->public.destroy = (void(*)(stroke_control_t*))destroy;
+ private_stroke_control_t *this;
+
+ INIT(this,
+ .public = {
+ .initiate = _initiate,
+ .terminate = _terminate,
+ .terminate_srcip = _terminate_srcip,
+ .rekey = _rekey,
+ .purge_ike = _purge_ike,
+ .route = _route,
+ .unroute = _unroute,
+ .destroy = _destroy,
+ },
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/stroke/stroke_control.h b/src/libcharon/plugins/stroke/stroke_control.h
index 9b49bdc31..869aab3d3 100644
--- a/src/libcharon/plugins/stroke/stroke_control.h
+++ b/src/libcharon/plugins/stroke/stroke_control.h
@@ -54,6 +54,13 @@ struct stroke_control_t {
void (*terminate_srcip)(stroke_control_t *this, stroke_msg_t *msg, FILE *out);
/**
+ * Rekey a connection.
+ *
+ * @param msg stroke message
+ */
+ void (*rekey)(stroke_control_t *this, stroke_msg_t *msg, FILE *out);
+
+ /**
* Delete IKE_SAs without a CHILD_SA.
*
* @param msg stroke message
diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c
index 91e71f1f4..83e5a9ad6 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.c
+++ b/src/libcharon/plugins/stroke/stroke_cred.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2010 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -25,7 +25,6 @@
#include <unistd.h>
#include "stroke_cred.h"
-#include "stroke_shared_key.h"
#include <credentials/certificates/x509.h>
#include <credentials/certificates/crl.h>
@@ -64,24 +63,9 @@ struct private_stroke_cred_t {
stroke_cred_t public;
/**
- * list of trusted peer/signer/CA certificates (certificate_t)
+ * credentials
*/
- linked_list_t *certs;
-
- /**
- * list of shared secrets (private_shared_key_t)
- */
- linked_list_t *shared;
-
- /**
- * list of private keys (private_key_t)
- */
- linked_list_t *private;
-
- /**
- * read-write lock to lists
- */
- rwlock_t *lock;
+ mem_cred_t *creds;
/**
* cache CRLs to disk?
@@ -90,237 +74,6 @@ struct private_stroke_cred_t {
};
/**
- * data to pass to various filters
- */
-typedef struct {
- private_stroke_cred_t *this;
- identification_t *id;
- certificate_type_t cert;
- key_type_t key;
-} id_data_t;
-
-/**
- * destroy id enumerator data and unlock list
- */
-static void id_data_destroy(id_data_t *data)
-{
- data->this->lock->unlock(data->this->lock);
- free(data);
-}
-
-/**
- * filter function for private key enumerator
- */
-static bool private_filter(id_data_t *data,
- private_key_t **in, private_key_t **out)
-{
- private_key_t *key;
-
- key = *in;
- if (data->key == KEY_ANY || data->key == key->get_type(key))
- {
- if (data->id == NULL)
- {
- *out = key;
- return TRUE;
- }
- if (key->has_fingerprint(key, data->id->get_encoding(data->id)))
- {
- *out = key;
- return TRUE;
- }
- }
- return FALSE;
-}
-
-/**
- * Implements credential_set_t.create_private_enumerator
- */
-static enumerator_t* create_private_enumerator(private_stroke_cred_t *this,
- key_type_t type, identification_t *id)
-{
- id_data_t *data;
-
- data = malloc_thing(id_data_t);
- data->this = this;
- data->id = id;
- data->key = type;
-
- this->lock->read_lock(this->lock);
- return enumerator_create_filter(this->private->create_enumerator(this->private),
- (void*)private_filter, data,
- (void*)id_data_destroy);
-}
-
-/**
- * filter function for certs enumerator
- */
-static bool certs_filter(id_data_t *data, certificate_t **in, certificate_t **out)
-{
- public_key_t *public;
- certificate_t *cert = *in;
-
- if (data->cert != CERT_ANY && data->cert != cert->get_type(cert))
- {
- return FALSE;
- }
- if (data->id == NULL || cert->has_subject(cert, data->id))
- {
- *out = *in;
- return TRUE;
- }
-
- public = cert->get_public_key(cert);
- if (public)
- {
- if (data->key == KEY_ANY || data->key != public->get_type(public))
- {
- if (public->has_fingerprint(public, data->id->get_encoding(data->id)))
- {
- public->destroy(public);
- *out = *in;
- return TRUE;
- }
- }
- public->destroy(public);
- }
- return FALSE;
-}
-
-/**
- * Implements credential_set_t.create_cert_enumerator
- */
-static enumerator_t* create_cert_enumerator(private_stroke_cred_t *this,
- certificate_type_t cert, key_type_t key,
- identification_t *id, bool trusted)
-{
- id_data_t *data;
-
- if (trusted && (cert == CERT_X509_CRL || cert == CERT_X509_AC))
- {
- return NULL;
- }
- data = malloc_thing(id_data_t);
- data->this = this;
- data->id = id;
- data->cert = cert;
- data->key = key;
-
- this->lock->read_lock(this->lock);
- return enumerator_create_filter(this->certs->create_enumerator(this->certs),
- (void*)certs_filter, data,
- (void*)id_data_destroy);
-}
-
-typedef struct {
- private_stroke_cred_t *this;
- identification_t *me;
- identification_t *other;
- shared_key_type_t type;
-} shared_data_t;
-
-/**
- * free shared key enumerator data and unlock list
- */
-static void shared_data_destroy(shared_data_t *data)
-{
- data->this->lock->unlock(data->this->lock);
- free(data);
-}
-
-/**
- * filter function for certs enumerator
- */
-static bool shared_filter(shared_data_t *data,
- stroke_shared_key_t **in, shared_key_t **out,
- void **unused1, id_match_t *me,
- void **unused2, id_match_t *other)
-{
- id_match_t my_match = ID_MATCH_NONE, other_match = ID_MATCH_NONE;
- stroke_shared_key_t *stroke = *in;
- shared_key_t *shared = &stroke->shared;
-
- if (data->type != SHARED_ANY && shared->get_type(shared) != data->type)
- {
- return FALSE;
- }
-
- if (data->me)
- {
- my_match = stroke->has_owner(stroke, data->me);
- }
- if (data->other)
- {
- other_match = stroke->has_owner(stroke, data->other);
- }
- if ((data->me || data->other) && (!my_match && !other_match))
- {
- return FALSE;
- }
- *out = shared;
- if (me)
- {
- *me = my_match;
- }
- if (other)
- {
- *other = other_match;
- }
- return TRUE;
-}
-
-/**
- * Implements credential_set_t.create_shared_enumerator
- */
-static enumerator_t* create_shared_enumerator(private_stroke_cred_t *this,
- shared_key_type_t type, identification_t *me,
- identification_t *other)
-{
- shared_data_t *data = malloc_thing(shared_data_t);
-
- data->this = this;
- data->me = me;
- data->other = other;
- data->type = type;
- this->lock->read_lock(this->lock);
- return enumerator_create_filter(this->shared->create_enumerator(this->shared),
- (void*)shared_filter, data,
- (void*)shared_data_destroy);
-}
-
-/**
- * Add a certificate to chain
- */
-static certificate_t* add_cert(private_stroke_cred_t *this, certificate_t *cert)
-{
- certificate_t *current;
- enumerator_t *enumerator;
- bool new = TRUE;
-
- this->lock->read_lock(this->lock);
- enumerator = this->certs->create_enumerator(this->certs);
- while (enumerator->enumerate(enumerator, (void**)&current))
- {
- if (current->equals(current, cert))
- {
- /* cert already in queue */
- cert->destroy(cert);
- cert = current;
- new = FALSE;
- break;
- }
- }
- enumerator->destroy(enumerator);
-
- if (new)
- {
- this->certs->insert_last(this->certs, cert);
- }
- this->lock->unlock(this->lock);
- return cert;
-}
-
-/**
* Implementation of stroke_cred_t.load_ca.
*/
static certificate_t* load_ca(private_stroke_cred_t *this, char *filename)
@@ -352,85 +105,12 @@ static certificate_t* load_ca(private_stroke_cred_t *this, char *filename)
cert->destroy(cert);
return NULL;
}
- return (certificate_t*)add_cert(this, cert);
+ return this->creds->add_cert_ref(this->creds, TRUE, cert);
}
return NULL;
}
/**
- * Add X.509 CRL to chain
- */
-static bool add_crl(private_stroke_cred_t *this, crl_t* crl)
-{
- certificate_t *current, *cert = &crl->certificate;
- enumerator_t *enumerator;
- bool new = TRUE, found = FALSE;
-
- this->lock->write_lock(this->lock);
- enumerator = this->certs->create_enumerator(this->certs);
- while (enumerator->enumerate(enumerator, (void**)&current))
- {
- if (current->get_type(current) == CERT_X509_CRL)
- {
- crl_t *crl_c = (crl_t*)current;
- chunk_t authkey = crl->get_authKeyIdentifier(crl);
- chunk_t authkey_c = crl_c->get_authKeyIdentifier(crl_c);
-
- /* if compare authorityKeyIdentifiers if available */
- if (authkey.ptr && authkey_c.ptr && chunk_equals(authkey, authkey_c))
- {
- found = TRUE;
- }
- else
- {
- identification_t *issuer = cert->get_issuer(cert);
- identification_t *issuer_c = current->get_issuer(current);
-
- /* otherwise compare issuer distinguished names */
- if (issuer->equals(issuer, issuer_c))
- {
- found = TRUE;
- }
- }
- if (found)
- {
- new = crl_is_newer(crl, crl_c);
- if (new)
- {
- this->certs->remove_at(this->certs, enumerator);
- }
- else
- {
- cert->destroy(cert);
- }
- break;
- }
- }
- }
- enumerator->destroy(enumerator);
-
- if (new)
- {
- this->certs->insert_last(this->certs, cert);
- }
- this->lock->unlock(this->lock);
- return new;
-}
-
-/**
- * Add X.509 attribute certificate to chain
- */
-static bool add_ac(private_stroke_cred_t *this, ac_t* ac)
-{
- certificate_t *cert = &ac->certificate;
-
- this->lock->write_lock(this->lock);
- this->certs->insert_last(this->certs, cert);
- this->lock->unlock(this->lock);
- return TRUE;
-}
-
-/**
* Implementation of stroke_cred_t.load_peer.
*/
static certificate_t* load_peer(private_stroke_cred_t *this, char *filename)
@@ -453,10 +133,10 @@ static certificate_t* load_peer(private_stroke_cred_t *this, char *filename)
BUILD_END);
if (cert)
{
- cert = add_cert(this, cert);
+ cert = this->creds->add_cert_ref(this->creds, TRUE, cert);
DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'",
cert->get_subject(cert), filename);
- return cert->get_ref(cert);
+ return cert;
}
DBG1(DBG_CFG, " loading certificate from '%s' failed", filename);
return NULL;
@@ -511,8 +191,8 @@ static void load_certdir(private_stroke_cred_t *this, char *path,
}
else
{
- DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
- cert->get_subject(cert), file);
+ DBG1(DBG_CFG, " loaded ca certificate \"%Y\" "
+ "from '%s'", cert->get_subject(cert), file);
}
}
else
@@ -540,7 +220,7 @@ static void load_certdir(private_stroke_cred_t *this, char *path,
}
if (cert)
{
- add_cert(this, cert);
+ this->creds->add_cert(this->creds, TRUE, cert);
}
break;
case CERT_X509_CRL:
@@ -550,7 +230,7 @@ static void load_certdir(private_stroke_cred_t *this, char *path,
BUILD_END);
if (cert)
{
- add_crl(this, (crl_t*)cert);
+ this->creds->add_crl(this->creds, (crl_t*)cert);
DBG1(DBG_CFG, " loaded crl from '%s'", file);
}
else
@@ -565,7 +245,7 @@ static void load_certdir(private_stroke_cred_t *this, char *path,
BUILD_END);
if (cert)
{
- add_ac(this, (ac_t*)cert);
+ this->creds->add_cert(this->creds, FALSE, cert);
DBG1(DBG_CFG, " loaded attribute certificate from '%s'",
file);
}
@@ -593,7 +273,7 @@ static void cache_cert(private_stroke_cred_t *this, certificate_t *cert)
crl_t *crl = (crl_t*)cert;
cert->get_ref(cert);
- if (add_crl(this, crl))
+ if (this->creds->add_crl(this->creds, crl))
{
char buf[BUF_LEN];
chunk_t chunk, hex;
@@ -914,7 +594,6 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
}
/* unlock: smartcard needs the pin and potentially calls public set */
- this->lock->unlock(this->lock);
switch (format)
{
case SC_FORMAT_SLOT_MODULE_KEYID:
@@ -936,7 +615,6 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
BUILD_PKCS11_KEYID, chunk, BUILD_END);
break;
}
- this->lock->write_lock(this->lock);
if (mem)
{
lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
@@ -951,7 +629,7 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
if (key)
{
DBG1(DBG_CFG, " loaded private key from %.*s", sc.len, sc.ptr);
- this->private->insert_last(this->private, key);
+ this->creds->add_key(this->creds, key);
}
return TRUE;
}
@@ -1022,11 +700,8 @@ static bool load_private(private_stroke_cred_t *this, chunk_t line, int line_nr,
cb = callback_cred_create_shared((void*)passphrase_cb, &pp_data);
lib->credmgr->add_local_set(lib->credmgr, &cb->set);
- /* unlock, as the builder might ask for a secret */
- this->lock->unlock(this->lock);
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, key_type,
BUILD_FROM_FILE, path, BUILD_END);
- this->lock->write_lock(this->lock);
lib->credmgr->remove_local_set(lib->credmgr, &cb->set);
cb->destroy(cb);
@@ -1042,11 +717,8 @@ static bool load_private(private_stroke_cred_t *this, chunk_t line, int line_nr,
mem->add_shared(mem, shared, NULL);
lib->credmgr->add_local_set(lib->credmgr, &mem->set);
- /* unlock, as the builder might ask for a secret */
- this->lock->unlock(this->lock);
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, key_type,
BUILD_FROM_FILE, path, BUILD_END);
- this->lock->write_lock(this->lock);
lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
mem->destroy(mem);
@@ -1055,7 +727,7 @@ static bool load_private(private_stroke_cred_t *this, chunk_t line, int line_nr,
{
DBG1(DBG_CFG, " loaded %N private key from '%s'",
key_type_names, key->get_type(key), path);
- this->private->insert_last(this->private, key);
+ this->creds->add_key(this->creds, key);
}
else
{
@@ -1070,7 +742,8 @@ static bool load_private(private_stroke_cred_t *this, chunk_t line, int line_nr,
static bool load_shared(private_stroke_cred_t *this, chunk_t line, int line_nr,
shared_key_type_t type, chunk_t ids)
{
- stroke_shared_key_t *shared_key;
+ shared_key_t *shared_key;
+ linked_list_t *owners;
chunk_t secret = chunk_empty;
bool any = TRUE;
@@ -1080,12 +753,12 @@ static bool load_shared(private_stroke_cred_t *this, chunk_t line, int line_nr,
DBG1(DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh);
return FALSE;
}
- shared_key = stroke_shared_key_create(type, secret);
+ shared_key = shared_key_create(type, secret);
DBG1(DBG_CFG, " loaded %N secret for %s", shared_key_type_names, type,
ids.len > 0 ? (char*)ids.ptr : "%any");
DBG4(DBG_CFG, " secret: %#B", &secret);
- this->shared->insert_last(this->shared, shared_key);
+ owners = linked_list_create();
while (ids.len > 0)
{
chunk_t id;
@@ -1111,14 +784,15 @@ static bool load_shared(private_stroke_cred_t *this, chunk_t line, int line_nr,
continue;
}
- shared_key->add_owner(shared_key, peer_id);
+ owners->insert_last(owners, peer_id);
any = FALSE;
}
if (any)
{
- shared_key->add_owner(shared_key,
+ owners->insert_last(owners,
identification_create_from_encoding(ID_ANY, chunk_empty));
}
+ this->creds->add_shared_list(this->creds, shared_key, owners);
return TRUE;
}
@@ -1130,8 +804,6 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level,
{
int line_nr = 0, fd;
chunk_t src, line;
- private_key_t *private;
- shared_key_t *shared;
struct stat sb;
void *addr;
@@ -1160,20 +832,8 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level,
src = chunk_create(addr, sb.st_size);
if (level == 0)
- {
- this->lock->write_lock(this->lock);
-
- /* flush secrets on non-recursive invocation */
- while (this->shared->remove_last(this->shared,
- (void**)&shared) == SUCCESS)
- {
- shared->destroy(shared);
- }
- while (this->private->remove_last(this->private,
- (void**)&private) == SUCCESS)
- {
- private->destroy(private);
- }
+ { /* flush secrets on non-recursive invocation */
+ this->creds->clear_secrets(this->creds);
}
while (fetchline(&src, &line))
@@ -1234,7 +894,6 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level,
if (glob(pattern, GLOB_ERR, NULL, &buf) != 0)
{
DBG1(DBG_CFG, "expanding file expression '%s' failed", pattern);
- globfree(&buf);
}
else
{
@@ -1302,10 +961,6 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level,
break;
}
}
- if (level == 0)
- {
- this->lock->unlock(this->lock);
- }
munmap(addr, sb.st_size);
close(fd);
}
@@ -1384,10 +1039,8 @@ static void reread(private_stroke_cred_t *this, stroke_msg_t *msg, FILE *prompt)
*/
static void destroy(private_stroke_cred_t *this)
{
- this->certs->destroy_offset(this->certs, offsetof(certificate_t, destroy));
- this->shared->destroy_offset(this->shared, offsetof(shared_key_t, destroy));
- this->private->destroy_offset(this->private, offsetof(private_key_t, destroy));
- this->lock->destroy(this->lock);
+ lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
+ this->creds->destroy(this->creds);
free(this);
}
@@ -1398,9 +1051,9 @@ stroke_cred_t *stroke_cred_create()
{
private_stroke_cred_t *this = malloc_thing(private_stroke_cred_t);
- this->public.set.create_private_enumerator = (void*)create_private_enumerator;
- this->public.set.create_cert_enumerator = (void*)create_cert_enumerator;
- this->public.set.create_shared_enumerator = (void*)create_shared_enumerator;
+ this->public.set.create_private_enumerator = (void*)return_null;
+ this->public.set.create_cert_enumerator = (void*)return_null;
+ this->public.set.create_shared_enumerator = (void*)return_null;
this->public.set.create_cdp_enumerator = (void*)return_null;
this->public.set.cache_cert = (void*)cache_cert;
this->public.reread = (void(*)(stroke_cred_t*, stroke_msg_t *msg, FILE*))reread;
@@ -1409,10 +1062,8 @@ stroke_cred_t *stroke_cred_create()
this->public.cachecrl = (void(*)(stroke_cred_t*, bool enabled))cachecrl;
this->public.destroy = (void(*)(stroke_cred_t*))destroy;
- this->certs = linked_list_create();
- this->shared = linked_list_create();
- this->private = linked_list_create();
- this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
+ this->creds = mem_cred_create();
+ lib->credmgr->add_set(lib->credmgr, &this->creds->set);
load_certs(this);
load_secrets(this, SECRETS_FILE, 0, NULL);
diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c
index 86deea490..36311f092 100644
--- a/src/libcharon/plugins/stroke/stroke_list.c
+++ b/src/libcharon/plugins/stroke/stroke_list.c
@@ -388,10 +388,8 @@ static void log_auth_cfgs(FILE *out, peer_cfg_t *peer_cfg, bool local)
enumerator->destroy(enumerator);
}
-/**
- * Implementation of stroke_list_t.status.
- */
-static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bool all)
+METHOD(stroke_list_t, status, void,
+ private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bool all)
{
enumerator_t *enumerator, *children;
ike_cfg_t *ike_cfg;
@@ -756,7 +754,7 @@ static void stroke_list_certs(linked_list_t *list, char *label,
enumerator_t *enumerator;
identification_t *altName;
bool first_altName = TRUE;
- int pathlen;
+ u_int pathlen;
chunk_t serial, authkey;
time_t notBefore, notAfter;
public_key_t *public;
@@ -836,10 +834,10 @@ static void stroke_list_certs(linked_list_t *list, char *label,
}
/* list optional pathLenConstraint */
- pathlen = x509->get_pathLenConstraint(x509);
- if (pathlen != X509_NO_PATH_LEN_CONSTRAINT)
+ pathlen = x509->get_constraint(x509, X509_PATH_LEN);
+ if (pathlen != X509_NO_CONSTRAINT)
{
- fprintf(out, " pathlen: %d\n", pathlen);
+ fprintf(out, " pathlen: %u\n", pathlen);
}
/* list optional ipAddrBlocks */
@@ -979,6 +977,10 @@ static void stroke_list_crls(linked_list_t *list, bool utc, FILE *out)
{
fprintf(out, " serial: %#B\n", &chunk);
}
+ if (crl->is_delta_crl(crl, &chunk))
+ {
+ fprintf(out, " delta for: %#B\n", &chunk);
+ }
/* count the number of revoked certificates */
{
@@ -1060,6 +1062,25 @@ static void stroke_list_ocsp(linked_list_t* list, bool utc, FILE *out)
}
/**
+ * Print the name of an algorithm plus the name of the plugin that registered it
+ */
+static void print_alg(FILE *out, int *len, enum_name_t *alg_names, int alg_type,
+ const char *plugin_name)
+{
+ 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;
+ }
+ fprintf(out, "%s", alg_name);
+ *len += alg_name_len;
+}
+
+/**
* List of registered cryptographical algorithms
*/
static void list_algs(FILE *out)
@@ -1070,58 +1091,73 @@ static void list_algs(FILE *out)
hash_algorithm_t hash;
pseudo_random_function_t prf;
diffie_hellman_group_t group;
+ rng_quality_t quality;
+ const char *plugin_name;
+ int len;
fprintf(out, "\n");
fprintf(out, "List of registered IKEv2 Algorithms:\n");
- fprintf(out, "\n encryption: ");
+ fprintf(out, "\n encryption:");
+ len = 13;
enumerator = lib->crypto->create_crypter_enumerator(lib->crypto);
- while (enumerator->enumerate(enumerator, &encryption))
+ while (enumerator->enumerate(enumerator, &encryption, &plugin_name))
{
- fprintf(out, "%N ", encryption_algorithm_names, encryption);
+ print_alg(out, &len, encryption_algorithm_names, encryption, plugin_name);
}
enumerator->destroy(enumerator);
- fprintf(out, "\n integrity: ");
+ fprintf(out, "\n integrity: ");
+ len = 13;
enumerator = lib->crypto->create_signer_enumerator(lib->crypto);
- while (enumerator->enumerate(enumerator, &integrity))
+ while (enumerator->enumerate(enumerator, &integrity, &plugin_name))
{
- fprintf(out, "%N ", integrity_algorithm_names, integrity);
+ print_alg(out, &len, integrity_algorithm_names, integrity, plugin_name);
}
enumerator->destroy(enumerator);
- fprintf(out, "\n aead: ");
+ fprintf(out, "\n aead: ");
+ len = 13;
enumerator = lib->crypto->create_aead_enumerator(lib->crypto);
- while (enumerator->enumerate(enumerator, &encryption))
+ while (enumerator->enumerate(enumerator, &encryption, &plugin_name))
{
- fprintf(out, "%N ", encryption_algorithm_names, encryption);
+ print_alg(out, &len, encryption_algorithm_names, encryption, plugin_name);
}
enumerator->destroy(enumerator);
- fprintf(out, "\n hasher: ");
+ fprintf(out, "\n hasher: ");
+ len = 13;
enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
- while (enumerator->enumerate(enumerator, &hash))
+ while (enumerator->enumerate(enumerator, &hash, &plugin_name))
{
- fprintf(out, "%N ", hash_algorithm_names, hash);
+ print_alg(out, &len, hash_algorithm_names, hash, plugin_name);
}
enumerator->destroy(enumerator);
- fprintf(out, "\n prf: ");
+ fprintf(out, "\n prf: ");
+ len = 13;
enumerator = lib->crypto->create_prf_enumerator(lib->crypto);
- while (enumerator->enumerate(enumerator, &prf))
+ while (enumerator->enumerate(enumerator, &prf, &plugin_name))
{
- fprintf(out, "%N ", pseudo_random_function_names, prf);
+ print_alg(out, &len, pseudo_random_function_names, prf, plugin_name);
}
enumerator->destroy(enumerator);
- fprintf(out, "\n dh-group: ");
+ fprintf(out, "\n dh-group: ");
+ len = 13;
enumerator = lib->crypto->create_dh_enumerator(lib->crypto);
- while (enumerator->enumerate(enumerator, &group))
+ while (enumerator->enumerate(enumerator, &group, &plugin_name))
{
- fprintf(out, "%N ", diffie_hellman_group_names, group);
+ print_alg(out, &len, diffie_hellman_group_names, group, plugin_name);
+ }
+ enumerator->destroy(enumerator);
+ fprintf(out, "\n random-gen:");
+ len = 13;
+ enumerator = lib->crypto->create_rng_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &quality, &plugin_name))
+ {
+ print_alg(out, &len, rng_quality_names, quality, plugin_name);
}
enumerator->destroy(enumerator);
fprintf(out, "\n");
}
-/**
- * Implementation of stroke_list_t.list.
- */
-static void list(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out)
+METHOD(stroke_list_t, list, void,
+ private_stroke_list_t *this, stroke_msg_t *msg, FILE *out)
{
linked_list_t *cert_list = NULL;
@@ -1224,10 +1260,8 @@ static void pool_leases(private_stroke_list_t *this, FILE *out, char *pool,
}
}
-/**
- * Implementation of stroke_list_t.leases
- */
-static void leases(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out)
+METHOD(stroke_list_t, leases, void,
+ private_stroke_list_t *this, stroke_msg_t *msg, FILE *out)
{
enumerator_t *enumerator;
u_int size, offline, online;
@@ -1264,10 +1298,8 @@ static void leases(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out)
DESTROY_IF(address);
}
-/**
- * Implementation of stroke_list_t.destroy
- */
-static void destroy(private_stroke_list_t *this)
+METHOD(stroke_list_t, destroy, void,
+ private_stroke_list_t *this)
{
free(this);
}
@@ -1277,15 +1309,19 @@ static void destroy(private_stroke_list_t *this)
*/
stroke_list_t *stroke_list_create(stroke_attribute_t *attribute)
{
- private_stroke_list_t *this = malloc_thing(private_stroke_list_t);
-
- this->public.list = (void(*)(stroke_list_t*, stroke_msg_t *msg, FILE *out))list;
- this->public.status = (void(*)(stroke_list_t*, stroke_msg_t *msg, FILE *out,bool))status;
- this->public.leases = (void(*)(stroke_list_t*, stroke_msg_t *msg, FILE *out))leases;
- this->public.destroy = (void(*)(stroke_list_t*))destroy;
-
- this->uptime = time_monotonic(NULL);
- this->attribute = attribute;
+ private_stroke_list_t *this;
+
+ INIT(this,
+ .public = {
+
+ .list = _list,
+ .status = _status,
+ .leases = _leases,
+ .destroy = _destroy,
+ },
+ .uptime = time_monotonic(NULL),
+ .attribute = attribute,
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/stroke/stroke_plugin.c b/src/libcharon/plugins/stroke/stroke_plugin.c
index 4361e5050..2e83d0d28 100644
--- a/src/libcharon/plugins/stroke/stroke_plugin.c
+++ b/src/libcharon/plugins/stroke/stroke_plugin.c
@@ -36,10 +36,8 @@ struct private_stroke_plugin_t {
stroke_socket_t *socket;
};
-/**
- * Implementation of stroke_plugin_t.destroy
- */
-static void destroy(private_stroke_plugin_t *this)
+METHOD(plugin_t, destroy, void,
+ private_stroke_plugin_t *this)
{
this->socket->destroy(this->socket);
free(this);
@@ -50,11 +48,17 @@ static void destroy(private_stroke_plugin_t *this)
*/
plugin_t *stroke_plugin_create()
{
- private_stroke_plugin_t *this = malloc_thing(private_stroke_plugin_t);
+ private_stroke_plugin_t *this;
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+ INIT(this,
+ .public = {
+ .plugin = {
+ .destroy = _destroy,
+ },
+ },
+ .socket = stroke_socket_create(),
+ );
- this->socket = stroke_socket_create();
if (this->socket == NULL)
{
free(this);
diff --git a/src/libcharon/plugins/stroke/stroke_shared_key.c b/src/libcharon/plugins/stroke/stroke_shared_key.c
deleted file mode 100644
index 4f716e83a..000000000
--- a/src/libcharon/plugins/stroke/stroke_shared_key.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * 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 "stroke_shared_key.h"
-
-#include <utils/linked_list.h>
-
-typedef struct private_stroke_shared_key_t private_stroke_shared_key_t;
-
-/**
- * private data of shared_key
- */
-struct private_stroke_shared_key_t {
-
- /**
- * implements shared_key_t
- */
- stroke_shared_key_t public;
-
- /**
- * type of this key
- */
- shared_key_type_t type;
-
- /**
- * data of the key
- */
- chunk_t key;
-
- /**
- * list of key owners, as identification_t
- */
- linked_list_t *owners;
-
- /**
- * reference counter
- */
- refcount_t ref;
-};
-
-/**
- * Implementation of shared_key_t.get_type.
- */
-static shared_key_type_t get_type(private_stroke_shared_key_t *this)
-{
- return this->type;
-}
-
-/**
- * Implementation of shared_key_t.get_ref.
- */
-static private_stroke_shared_key_t* get_ref(private_stroke_shared_key_t *this)
-{
- ref_get(&this->ref);
- return this;
-}
-
-/**
- * Implementation of shared_key_t.get_key.
- */
-static chunk_t get_key(private_stroke_shared_key_t *this)
-{
- return this->key;
-}
-
-/**
- * Implementation of stroke_shared_key_t.has_owner.
- */
-static id_match_t has_owner(private_stroke_shared_key_t *this, identification_t *owner)
-{
- enumerator_t *enumerator;
- id_match_t match, best = ID_MATCH_NONE;
- identification_t *current;
-
- enumerator = this->owners->create_enumerator(this->owners);
- while (enumerator->enumerate(enumerator, &current))
- {
- match = owner->matches(owner, current);
- if (match > best)
- {
- best = match;
- }
- }
- enumerator->destroy(enumerator);
- return best;
-}
-/**
- * Implementation of stroke_shared_key_t.add_owner.
- */
-static void add_owner(private_stroke_shared_key_t *this, identification_t *owner)
-{
- this->owners->insert_last(this->owners, owner);
-}
-
-/**
- * Implementation of stroke_shared_key_t.destroy
- */
-static void destroy(private_stroke_shared_key_t *this)
-{
- if (ref_put(&this->ref))
- {
- this->owners->destroy_offset(this->owners, offsetof(identification_t, destroy));
- chunk_free(&this->key);
- free(this);
- }
-}
-
-/**
- * create a shared key
- */
-stroke_shared_key_t *stroke_shared_key_create(shared_key_type_t type, chunk_t key)
-{
- private_stroke_shared_key_t *this = malloc_thing(private_stroke_shared_key_t);
-
- this->public.shared.get_type = (shared_key_type_t(*)(shared_key_t*))get_type;
- this->public.shared.get_key = (chunk_t(*)(shared_key_t*))get_key;
- this->public.shared.get_ref = (shared_key_t*(*)(shared_key_t*))get_ref;
- this->public.shared.destroy = (void(*)(shared_key_t*))destroy;
- this->public.add_owner = (void(*)(stroke_shared_key_t*, identification_t *owner))add_owner;
- this->public.has_owner = (id_match_t(*)(stroke_shared_key_t*, identification_t *owner))has_owner;
-
- this->owners = linked_list_create();
- this->type = type;
- this->key = key;
- this->ref = 1;
-
- return &this->public;
-}
diff --git a/src/libcharon/plugins/stroke/stroke_shared_key.h b/src/libcharon/plugins/stroke/stroke_shared_key.h
deleted file mode 100644
index 05ad55083..000000000
--- a/src/libcharon/plugins/stroke/stroke_shared_key.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * 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 stroke_shared_key stroke_shared_key
- * @{ @ingroup stroke
- */
-
-#ifndef STROKE_SHARED_KEY_H_
-#define STROKE_SHARED_KEY_H_
-
-#include <utils/identification.h>
-#include <credentials/keys/shared_key.h>
-
-typedef struct stroke_shared_key_t stroke_shared_key_t;
-
-/**
- * Shared key implementation for keys read from ipsec.secrets
- */
-struct stroke_shared_key_t {
-
- /**
- * Implements the shared_key_t interface.
- */
- shared_key_t shared;
-
- /**
- * Add an owner to the key.
- *
- * @param owner owner to add
- */
- void (*add_owner)(stroke_shared_key_t *this, identification_t *owner);
-
- /**
- * Check if a key has a specific owner.
- *
- * @param owner owner to check
- * @return best match found
- */
- id_match_t (*has_owner)(stroke_shared_key_t *this, identification_t *owner);
-};
-
-/**
- * Create a stroke_shared_key instance.
- */
-stroke_shared_key_t *stroke_shared_key_create(shared_key_type_t type, chunk_t key);
-
-#endif /** STROKE_SHARED_KEY_H_ @}*/
diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c
index 0a5110fd3..18e77905d 100644
--- a/src/libcharon/plugins/stroke/stroke_socket.c
+++ b/src/libcharon/plugins/stroke/stroke_socket.c
@@ -151,6 +151,7 @@ static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
pop_string(msg, &end->ca);
pop_string(msg, &end->ca2);
pop_string(msg, &end->groups);
+ pop_string(msg, &end->cert_policy);
pop_string(msg, &end->updown);
DBG2(DBG_CFG, " %s=%s", label, end->address);
@@ -246,6 +247,17 @@ static void stroke_terminate_srcip(private_stroke_socket_t *this,
}
/**
+ * rekey a connection by name/id
+ */
+static void stroke_rekey(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
+{
+ pop_string(msg, &msg->terminate.name);
+ DBG1(DBG_CFG, "received stroke: rekey '%s'", msg->rekey.name);
+
+ this->control->rekey(this->control, msg, out);
+}
+
+/**
* route a policy (install SPD entries)
*/
static void stroke_route(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
@@ -348,6 +360,14 @@ static void stroke_purge(private_stroke_socket_t *this,
{
lib->credmgr->flush_cache(lib->credmgr, CERT_X509_OCSP_RESPONSE);
}
+ if (msg->purge.flags & PURGE_CRLS)
+ {
+ lib->credmgr->flush_cache(lib->credmgr, CERT_X509_CRL);
+ }
+ if (msg->purge.flags & PURGE_CERTS)
+ {
+ lib->credmgr->flush_cache(lib->credmgr, CERT_X509);
+ }
if (msg->purge.flags & PURGE_IKE)
{
this->control->purge_ike(this->control, msg, out);
@@ -510,6 +530,9 @@ static job_requeue_t process(stroke_job_context_t *ctx)
case STR_TERMINATE_SRCIP:
stroke_terminate_srcip(this, msg, out);
break;
+ case STR_REKEY:
+ stroke_rekey(this, msg, out);
+ break;
case STR_STATUS:
stroke_status(this, msg, out, FALSE);
break;
diff --git a/src/libcharon/plugins/tnc_imc/Makefile.am b/src/libcharon/plugins/tnc_imc/Makefile.am
index ca8869460..2c551813e 100644
--- a/src/libcharon/plugins/tnc_imc/Makefile.am
+++ b/src/libcharon/plugins/tnc_imc/Makefile.am
@@ -1,11 +1,9 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon `xml2-config --cflags`
+ -I$(top_srcdir)/src/libcharon
AM_CFLAGS = -rdynamic
-libstrongswan_tnc_imc_la_LIBADD = -ltnc
-
if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-tnc-imc.la
else
@@ -13,7 +11,8 @@ plugin_LTLIBRARIES = libstrongswan-tnc-imc.la
endif
libstrongswan_tnc_imc_la_SOURCES = \
- tnc_imc_plugin.h tnc_imc_plugin.c
+ tnc_imc_plugin.h tnc_imc_plugin.c tnc_imc.h tnc_imc.c \
+ tnc_imc_manager.h tnc_imc_manager.c tnc_imc_bind_function.c
libstrongswan_tnc_imc_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/tnc_imc/Makefile.in b/src/libcharon/plugins/tnc_imc/Makefile.in
index 9a8794e93..dc44408ff 100644
--- a/src/libcharon/plugins/tnc_imc/Makefile.in
+++ b/src/libcharon/plugins/tnc_imc/Makefile.in
@@ -74,8 +74,9 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_tnc_imc_la_DEPENDENCIES =
-am_libstrongswan_tnc_imc_la_OBJECTS = tnc_imc_plugin.lo
+libstrongswan_tnc_imc_la_LIBADD =
+am_libstrongswan_tnc_imc_la_OBJECTS = tnc_imc_plugin.lo tnc_imc.lo \
+ tnc_imc_manager.lo tnc_imc_bind_function.lo
libstrongswan_tnc_imc_la_OBJECTS = \
$(am_libstrongswan_tnc_imc_la_OBJECTS)
libstrongswan_tnc_imc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -221,9 +222,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -262,6 +261,8 @@ 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@
@@ -273,14 +274,14 @@ 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 `xml2-config --cflags`
+ -I$(top_srcdir)/src/libcharon
AM_CFLAGS = -rdynamic
-libstrongswan_tnc_imc_la_LIBADD = -ltnc
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-imc.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-imc.la
libstrongswan_tnc_imc_la_SOURCES = \
- tnc_imc_plugin.h tnc_imc_plugin.c
+ tnc_imc_plugin.h tnc_imc_plugin.c tnc_imc.h tnc_imc.c \
+ tnc_imc_manager.h tnc_imc_manager.c tnc_imc_bind_function.c
libstrongswan_tnc_imc_la_LDFLAGS = -module -avoid-version
all: all-am
@@ -366,6 +367,9 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_imc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_imc_bind_function.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_imc_manager.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_imc_plugin.Plo@am__quote@
.c.o:
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc.c b/src/libcharon/plugins/tnc_imc/tnc_imc.c
new file mode 100644
index 000000000..174084436
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2006 Mike McCauley
+ * 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 "tnc_imc.h"
+
+#include <dlfcn.h>
+
+#include <debug.h>
+#include <library.h>
+
+typedef struct private_tnc_imc_t private_tnc_imc_t;
+
+/**
+ * Private data of an imv_t object.
+ */
+struct private_tnc_imc_t {
+
+ /**
+ * Public members of imc_t.
+ */
+ imc_t public;
+
+ /**
+ * Path of loaded IMC
+ */
+ char *path;
+
+ /**
+ * Name of loaded IMC
+ */
+ char *name;
+
+ /**
+ * Handle of loaded IMC
+ */
+ void *handle;
+
+ /**
+ * ID of loaded IMC
+ */
+ TNC_IMCID id;
+
+ /**
+ * List of message types supported by IMC
+ */
+ TNC_MessageTypeList supported_types;
+
+ /**
+ * Number of supported message types
+ */
+ TNC_UInt32 type_count;
+};
+
+METHOD(imc_t, set_id, void,
+ private_tnc_imc_t *this, TNC_IMCID id)
+{
+ this->id = id;
+}
+
+METHOD(imc_t, get_id, TNC_IMCID,
+ private_tnc_imc_t *this)
+{
+ return this->id;
+}
+
+METHOD(imc_t, get_name, char*,
+ private_tnc_imc_t *this)
+{
+ return this->name;
+}
+
+METHOD(imc_t, set_message_types, void,
+ private_tnc_imc_t *this, TNC_MessageTypeList supported_types,
+ TNC_UInt32 type_count)
+{
+ /* Free an existing MessageType list */
+ free(this->supported_types);
+ this->supported_types = NULL;
+
+ /* Store the new MessageType list */
+ this->type_count = type_count;
+ if (type_count && supported_types)
+ {
+ size_t size = type_count * sizeof(TNC_MessageType);
+
+ 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);
+}
+
+METHOD(imc_t, type_supported, bool,
+ private_tnc_imc_t *this, TNC_MessageType message_type)
+{
+ TNC_VendorID msg_vid, vid;
+ TNC_MessageSubtype msg_subtype, subtype;
+ int i;
+
+ msg_vid = (message_type >> 8) & TNC_VENDORID_ANY;
+ msg_subtype = message_type & TNC_SUBTYPE_ANY;
+
+ for (i = 0; i < this->type_count; i++)
+ {
+ vid = (this->supported_types[i] >> 8) & TNC_VENDORID_ANY;
+ subtype = this->supported_types[i] & TNC_SUBTYPE_ANY;
+
+ if (this->supported_types[i] == message_type
+ || (subtype == TNC_SUBTYPE_ANY
+ && (msg_vid == vid || vid == TNC_VENDORID_ANY))
+ || (vid == TNC_VENDORID_ANY
+ && (msg_subtype == subtype || subtype == TNC_SUBTYPE_ANY)))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+METHOD(imc_t, destroy, void,
+ private_tnc_imc_t *this)
+{
+ dlclose(this->handle);
+ free(this->supported_types);
+ free(this->name);
+ free(this->path);
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+imc_t* tnc_imc_create(char *name, char *path)
+{
+ private_tnc_imc_t *this;
+
+ INIT(this,
+ .public = {
+ .set_id = _set_id,
+ .get_id = _get_id,
+ .get_name = _get_name,
+ .set_message_types = _set_message_types,
+ .type_supported = _type_supported,
+ .destroy = _destroy,
+ },
+ .name = name,
+ .path = path,
+ );
+
+ this->handle = dlopen(path, RTLD_LAZY);
+ if (!this->handle)
+ {
+ DBG1(DBG_TNC, "IMC \"%s\" failed to load: %s", name, dlerror());
+ free(this);
+ return NULL;
+ }
+
+ this->public.initialize = dlsym(this->handle, "TNC_IMC_Initialize");
+ if (!this->public.initialize)
+ {
+ DBG1(DBG_TNC, "could not resolve TNC_IMC_Initialize in %s: %s\n",
+ path, dlerror());
+ dlclose(this->handle);
+ free(this);
+ return NULL;
+ }
+ this->public.notify_connection_change =
+ dlsym(this->handle, "TNC_IMC_NotifyConnectionChange");
+ this->public.begin_handshake = dlsym(this->handle, "TNC_IMC_BeginHandshake");
+ if (!this->public.begin_handshake)
+ {
+ DBG1(DBG_TNC, "could not resolve TNC_IMC_BeginHandshake in %s: %s\n",
+ path, dlerror());
+ dlclose(this->handle);
+ free(this);
+ return NULL;
+ }
+ this->public.receive_message =
+ dlsym(this->handle, "TNC_IMC_ReceiveMessage");
+ this->public.batch_ending =
+ dlsym(this->handle, "TNC_IMC_BatchEnding");
+ this->public.terminate =
+ dlsym(this->handle, "TNC_IMC_Terminate");
+ this->public.provide_bind_function =
+ dlsym(this->handle, "TNC_IMC_ProvideBindFunction");
+ if (!this->public.provide_bind_function)
+ {
+ DBG1(DBG_TNC, "could not resolve TNC_IMC_ProvideBindFunction in %s: %s\n",
+ path, dlerror());
+ dlclose(this->handle);
+ free(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc.h b/src/libcharon/plugins/tnc_imc/tnc_imc.h
new file mode 100644
index 000000000..10a67f90b
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ *
+ * @defgroup tnc_imc_t tnc_imc
+ * @{ @ingroup tnc_imc
+ */
+
+#ifndef TNC_IMC_H_
+#define TNC_IMC_H_
+
+#include <tnc/imc/imc.h>
+
+/**
+ * Create an Integrity Measurement Collector.
+ *
+ * @param name name of the IMC
+ * @param filename path to the dynamic IMC library
+ * @return instance of the imc_t interface
+ */
+imc_t* tnc_imc_create(char *name, char *filename);
+
+#endif /** TNC_IMC_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c b/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c
new file mode 100644
index 000000000..e18f1b006
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2006 Mike McCauley
+ * 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 "tnc_imc.h"
+
+#include <debug.h>
+#include <daemon.h>
+
+#define TNC_IMVID_ANY 0xffff
+
+/**
+ * Called by the IMC to inform a TNCC about the set of message types the IMC
+ * is able to receive
+ */
+TNC_Result TNC_TNCC_ReportMessageTypes(TNC_IMCID imc_id,
+ TNC_MessageTypeList supported_types,
+ TNC_UInt32 type_count)
+{
+ return charon->imcs->set_message_types(charon->imcs, imc_id,
+ supported_types, type_count);
+}
+
+/**
+ * Called by the IMC to ask a TNCC to retry an Integrity Check Handshake
+ */
+TNC_Result TNC_TNCC_RequestHandshakeRetry(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_RetryReason reason)
+{
+ return charon->tnccs->request_handshake_retry(charon->tnccs, TRUE, imc_id,
+ connection_id, reason);
+}
+
+/**
+ * Called by the IMC when an IMC-IMV message is to be sent
+ */
+TNC_Result TNC_TNCC_SendMessage(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_MessageType msg_type)
+{
+ return charon->tnccs->send_message(charon->tnccs, imc_id, TNC_IMVID_ANY,
+ connection_id, msg, msg_len, msg_type);
+}
+
+/**
+ * Called by the IMC when it needs a function pointer
+ */
+TNC_Result TNC_TNCC_BindFunction(TNC_IMCID id,
+ char *function_name,
+ void **function_pointer)
+{
+ if (streq(function_name, "TNC_TNCC_ReportMessageTypes"))
+ {
+ *function_pointer = (void*)TNC_TNCC_ReportMessageTypes;
+ }
+ else if (streq(function_name, "TNC_TNCC_RequestHandshakeRetry"))
+ {
+ *function_pointer = (void*)TNC_TNCC_RequestHandshakeRetry;
+ }
+ else if (streq(function_name, "TNC_TNCC_SendMessage"))
+ {
+ *function_pointer = (void*)TNC_TNCC_SendMessage;
+ }
+ else
+ {
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ return TNC_RESULT_SUCCESS;
+}
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c b/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
new file mode 100644
index 000000000..aa20534f5
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2006 Mike McCauley
+ * 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 "tnc_imc_manager.h"
+
+#include <tnc/imc/imc_manager.h>
+#include <tnc/tncifimc.h>
+
+#include <debug.h>
+#include <library.h>
+#include <utils/linked_list.h>
+
+typedef struct private_tnc_imc_manager_t private_tnc_imc_manager_t;
+
+/**
+ * Private data of an imc_manager_t object.
+ */
+struct private_tnc_imc_manager_t {
+
+ /**
+ * Public members of imc_manager_t.
+ */
+ imc_manager_t public;
+
+ /**
+ * Linked list of IMCs
+ */
+ linked_list_t *imcs;
+
+ /**
+ * Next IMC ID to be assigned
+ */
+ TNC_IMCID next_imc_id;
+};
+
+METHOD(imc_manager_t, add, bool,
+ private_tnc_imc_manager_t *this, imc_t *imc)
+{
+ TNC_Version version;
+
+ /* Initialize the module */
+ imc->set_id(imc, this->next_imc_id);
+ if (imc->initialize(imc->get_id(imc), TNC_IFIMC_VERSION_1,
+ TNC_IFIMC_VERSION_1, &version) != TNC_RESULT_SUCCESS)
+ {
+ DBG1(DBG_TNC, "IMC \"%s\" failed to initialize", imc->get_name(imc));
+ return FALSE;
+ }
+ this->imcs->insert_last(this->imcs, imc);
+ this->next_imc_id++;
+
+ if (imc->provide_bind_function(imc->get_id(imc), TNC_TNCC_BindFunction)
+ != TNC_RESULT_SUCCESS)
+ {
+ DBG1(DBG_TNC, "IMC \"%s\" failed to obtain bind function",
+ imc->get_name(imc));
+ this->imcs->remove_last(this->imcs, (void**)&imc);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+METHOD(imc_manager_t, remove_, imc_t*,
+ private_tnc_imc_manager_t *this, TNC_IMCID id)
+{
+ enumerator_t *enumerator;
+ imc_t *imc;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc))
+ {
+ if (id == imc->get_id(imc))
+ {
+ this->imcs->remove_at(this->imcs, enumerator);
+ return imc;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return NULL;
+}
+
+METHOD(imc_manager_t, get_preferred_language, char*,
+ private_tnc_imc_manager_t *this)
+{
+ return lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-imc.preferred_language", "en");
+}
+
+METHOD(imc_manager_t, notify_connection_change, void,
+ private_tnc_imc_manager_t *this, TNC_ConnectionID id,
+ TNC_ConnectionState state)
+{
+ enumerator_t *enumerator;
+ imc_t *imc;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc))
+ {
+ if (imc->notify_connection_change)
+ {
+ imc->notify_connection_change(imc->get_id(imc), id, state);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(imc_manager_t, begin_handshake, void,
+ private_tnc_imc_manager_t *this, TNC_ConnectionID id)
+{
+ enumerator_t *enumerator;
+ imc_t *imc;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc))
+ {
+ imc->begin_handshake(imc->get_id(imc), id);
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(imc_manager_t, set_message_types, TNC_Result,
+ private_tnc_imc_manager_t *this, TNC_IMCID id,
+ TNC_MessageTypeList supported_types,
+ TNC_UInt32 type_count)
+{
+ enumerator_t *enumerator;
+ imc_t *imc;
+ TNC_Result result = TNC_RESULT_FATAL;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc))
+ {
+ if (id == imc->get_id(imc))
+ {
+ imc->set_message_types(imc, supported_types, type_count);
+ result = TNC_RESULT_SUCCESS;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return result;
+}
+
+METHOD(imc_manager_t, receive_message, void,
+ private_tnc_imc_manager_t *this, TNC_ConnectionID connection_id,
+ TNC_BufferReference message,
+ TNC_UInt32 message_len,
+ TNC_MessageType message_type)
+{
+ enumerator_t *enumerator;
+ imc_t *imc;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc))
+ {
+ if (imc->receive_message && imc->type_supported(imc, message_type))
+ {
+ imc->receive_message(imc->get_id(imc), connection_id,
+ message, message_len, message_type);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(imc_manager_t, batch_ending, void,
+ private_tnc_imc_manager_t *this, TNC_ConnectionID id)
+{
+ enumerator_t *enumerator;
+ imc_t *imc;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc))
+ {
+ if (imc->batch_ending)
+ {
+ imc->batch_ending(imc->get_id(imc), id);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(imc_manager_t, destroy, void,
+ private_tnc_imc_manager_t *this)
+{
+ imc_t *imc;
+
+ while (this->imcs->remove_last(this->imcs, (void**)&imc) == SUCCESS)
+ {
+ 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);
+ }
+ this->imcs->destroy(this->imcs);
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+imc_manager_t* tnc_imc_manager_create(void)
+{
+ private_tnc_imc_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .add = _add,
+ .remove = _remove_, /* avoid name conflict with stdio.h */
+ .get_preferred_language = _get_preferred_language,
+ .notify_connection_change = _notify_connection_change,
+ .begin_handshake = _begin_handshake,
+ .set_message_types = _set_message_types,
+ .receive_message = _receive_message,
+ .batch_ending = _batch_ending,
+ .destroy = _destroy,
+ },
+ .imcs = linked_list_create(),
+ .next_imc_id = 1,
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_manager.h b/src/libcharon/plugins/tnc_imc/tnc_imc_manager.h
new file mode 100644
index 000000000..ed490293b
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc_manager.h
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+/**
+ *
+ * @defgroup tnc_imc_manager tnc_imc_manager
+ * @{ @ingroup tnc_imc
+ */
+
+#ifndef TNC_IMC_MANAGER_H_
+#define TNC_IMC_MANAGER_H_
+
+#include <tnc/imc/imc_manager.h>
+
+/**
+ * Create an IMC manager instance.
+ */
+imc_manager_t *tnc_imc_manager_create();
+
+#endif /** TNC_IMC_MANAGER_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c
index 0ce930ba3..89888040a 100644
--- a/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c
@@ -14,15 +14,137 @@
*/
#include "tnc_imc_plugin.h"
+#include "tnc_imc_manager.h"
+#include "tnc_imc.h"
-#include <libtnctncc.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
#include <daemon.h>
+#include <utils/lexparser.h>
+
+/**
+ * load IMCs from a configuration file
+ */
+static bool load_imcs(char *filename)
+{
+ int fd, line_nr = 0;
+ chunk_t src, line;
+ struct stat sb;
+ void *addr;
+
+ DBG1(DBG_TNC, "loading IMCs from '%s'", filename);
+ fd = open(filename, O_RDONLY);
+ if (fd == -1)
+ {
+ DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename,
+ strerror(errno));
+ return FALSE;
+ }
+ if (fstat(fd, &sb) == -1)
+ {
+ DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename,
+ strerror(errno));
+ close(fd);
+ return FALSE;
+ }
+ addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ if (addr == MAP_FAILED)
+ {
+ DBG1(DBG_LIB, "mapping '%s' failed: %s", filename, strerror(errno));
+ close(fd);
+ return FALSE;
+ }
+ src = chunk_create(addr, sb.st_size);
+
+ while (fetchline(&src, &line))
+ {
+ char *name, *path;
+ chunk_t token;
+ imc_t *imc;
+
+ line_nr++;
+
+ /* skip comments or empty lines */
+ if (*line.ptr == '#' || !eat_whitespace(&line))
+ {
+ continue;
+ }
+
+ /* determine keyword */
+ if (!extract_token(&token, ' ', &line))
+ {
+ DBG1(DBG_TNC, "line %d: keyword must be followed by a space",
+ line_nr);
+ return FALSE;
+ }
+
+ /* only interested in IMCs */
+ if (!match("IMC", &token))
+ {
+ continue;
+ }
+
+ /* advance to the IMC name and extract it */
+ if (!extract_token(&token, '"', &line) ||
+ !extract_token(&token, '"', &line))
+ {
+ DBG1(DBG_TNC, "line %d: IMC name must be set in double quotes",
+ line_nr);
+ return FALSE;
+ }
+
+ /* copy the IMC name */
+ name = malloc(token.len + 1);
+ memcpy(name, token.ptr, token.len);
+ name[token.len] = '\0';
+
+ /* advance to the IMC path and extract it */
+ if (!eat_whitespace(&line))
+ {
+ DBG1(DBG_TNC, "line %d: IMC path is missing", line_nr);
+ free(name);
+ return FALSE;
+ }
+ if (!extract_token(&token, ' ', &line))
+ {
+ token = line;
+ }
+
+ /* copy the IMC path */
+ path = malloc(token.len + 1);
+ memcpy(path, token.ptr, token.len);
+ path[token.len] = '\0';
+
+ /* load and register IMC instance */
+ imc = tnc_imc_create(name, path);
+ if (!imc)
+ {
+ free(name);
+ free(path);
+ return FALSE;
+ }
+ if (!charon->imcs->add(charon->imcs, imc))
+ {
+ imc->destroy(imc);
+ return FALSE;
+ }
+ DBG1(DBG_TNC, "IMC %u \"%s\" loaded from '%s'", imc->get_id(imc),
+ name, path);
+ }
+ munmap(addr, sb.st_size);
+ close(fd);
+ return TRUE;
+}
METHOD(plugin_t, destroy, void,
tnc_imc_plugin_t *this)
{
- libtnc_tncc_Terminate();
+ charon->imcs->destroy(charon->imcs);
free(this);
}
@@ -31,7 +153,7 @@ METHOD(plugin_t, destroy, void,
*/
plugin_t *tnc_imc_plugin_create()
{
- char *tnc_config, *pref_lang;
+ char *tnc_config;
tnc_imc_plugin_t *this;
INIT(this,
@@ -40,18 +162,19 @@ plugin_t *tnc_imc_plugin_create()
},
);
- pref_lang = lib->settings->get_str(lib->settings,
- "charon.plugins.tnc-imc.preferred_language", "en");
+ /* Create IMC manager */
+ charon->imcs = tnc_imc_manager_create();
+
+ /* Load IMCs and abort if not all instances initalize successfully */
tnc_config = lib->settings->get_str(lib->settings,
"charon.plugins.tnc-imc.tnc_config", "/etc/tnc_config");
-
- if (libtnc_tncc_Initialize(tnc_config) != TNC_RESULT_SUCCESS)
+ if (!load_imcs(tnc_config))
{
+ charon->imcs->destroy(charon->imcs);
+ charon->imcs = NULL;
free(this);
- DBG1(DBG_TNC, "TNC IMC initialization failed");
return NULL;
}
-
return &this->plugin;
}
diff --git a/src/libcharon/plugins/tnc_imv/Makefile.am b/src/libcharon/plugins/tnc_imv/Makefile.am
index 9c3b47364..3ba283bb7 100644
--- a/src/libcharon/plugins/tnc_imv/Makefile.am
+++ b/src/libcharon/plugins/tnc_imv/Makefile.am
@@ -1,11 +1,9 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon `xml2-config --cflags`
+ -I$(top_srcdir)/src/libcharon
AM_CFLAGS = -rdynamic
-libstrongswan_tnc_imv_la_LIBADD = -ltnc
-
if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-tnc-imv.la
else
@@ -13,7 +11,9 @@ plugin_LTLIBRARIES = libstrongswan-tnc-imv.la
endif
libstrongswan_tnc_imv_la_SOURCES = \
- tnc_imv_plugin.h tnc_imv_plugin.c
+ tnc_imv_plugin.h tnc_imv_plugin.c tnc_imv.h tnc_imv.c \
+ tnc_imv_manager.h tnc_imv_manager.c tnc_imv_bind_function.c \
+ tnc_imv_recommendations.h tnc_imv_recommendations.c
libstrongswan_tnc_imv_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/tnc_imv/Makefile.in b/src/libcharon/plugins/tnc_imv/Makefile.in
index f89b5e03b..0324d2eb9 100644
--- a/src/libcharon/plugins/tnc_imv/Makefile.in
+++ b/src/libcharon/plugins/tnc_imv/Makefile.in
@@ -74,8 +74,10 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_tnc_imv_la_DEPENDENCIES =
-am_libstrongswan_tnc_imv_la_OBJECTS = tnc_imv_plugin.lo
+libstrongswan_tnc_imv_la_LIBADD =
+am_libstrongswan_tnc_imv_la_OBJECTS = tnc_imv_plugin.lo tnc_imv.lo \
+ tnc_imv_manager.lo tnc_imv_bind_function.lo \
+ tnc_imv_recommendations.lo
libstrongswan_tnc_imv_la_OBJECTS = \
$(am_libstrongswan_tnc_imv_la_OBJECTS)
libstrongswan_tnc_imv_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -221,9 +223,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -262,6 +262,8 @@ 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@
@@ -273,14 +275,15 @@ 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 `xml2-config --cflags`
+ -I$(top_srcdir)/src/libcharon
AM_CFLAGS = -rdynamic
-libstrongswan_tnc_imv_la_LIBADD = -ltnc
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-imv.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-imv.la
libstrongswan_tnc_imv_la_SOURCES = \
- tnc_imv_plugin.h tnc_imv_plugin.c
+ tnc_imv_plugin.h tnc_imv_plugin.c tnc_imv.h tnc_imv.c \
+ tnc_imv_manager.h tnc_imv_manager.c tnc_imv_bind_function.c \
+ tnc_imv_recommendations.h tnc_imv_recommendations.c
libstrongswan_tnc_imv_la_LDFLAGS = -module -avoid-version
all: all-am
@@ -366,7 +369,11 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_imv.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_imv_bind_function.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_imv_manager.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_imv_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_imv_recommendations.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv.c b/src/libcharon/plugins/tnc_imv/tnc_imv.c
new file mode 100644
index 000000000..f88b645d6
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2006 Mike McCauley
+ * 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 "tnc_imv.h"
+
+#include <dlfcn.h>
+
+#include <debug.h>
+#include <library.h>
+
+typedef struct private_tnc_imv_t private_tnc_imv_t;
+
+/**
+ * Private data of an imv_t object.
+ */
+struct private_tnc_imv_t {
+
+ /**
+ * Public members of imv_t.
+ */
+ imv_t public;
+
+ /**
+ * Path of loaded IMV
+ */
+ char *path;
+
+ /**
+ * Name of loaded IMV
+ */
+ char *name;
+
+ /**
+ * Handle of loaded IMV
+ */
+ void *handle;
+
+ /**
+ * ID of loaded IMV
+ */
+ TNC_IMVID id;
+
+ /**
+ * List of message types supported by IMC
+ */
+ TNC_MessageTypeList supported_types;
+
+ /**
+ * Number of supported message types
+ */
+ TNC_UInt32 type_count;
+};
+
+METHOD(imv_t, set_id, void,
+ private_tnc_imv_t *this, TNC_IMVID id)
+{
+ this->id = id;
+}
+
+METHOD(imv_t, get_id, TNC_IMVID,
+ private_tnc_imv_t *this)
+{
+ return this->id;
+}
+
+METHOD(imv_t, get_name, char*,
+ private_tnc_imv_t *this)
+{
+ return this->name;
+}
+
+METHOD(imv_t, set_message_types, void,
+ private_tnc_imv_t *this, TNC_MessageTypeList supported_types,
+ TNC_UInt32 type_count)
+{
+ /* Free an existing MessageType list */
+ free(this->supported_types);
+ this->supported_types = NULL;
+
+ /* Store the new MessageType list */
+ this->type_count = type_count;
+ if (type_count && supported_types)
+ {
+ size_t size = type_count * sizeof(TNC_MessageType);
+
+ 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);
+}
+
+METHOD(imv_t, type_supported, bool,
+ private_tnc_imv_t *this, TNC_MessageType message_type)
+{
+ TNC_VendorID msg_vid, vid;
+ TNC_MessageSubtype msg_subtype, subtype;
+ int i;
+
+ msg_vid = (message_type >> 8) & TNC_VENDORID_ANY;
+ msg_subtype = message_type & TNC_SUBTYPE_ANY;
+
+ for (i = 0; i < this->type_count; i++)
+ {
+ vid = (this->supported_types[i] >> 8) & TNC_VENDORID_ANY;
+ subtype = this->supported_types[i] & TNC_SUBTYPE_ANY;
+
+ if (this->supported_types[i] == message_type
+ || (subtype == TNC_SUBTYPE_ANY
+ && (msg_vid == vid || vid == TNC_VENDORID_ANY))
+ || (vid == TNC_VENDORID_ANY
+ && (msg_subtype == subtype || subtype == TNC_SUBTYPE_ANY)))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+METHOD(imv_t, destroy, void,
+ private_tnc_imv_t *this)
+{
+ dlclose(this->handle);
+ free(this->supported_types);
+ free(this->name);
+ free(this->path);
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+imv_t* tnc_imv_create(char *name, char *path)
+{
+ private_tnc_imv_t *this;
+
+ INIT(this,
+ .public = {
+ .set_id = _set_id,
+ .get_id = _get_id,
+ .get_name = _get_name,
+ .set_message_types = _set_message_types,
+ .type_supported = _type_supported,
+ .destroy = _destroy,
+ },
+ .name = name,
+ .path = path,
+ );
+
+ this->handle = dlopen(path, RTLD_LAZY);
+ if (!this->handle)
+ {
+ DBG1(DBG_TNC, "IMV \"%s\" failed to load: %s", name, dlerror());
+ free(this);
+ return NULL;
+ }
+
+ this->public.initialize = dlsym(this->handle, "TNC_IMV_Initialize");
+ if (!this->public.initialize)
+ {
+ DBG1(DBG_TNC, "could not resolve TNC_IMV_Initialize in %s: %s\n",
+ path, dlerror());
+ dlclose(this->handle);
+ free(this);
+ return NULL;
+ }
+ this->public.notify_connection_change =
+ dlsym(this->handle, "TNC_IMV_NotifyConnectionChange");
+ this->public.solicit_recommendation =
+ dlsym(this->handle, "TNC_IMV_SolicitRecommendation");
+ if (!this->public.solicit_recommendation)
+ {
+ DBG1(DBG_TNC, "could not resolve TNC_IMV_SolicitRecommendation in %s: %s\n",
+ path, dlerror());
+ dlclose(this->handle);
+ free(this);
+ return NULL;
+ }
+ this->public.receive_message =
+ dlsym(this->handle, "TNC_IMV_ReceiveMessage");
+ this->public.batch_ending =
+ dlsym(this->handle, "TNC_IMV_BatchEnding");
+ this->public.terminate =
+ dlsym(this->handle, "TNC_IMV_Terminate");
+ this->public.provide_bind_function =
+ dlsym(this->handle, "TNC_IMV_ProvideBindFunction");
+ if (!this->public.provide_bind_function)
+ {
+ DBG1(DBG_TNC, "could not resolve TNC_IMV_ProvideBindFunction in %s: %s\n",
+ path, dlerror());
+ dlclose(this->handle);
+ free(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv.h b/src/libcharon/plugins/tnc_imv/tnc_imv.h
new file mode 100644
index 000000000..75939e54c
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ *
+ * @defgroup tnc_imv_t tnc_imv
+ * @{ @ingroup tnc_imv
+ */
+
+#ifndef TNC_IMV_H_
+#define TNC_IMV_H_
+
+#include <tnc/imv/imv.h>
+
+/**
+ * Create an Integrity Measurement Verifier.
+ *
+ * @param name name of the IMV
+ * @param filename path to the dynamic IMV library
+ * @return instance of the imv_t interface
+ */
+imv_t* tnc_imv_create(char *name, char *filename);
+
+#endif /** TNC_IMV_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c b/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c
new file mode 100644
index 000000000..0ea52f08e
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2006 Mike McCauley
+ * 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 "tnc_imv.h"
+
+#include <debug.h>
+#include <daemon.h>
+
+#define TNC_IMCID_ANY 0xffff
+
+/**
+ * Called by the IMV to inform a TNCS about the set of message types the IMV
+ * is able to receive
+ */
+TNC_Result TNC_TNCS_ReportMessageTypes(TNC_IMVID imv_id,
+ TNC_MessageTypeList supported_types,
+ TNC_UInt32 type_count)
+{
+ return charon->imvs->set_message_types(charon->imvs, imv_id,
+ supported_types, type_count);
+}
+
+/**
+ * Called by the IMV to ask a TNCS to retry an Integrity Check Handshake
+ */
+TNC_Result TNC_TNCS_RequestHandshakeRetry(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_RetryReason reason)
+{
+ return charon->tnccs->request_handshake_retry(charon->tnccs, FALSE, imv_id,
+ connection_id, reason);
+}
+
+/**
+ * Called by the IMV when an IMV-IMC message is to be sent
+ */
+TNC_Result TNC_TNCS_SendMessage(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_MessageType msg_type)
+{
+ return charon->tnccs->send_message(charon->tnccs, TNC_IMCID_ANY, imv_id,
+ connection_id, msg, msg_len, msg_type);
+}
+
+/**
+ * Called by the IMV to deliver its IMV Action Recommendation and IMV Evaluation
+ * Result to the TNCS
+ */
+TNC_Result TNC_TNCS_ProvideRecommendation(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_IMV_Action_Recommendation recommendation,
+ TNC_IMV_Evaluation_Result evaluation)
+{
+ return charon->tnccs->provide_recommendation(charon->tnccs, imv_id,
+ connection_id, recommendation, evaluation);
+}
+
+/**
+ * Called by the IMV to get the value of an attribute associated with a
+ * connection or with the TNCS as a whole.
+ */
+TNC_Result TNC_TNCS_GetAttribute(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_AttributeID attribute_id,
+ TNC_UInt32 buffer_len,
+ TNC_BufferReference buffer,
+ TNC_UInt32 *out_value_len)
+{
+ return charon->tnccs->get_attribute(charon->tnccs, imv_id, connection_id,
+ attribute_id, buffer_len, buffer, out_value_len);
+}
+
+/**
+ * Called by the IMV to set the value of an attribute associated with a
+ * connection or with the TNCS as a whole.
+ */
+TNC_Result TNC_TNCS_SetAttribute(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_AttributeID attribute_id,
+ TNC_UInt32 buffer_len,
+ TNC_BufferReference buffer)
+{
+ return charon->tnccs->set_attribute(charon->tnccs, imv_id, connection_id,
+ attribute_id, buffer_len, buffer);
+}
+
+/**
+ * Called by the IMV when it needs a function pointer
+ */
+TNC_Result TNC_TNCS_BindFunction(TNC_IMVID id,
+ char *function_name,
+ void **function_pointer)
+{
+ if (streq(function_name, "TNC_TNCS_ReportMessageTypes"))
+ {
+ *function_pointer = (void*)TNC_TNCS_ReportMessageTypes;
+ }
+ else if (streq(function_name, "TNC_TNCS_RequestHandshakeRetry"))
+ {
+ *function_pointer = (void*)TNC_TNCS_RequestHandshakeRetry;
+ }
+ else if (streq(function_name, "TNC_TNCS_SendMessage"))
+ {
+ *function_pointer = (void*)TNC_TNCS_SendMessage;
+ }
+ else if (streq(function_name, "TNC_TNCS_ProvideRecommendation"))
+ {
+ *function_pointer = (void*)TNC_TNCS_ProvideRecommendation;
+ }
+ else if (streq(function_name, "TNC_TNCS_GetAttribute"))
+ {
+ *function_pointer = (void*)TNC_TNCS_GetAttribute;
+ }
+ else if (streq(function_name, "TNC_TNCS_SetAttribute"))
+ {
+ *function_pointer = (void*)TNC_TNCS_SetAttribute;
+ }
+ else
+ {
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ return TNC_RESULT_SUCCESS;
+}
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
new file mode 100644
index 000000000..559de86d0
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2006 Mike McCauley
+ * 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 "tnc_imv_manager.h"
+#include "tnc_imv_recommendations.h"
+
+#include <tnc/imv/imv_manager.h>
+#include <tnc/tncifimv.h>
+
+#include <debug.h>
+#include <daemon.h>
+#include <threading/mutex.h>
+
+typedef struct private_tnc_imv_manager_t private_tnc_imv_manager_t;
+
+
+/**
+ * Private data of an imv_manager_t object.
+ */
+struct private_tnc_imv_manager_t {
+
+ /**
+ * Public members of imv_manager_t.
+ */
+ imv_manager_t public;
+
+ /**
+ * Linked list of IMVs
+ */
+ linked_list_t *imvs;
+
+ /**
+ * Next IMV ID to be assigned
+ */
+ TNC_IMVID next_imv_id;
+
+ /**
+ * Policy defining how to derive final recommendation from individual ones
+ */
+ recommendation_policy_t policy;
+};
+
+METHOD(imv_manager_t, add, bool,
+ private_tnc_imv_manager_t *this, imv_t *imv)
+{
+ TNC_Version version;
+
+ /* Initialize the IMV module */
+ imv->set_id(imv, this->next_imv_id);
+ if (imv->initialize(imv->get_id(imv), TNC_IFIMV_VERSION_1,
+ TNC_IFIMV_VERSION_1, &version) != TNC_RESULT_SUCCESS)
+ {
+ DBG1(DBG_TNC, "IMV \"%s\" failed to initialize", imv->get_name(imv));
+ return FALSE;
+ }
+ this->imvs->insert_last(this->imvs, imv);
+ this->next_imv_id++;
+
+ if (imv->provide_bind_function(imv->get_id(imv), TNC_TNCS_BindFunction)
+ != TNC_RESULT_SUCCESS)
+ {
+ DBG1(DBG_TNC, "IMV \"%s\" could failed to obtain bind function",
+ imv->get_name(imv));
+ this->imvs->remove_last(this->imvs, (void**)&imv);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+METHOD(imv_manager_t, remove_, imv_t*,
+ private_tnc_imv_manager_t *this, TNC_IMVID id)
+{
+ enumerator_t *enumerator;
+ imv_t *imv;
+
+ enumerator = this->imvs->create_enumerator(this->imvs);
+ while (enumerator->enumerate(enumerator, &imv))
+ {
+ if (id == imv->get_id(imv))
+ {
+ this->imvs->remove_at(this->imvs, enumerator);
+ return imv;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return NULL;
+}
+
+METHOD(imv_manager_t, get_recommendation_policy, recommendation_policy_t,
+ private_tnc_imv_manager_t *this)
+{
+ return this->policy;
+}
+
+METHOD(imv_manager_t, create_recommendations, recommendations_t*,
+ private_tnc_imv_manager_t *this)
+{
+ return tnc_imv_recommendations_create(this->imvs);
+}
+
+METHOD(imv_manager_t, enforce_recommendation, bool,
+ private_tnc_imv_manager_t *this, TNC_IMV_Action_Recommendation rec)
+{
+ char *group;
+ identification_t *id;
+ ike_sa_t *ike_sa;
+ auth_cfg_t *auth;
+
+ 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;
+ }
+ ike_sa = charon->bus->get_sa(charon->bus);
+ if (ike_sa)
+ {
+ 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);
+ }
+ return TRUE;
+}
+
+
+METHOD(imv_manager_t, notify_connection_change, void,
+ private_tnc_imv_manager_t *this, TNC_ConnectionID id,
+ TNC_ConnectionState state)
+{
+ enumerator_t *enumerator;
+ imv_t *imv;
+
+ enumerator = this->imvs->create_enumerator(this->imvs);
+ while (enumerator->enumerate(enumerator, &imv))
+ {
+ if (imv->notify_connection_change)
+ {
+ imv->notify_connection_change(imv->get_id(imv), id, state);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(imv_manager_t, set_message_types, TNC_Result,
+ private_tnc_imv_manager_t *this, TNC_IMVID id,
+ TNC_MessageTypeList supported_types,
+ TNC_UInt32 type_count)
+{
+ enumerator_t *enumerator;
+ imv_t *imv;
+ TNC_Result result = TNC_RESULT_FATAL;
+
+ enumerator = this->imvs->create_enumerator(this->imvs);
+ while (enumerator->enumerate(enumerator, &imv))
+ {
+ if (id == imv->get_id(imv))
+ {
+ imv->set_message_types(imv, supported_types, type_count);
+ result = TNC_RESULT_SUCCESS;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return result;
+}
+
+METHOD(imv_manager_t, solicit_recommendation, void,
+ private_tnc_imv_manager_t *this, TNC_ConnectionID id)
+{
+ enumerator_t *enumerator;
+ imv_t *imv;
+
+ enumerator = this->imvs->create_enumerator(this->imvs);
+ while (enumerator->enumerate(enumerator, &imv))
+ {
+ imv->solicit_recommendation(imv->get_id(imv), id);
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(imv_manager_t, receive_message, void,
+ private_tnc_imv_manager_t *this, TNC_ConnectionID connection_id,
+ TNC_BufferReference message,
+ TNC_UInt32 message_len,
+ TNC_MessageType message_type)
+{
+ enumerator_t *enumerator;
+ imv_t *imv;
+
+ enumerator = this->imvs->create_enumerator(this->imvs);
+ while (enumerator->enumerate(enumerator, &imv))
+ {
+ if (imv->receive_message && imv->type_supported(imv, message_type))
+ {
+ imv->receive_message(imv->get_id(imv), connection_id,
+ message, message_len, message_type);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(imv_manager_t, batch_ending, void,
+ private_tnc_imv_manager_t *this, TNC_ConnectionID id)
+{
+ enumerator_t *enumerator;
+ imv_t *imv;
+
+ enumerator = this->imvs->create_enumerator(this->imvs);
+ while (enumerator->enumerate(enumerator, &imv))
+ {
+ if (imv->batch_ending)
+ {
+ imv->batch_ending(imv->get_id(imv), id);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(imv_manager_t, destroy, void,
+ private_tnc_imv_manager_t *this)
+{
+ imv_t *imv;
+
+ while (this->imvs->remove_last(this->imvs, (void**)&imv) == SUCCESS)
+ {
+ 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);
+ }
+ this->imvs->destroy(this->imvs);
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+imv_manager_t* tnc_imv_manager_create(void)
+{
+ private_tnc_imv_manager_t *this;
+ recommendation_policy_t policy;
+
+ INIT(this,
+ .public = {
+ .add = _add,
+ .remove = _remove_, /* avoid name conflict with stdio.h */
+ .get_recommendation_policy = _get_recommendation_policy,
+ .create_recommendations = _create_recommendations,
+ .enforce_recommendation = _enforce_recommendation,
+ .notify_connection_change = _notify_connection_change,
+ .set_message_types = _set_message_types,
+ .solicit_recommendation = _solicit_recommendation,
+ .receive_message = _receive_message,
+ .batch_ending = _batch_ending,
+ .destroy = _destroy,
+ },
+ .imvs = linked_list_create(),
+ .next_imv_id = 1,
+ );
+ policy = enum_from_name(recommendation_policy_names,
+ lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-imv.recommendation_policy", "default"));
+ this->policy = (policy != -1) ? policy : RECOMMENDATION_POLICY_DEFAULT;
+ DBG1(DBG_TNC, "TNC recommendation policy is '%N'",
+ recommendation_policy_names, this->policy);
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_manager.h b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.h
new file mode 100644
index 000000000..2fe9e7ae3
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.h
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+/**
+ *
+ * @defgroup tnc_imv_manager tnc_imv_manager
+ * @{ @ingroup tnc_imv
+ */
+
+#ifndef TNC_IMV_MANAGER_H_
+#define TNC_IMV_MANAGER_H_
+
+#include <tnc/imv/imv_manager.h>
+
+/**
+ * Create an IMV manager instance.
+ */
+imv_manager_t *tnc_imv_manager_create();
+
+#endif /** TNC_IMV_MANAGER_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
index 5b3d3892d..f238f01ea 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
@@ -14,15 +14,137 @@
*/
#include "tnc_imv_plugin.h"
+#include "tnc_imv_manager.h"
+#include "tnc_imv.h"
-#include <libtnctncs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
#include <daemon.h>
+#include <utils/lexparser.h>
+
+/**
+ * load IMVs from a configuration file
+ */
+static bool load_imvs(char *filename)
+{
+ int fd, line_nr = 0;
+ chunk_t src, line;
+ struct stat sb;
+ void *addr;
+
+ DBG1(DBG_TNC, "loading IMVs from '%s'", filename);
+ fd = open(filename, O_RDONLY);
+ if (fd == -1)
+ {
+ DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename,
+ strerror(errno));
+ return FALSE;
+ }
+ if (fstat(fd, &sb) == -1)
+ {
+ DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename,
+ strerror(errno));
+ close(fd);
+ return FALSE;
+ }
+ addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ if (addr == MAP_FAILED)
+ {
+ DBG1(DBG_LIB, "mapping '%s' failed: %s", filename, strerror(errno));
+ close(fd);
+ return FALSE;
+ }
+ src = chunk_create(addr, sb.st_size);
+
+ while (fetchline(&src, &line))
+ {
+ char *name, *path;
+ chunk_t token;
+ imv_t *imv;
+
+ line_nr++;
+
+ /* skip comments or empty lines */
+ if (*line.ptr == '#' || !eat_whitespace(&line))
+ {
+ continue;
+ }
+
+ /* determine keyword */
+ if (!extract_token(&token, ' ', &line))
+ {
+ DBG1(DBG_TNC, "line %d: keyword must be followed by a space",
+ line_nr);
+ return FALSE;
+ }
+
+ /* only interested in IMVs */
+ if (!match("IMV", &token))
+ {
+ continue;
+ }
+
+ /* advance to the IMV name and extract it */
+ if (!extract_token(&token, '"', &line) ||
+ !extract_token(&token, '"', &line))
+ {
+ DBG1(DBG_TNC, "line %d: IMV name must be set in double quotes",
+ line_nr);
+ return FALSE;
+ }
+
+ /* copy the IMV name */
+ name = malloc(token.len + 1);
+ memcpy(name, token.ptr, token.len);
+ name[token.len] = '\0';
+
+ /* advance to the IMV path and extract it */
+ if (!eat_whitespace(&line))
+ {
+ DBG1(DBG_TNC, "line %d: IMV path is missing", line_nr);
+ free(name);
+ return FALSE;
+ }
+ if (!extract_token(&token, ' ', &line))
+ {
+ token = line;
+ }
+
+ /* copy the IMV path */
+ path = malloc(token.len + 1);
+ memcpy(path, token.ptr, token.len);
+ path[token.len] = '\0';
+
+ /* load and register IMV instance */
+ imv = tnc_imv_create(name, path);
+ if (!imv)
+ {
+ free(name);
+ free(path);
+ return FALSE;
+ }
+ if (!charon->imvs->add(charon->imvs, imv))
+ {
+ imv->destroy(imv);
+ return FALSE;
+ }
+ DBG1(DBG_TNC, "IMV %u \"%s\" loaded from '%s'", imv->get_id(imv),
+ name, path);
+ }
+ munmap(addr, sb.st_size);
+ close(fd);
+ return TRUE;
+}
METHOD(plugin_t, destroy, void,
tnc_imv_plugin_t *this)
{
- libtnc_tncs_Terminate();
+ charon->imvs->destroy(charon->imvs);
free(this);
}
@@ -42,13 +164,18 @@ plugin_t *tnc_imv_plugin_create()
tnc_config = lib->settings->get_str(lib->settings,
"charon.plugins.tnc-imv.tnc_config", "/etc/tnc_config");
- if (libtnc_tncs_Initialize(tnc_config) != TNC_RESULT_SUCCESS)
+
+ /* Create IMV manager */
+ charon->imvs = tnc_imv_manager_create();
+
+ /* Load IMVs and abort if not all instances initalize successfully */
+ if (!load_imvs(tnc_config))
{
+ charon->imvs->destroy(charon->imvs);
+ charon->imvs = NULL;
free(this);
- DBG1(DBG_TNC, "TNC IMV initialization failed");
return NULL;
}
-
return &this->plugin;
}
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c b/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c
new file mode 100644
index 000000000..5cc6b0ced
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c
@@ -0,0 +1,415 @@
+/*
+ * 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 <debug.h>
+#include <daemon.h>
+#include <tnc/tncifimv.h>
+#include <tnc/imv/imv.h>
+#include <tnc/imv/imv_recommendations.h>
+
+typedef struct private_tnc_imv_recommendations_t private_tnc_imv_recommendations_t;
+typedef struct recommendation_entry_t recommendation_entry_t;
+
+/**
+ * Recommendation entry
+ */
+struct recommendation_entry_t {
+
+ /**
+ * IMV ID
+ */
+ TNC_IMVID id;
+
+ /**
+ * Received a recommendation message from this IMV?
+ */
+ bool have_recommendation;
+
+ /**
+ * Action Recommendation provided by IMV instance
+ */
+ TNC_IMV_Action_Recommendation rec;
+
+ /**
+ * Evaluation Result provided by IMV instance
+ */
+ TNC_IMV_Evaluation_Result eval;
+
+ /**
+ * Reason string provided by IMV instance
+ */
+ chunk_t reason;
+
+ /**
+ * Reason language provided by IMV instance
+ */
+ chunk_t reason_language;
+};
+
+/**
+ * Private data of a recommendations_t object.
+ */
+struct private_tnc_imv_recommendations_t {
+
+ /**
+ * Public members of recommendations_t.
+ */
+ recommendations_t public;
+
+ /**
+ * list of recommendations and evaluations provided by IMVs
+ */
+ linked_list_t *recs;
+
+ /**
+ * Preferred language for remediation messages
+ */
+ chunk_t preferred_language;
+};
+
+METHOD(recommendations_t, provide_recommendation, TNC_Result,
+ private_tnc_imv_recommendations_t* this, TNC_IMVID id,
+ TNC_IMV_Action_Recommendation rec,
+ TNC_IMV_Evaluation_Result eval)
+{
+ enumerator_t *enumerator;
+ recommendation_entry_t *entry;
+ bool found = FALSE;
+
+ DBG2(DBG_TNC, "IMV %u provides recommendation '%N' and evaluation '%N'", id,
+ TNC_IMV_Action_Recommendation_names, rec,
+ TNC_IMV_Evaluation_Result_names, eval);
+
+ enumerator = this->recs->create_enumerator(this->recs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->id == id)
+ {
+ found = TRUE;
+ entry->have_recommendation = TRUE;
+ entry->rec = rec;
+ entry->eval = eval;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return found ? TNC_RESULT_SUCCESS : TNC_RESULT_FATAL;
+}
+
+METHOD(recommendations_t, have_recommendation, bool,
+ private_tnc_imv_recommendations_t *this, TNC_IMV_Action_Recommendation *rec,
+ TNC_IMV_Evaluation_Result *eval)
+{
+ enumerator_t *enumerator;
+ recommendation_entry_t *entry;
+ recommendation_policy_t policy;
+ TNC_IMV_Action_Recommendation final_rec;
+ TNC_IMV_Evaluation_Result final_eval;
+ bool first = TRUE, incomplete = FALSE;
+
+ *rec = final_rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION;
+ *eval = final_eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW;
+
+ if (this->recs->get_count(this->recs) == 0)
+ {
+ DBG1(DBG_TNC, "there are no IMVs to make a recommendation");
+ return TRUE;
+ }
+ policy = charon->imvs->get_recommendation_policy(charon->imvs);
+
+ enumerator = this->recs->create_enumerator(this->recs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (!entry->have_recommendation)
+ {
+ incomplete = TRUE;
+ break;
+ }
+ if (first)
+ {
+ final_rec = entry->rec;
+ final_eval = entry->eval;
+ first = FALSE;
+ continue;
+ }
+ switch (policy)
+ {
+ case RECOMMENDATION_POLICY_DEFAULT:
+ switch (entry->rec)
+ {
+ case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
+ final_rec = entry->rec;
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
+ if (final_rec != TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS)
+ {
+ final_rec = entry->rec;
+ };
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
+ if (final_rec == TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION)
+ {
+ final_rec = entry->rec;
+ };
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
+ break;
+ }
+ switch (entry->eval)
+ {
+ case TNC_IMV_EVALUATION_RESULT_ERROR:
+ final_eval = entry->eval;
+ break;
+ case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR:
+ if (final_eval != TNC_IMV_EVALUATION_RESULT_ERROR)
+ {
+ final_eval = entry->eval;
+ }
+ break;
+ case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR:
+ if (final_eval != TNC_IMV_EVALUATION_RESULT_ERROR &&
+ final_eval != TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR)
+ {
+ final_eval = entry->eval;
+ }
+ break;
+ case TNC_IMV_EVALUATION_RESULT_COMPLIANT:
+ if (final_eval == TNC_IMV_EVALUATION_RESULT_DONT_KNOW)
+ {
+ final_eval = entry->eval;
+ }
+ break;
+ case TNC_IMV_EVALUATION_RESULT_DONT_KNOW:
+ break;
+ }
+ break;
+
+ case RECOMMENDATION_POLICY_ALL:
+ if (entry->rec != final_rec)
+ {
+ final_rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION;
+ }
+ if (entry->eval != final_eval)
+ {
+ final_eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW;
+ }
+ break;
+
+ case RECOMMENDATION_POLICY_ANY:
+ switch (entry->rec)
+ {
+ case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
+ final_rec = entry->rec;
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
+ if (final_rec != TNC_IMV_ACTION_RECOMMENDATION_ALLOW)
+ {
+ final_rec = entry->rec;
+ };
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
+ if (final_rec == TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION)
+ {
+ final_rec = entry->rec;
+ };
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
+ break;
+ }
+ switch (entry->eval)
+ {
+ case TNC_IMV_EVALUATION_RESULT_COMPLIANT:
+ final_eval = entry->eval;
+ break;
+ case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR:
+ if (final_eval != TNC_IMV_EVALUATION_RESULT_COMPLIANT)
+ {
+ final_eval = entry->eval;
+ }
+ break;
+ case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR:
+ if (final_eval != TNC_IMV_EVALUATION_RESULT_COMPLIANT &&
+ final_eval != TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR)
+ {
+ final_eval = entry->eval;
+ }
+ break;
+ case TNC_IMV_EVALUATION_RESULT_ERROR:
+ if (final_eval == TNC_IMV_EVALUATION_RESULT_DONT_KNOW)
+ {
+ final_eval = entry->eval;
+ }
+ break;
+ case TNC_IMV_EVALUATION_RESULT_DONT_KNOW:
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (incomplete)
+ {
+ return FALSE;
+ }
+ *rec = final_rec;
+ *eval = final_eval;
+ return TRUE;
+}
+
+METHOD(recommendations_t, get_preferred_language, chunk_t,
+ private_tnc_imv_recommendations_t *this)
+{
+ return this->preferred_language;
+}
+
+METHOD(recommendations_t, set_preferred_language, void,
+ private_tnc_imv_recommendations_t *this, chunk_t pref_lang)
+{
+ free(this->preferred_language.ptr);
+ this->preferred_language = chunk_clone(pref_lang);
+}
+
+METHOD(recommendations_t, set_reason_string, TNC_Result,
+ private_tnc_imv_recommendations_t *this, TNC_IMVID id, chunk_t reason)
+{
+ enumerator_t *enumerator;
+ recommendation_entry_t *entry;
+ bool found = FALSE;
+
+ DBG2(DBG_TNC, "IMV %u is setting reason string to '%.*s'",
+ id, reason.len, reason.ptr);
+
+ enumerator = this->recs->create_enumerator(this->recs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->id == id)
+ {
+ found = TRUE;
+ free(entry->reason.ptr);
+ entry->reason = chunk_clone(reason);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return found ? TNC_RESULT_SUCCESS : TNC_RESULT_INVALID_PARAMETER;
+}
+
+METHOD(recommendations_t, set_reason_language, TNC_Result,
+ private_tnc_imv_recommendations_t *this, TNC_IMVID id, chunk_t reason_lang)
+{
+ enumerator_t *enumerator;
+ recommendation_entry_t *entry;
+ bool found = FALSE;
+
+ DBG2(DBG_TNC, "IMV %u is setting reason language to '%.*s'",
+ id, reason_lang.len, reason_lang.ptr);
+
+ enumerator = this->recs->create_enumerator(this->recs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->id == id)
+ {
+ found = TRUE;
+ free(entry->reason_language.ptr);
+ entry->reason_language = chunk_clone(reason_lang);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return found ? TNC_RESULT_SUCCESS : TNC_RESULT_INVALID_PARAMETER;
+}
+
+/**
+ * Enumerate reason and reason_language, not recommendation entries
+ */
+static bool reason_filter(void *null, recommendation_entry_t **entry,
+ TNC_IMVID *id, void *i2, chunk_t *reason, void *i3,
+ chunk_t *reason_language)
+{
+ if ((*entry)->reason.len)
+ {
+ *id = (*entry)->id;
+ *reason = (*entry)->reason;
+ *reason_language = (*entry)->reason_language;
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+METHOD(recommendations_t, create_reason_enumerator, enumerator_t*,
+ private_tnc_imv_recommendations_t *this)
+{
+ return enumerator_create_filter(this->recs->create_enumerator(this->recs),
+ (void*)reason_filter, NULL, NULL);
+}
+
+METHOD(recommendations_t, destroy, void,
+ private_tnc_imv_recommendations_t *this)
+{
+ recommendation_entry_t *entry;
+
+ while (this->recs->remove_last(this->recs, (void**)&entry) == SUCCESS)
+ {
+ free(entry->reason.ptr);
+ free(entry->reason_language.ptr);
+ free(entry);
+ }
+ this->recs->destroy(this->recs);
+ free(this->preferred_language.ptr);
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+recommendations_t* tnc_imv_recommendations_create(linked_list_t *imv_list)
+{
+ private_tnc_imv_recommendations_t *this;
+ recommendation_entry_t *entry;
+ enumerator_t *enumerator;
+ imv_t *imv;
+
+ INIT(this,
+ .public = {
+ .provide_recommendation = _provide_recommendation,
+ .have_recommendation = _have_recommendation,
+ .get_preferred_language = _get_preferred_language,
+ .set_preferred_language = _set_preferred_language,
+ .set_reason_string = _set_reason_string,
+ .set_reason_language = _set_reason_language,
+ .create_reason_enumerator = _create_reason_enumerator,
+ .destroy = _destroy,
+ },
+ .recs = linked_list_create(),
+ );
+
+ enumerator = imv_list->create_enumerator(imv_list);
+ while (enumerator->enumerate(enumerator, &imv))
+ {
+ entry = malloc_thing(recommendation_entry_t);
+ entry->id = imv->get_id(imv);
+ entry->have_recommendation = FALSE;
+ entry->rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION;
+ entry->eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW;
+ entry->reason = chunk_empty;
+ entry->reason_language = chunk_empty;
+ this->recs->insert_last(this->recs, entry);
+ }
+ enumerator->destroy(enumerator);
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.h b/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.h
new file mode 100644
index 000000000..6d65a2521
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.h
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ *
+ * @defgroup tnc_imv_manager tnc_imv_manager
+ * @{ @ingroup tnc_imv
+ */
+
+#ifndef TNC_IMV_RECOMMENDATIONS_H_
+#define TNC_IMV_RECOMMENDATIONS_H_
+
+#include <tnc/imv/imv_recommendations.h>
+#include <utils/linked_list.h>
+
+/**
+ * Create an IMV empty recommendations instance
+ */
+recommendations_t *tnc_imv_recommendations_create();
+
+#endif /** TNC_IMV_RECOMMENDATIONS_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/Makefile.am b/src/libcharon/plugins/tnccs_11/Makefile.am
index 7ccd0dfee..1042c3514 100644
--- a/src/libcharon/plugins/tnccs_11/Makefile.am
+++ b/src/libcharon/plugins/tnccs_11/Makefile.am
@@ -1,21 +1,27 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls \
- `xml2-config --cflags`
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls ${xml_CFLAGS}
AM_CFLAGS = -rdynamic
-libstrongswan_tnccs_11_la_LIBADD = -ltnc
+libstrongswan_tnccs_11_la_LIBADD = ${xml_LIBS}
if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-tnccs-11.la
else
plugin_LTLIBRARIES = libstrongswan-tnccs-11.la
-libstrongswan_tnccs_11_la_LIBADD += $(top_builddir)/src/libtls/libtls.la
endif
libstrongswan_tnccs_11_la_SOURCES = \
- tnccs_11_plugin.h tnccs_11_plugin.c tnccs_11.h tnccs_11.c
+ tnccs_11_plugin.h tnccs_11_plugin.c tnccs_11.h tnccs_11.c \
+ batch/tnccs_batch.h batch/tnccs_batch.c \
+ messages/tnccs_msg.h messages/tnccs_msg.c \
+ messages/imc_imv_msg.h messages/imc_imv_msg.c \
+ messages/tnccs_error_msg.h messages/tnccs_error_msg.c \
+ messages/tnccs_preferred_language_msg.h messages/tnccs_preferred_language_msg.c \
+ messages/tnccs_reason_strings_msg.h messages/tnccs_reason_strings_msg.c \
+ messages/tnccs_recommendation_msg.h messages/tnccs_recommendation_msg.c \
+ messages/tnccs_tncs_contact_info_msg.h messages/tnccs_tncs_contact_info_msg.c
libstrongswan_tnccs_11_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/tnccs_11/Makefile.in b/src/libcharon/plugins/tnccs_11/Makefile.in
index 200ff7a0a..5ab7ccbca 100644
--- a/src/libcharon/plugins/tnccs_11/Makefile.in
+++ b/src/libcharon/plugins/tnccs_11/Makefile.in
@@ -34,7 +34,6 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-@MONOLITHIC_FALSE@am__append_1 = $(top_builddir)/src/libtls/libtls.la
subdir = src/libcharon/plugins/tnccs_11
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -75,8 +74,12 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_tnccs_11_la_DEPENDENCIES = $(am__append_1)
-am_libstrongswan_tnccs_11_la_OBJECTS = tnccs_11_plugin.lo tnccs_11.lo
+am__DEPENDENCIES_1 =
+libstrongswan_tnccs_11_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_libstrongswan_tnccs_11_la_OBJECTS = tnccs_11_plugin.lo tnccs_11.lo \
+ tnccs_batch.lo tnccs_msg.lo imc_imv_msg.lo tnccs_error_msg.lo \
+ tnccs_preferred_language_msg.lo tnccs_reason_strings_msg.lo \
+ tnccs_recommendation_msg.lo tnccs_tncs_contact_info_msg.lo
libstrongswan_tnccs_11_la_OBJECTS = \
$(am_libstrongswan_tnccs_11_la_OBJECTS)
libstrongswan_tnccs_11_la_LINK = $(LIBTOOL) --tag=CC \
@@ -223,9 +226,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +265,8 @@ 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@
@@ -275,15 +278,22 @@ 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 \
- `xml2-config --cflags`
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls ${xml_CFLAGS}
AM_CFLAGS = -rdynamic
-libstrongswan_tnccs_11_la_LIBADD = -ltnc $(am__append_1)
+libstrongswan_tnccs_11_la_LIBADD = ${xml_LIBS}
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnccs-11.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnccs-11.la
libstrongswan_tnccs_11_la_SOURCES = \
- tnccs_11_plugin.h tnccs_11_plugin.c tnccs_11.h tnccs_11.c
+ tnccs_11_plugin.h tnccs_11_plugin.c tnccs_11.h tnccs_11.c \
+ batch/tnccs_batch.h batch/tnccs_batch.c \
+ messages/tnccs_msg.h messages/tnccs_msg.c \
+ messages/imc_imv_msg.h messages/imc_imv_msg.c \
+ messages/tnccs_error_msg.h messages/tnccs_error_msg.c \
+ messages/tnccs_preferred_language_msg.h messages/tnccs_preferred_language_msg.c \
+ messages/tnccs_reason_strings_msg.h messages/tnccs_reason_strings_msg.c \
+ messages/tnccs_recommendation_msg.h messages/tnccs_recommendation_msg.c \
+ messages/tnccs_tncs_contact_info_msg.h messages/tnccs_tncs_contact_info_msg.c
libstrongswan_tnccs_11_la_LDFLAGS = -module -avoid-version
all: all-am
@@ -369,8 +379,16 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imc_imv_msg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_11.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_11_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_batch.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_error_msg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_msg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_preferred_language_msg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_reason_strings_msg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_recommendation_msg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_tncs_contact_info_msg.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -393,6 +411,62 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+tnccs_batch.lo: batch/tnccs_batch.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs_batch.lo -MD -MP -MF $(DEPDIR)/tnccs_batch.Tpo -c -o tnccs_batch.lo `test -f 'batch/tnccs_batch.c' || echo '$(srcdir)/'`batch/tnccs_batch.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_batch.Tpo $(DEPDIR)/tnccs_batch.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='batch/tnccs_batch.c' object='tnccs_batch.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs_batch.lo `test -f 'batch/tnccs_batch.c' || echo '$(srcdir)/'`batch/tnccs_batch.c
+
+tnccs_msg.lo: messages/tnccs_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs_msg.lo -MD -MP -MF $(DEPDIR)/tnccs_msg.Tpo -c -o tnccs_msg.lo `test -f 'messages/tnccs_msg.c' || echo '$(srcdir)/'`messages/tnccs_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_msg.Tpo $(DEPDIR)/tnccs_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/tnccs_msg.c' object='tnccs_msg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs_msg.lo `test -f 'messages/tnccs_msg.c' || echo '$(srcdir)/'`messages/tnccs_msg.c
+
+imc_imv_msg.lo: messages/imc_imv_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imc_imv_msg.lo -MD -MP -MF $(DEPDIR)/imc_imv_msg.Tpo -c -o imc_imv_msg.lo `test -f 'messages/imc_imv_msg.c' || echo '$(srcdir)/'`messages/imc_imv_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/imc_imv_msg.Tpo $(DEPDIR)/imc_imv_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/imc_imv_msg.c' object='imc_imv_msg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imc_imv_msg.lo `test -f 'messages/imc_imv_msg.c' || echo '$(srcdir)/'`messages/imc_imv_msg.c
+
+tnccs_error_msg.lo: messages/tnccs_error_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs_error_msg.lo -MD -MP -MF $(DEPDIR)/tnccs_error_msg.Tpo -c -o tnccs_error_msg.lo `test -f 'messages/tnccs_error_msg.c' || echo '$(srcdir)/'`messages/tnccs_error_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_error_msg.Tpo $(DEPDIR)/tnccs_error_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/tnccs_error_msg.c' object='tnccs_error_msg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs_error_msg.lo `test -f 'messages/tnccs_error_msg.c' || echo '$(srcdir)/'`messages/tnccs_error_msg.c
+
+tnccs_preferred_language_msg.lo: messages/tnccs_preferred_language_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs_preferred_language_msg.lo -MD -MP -MF $(DEPDIR)/tnccs_preferred_language_msg.Tpo -c -o tnccs_preferred_language_msg.lo `test -f 'messages/tnccs_preferred_language_msg.c' || echo '$(srcdir)/'`messages/tnccs_preferred_language_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_preferred_language_msg.Tpo $(DEPDIR)/tnccs_preferred_language_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/tnccs_preferred_language_msg.c' object='tnccs_preferred_language_msg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs_preferred_language_msg.lo `test -f 'messages/tnccs_preferred_language_msg.c' || echo '$(srcdir)/'`messages/tnccs_preferred_language_msg.c
+
+tnccs_reason_strings_msg.lo: messages/tnccs_reason_strings_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs_reason_strings_msg.lo -MD -MP -MF $(DEPDIR)/tnccs_reason_strings_msg.Tpo -c -o tnccs_reason_strings_msg.lo `test -f 'messages/tnccs_reason_strings_msg.c' || echo '$(srcdir)/'`messages/tnccs_reason_strings_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_reason_strings_msg.Tpo $(DEPDIR)/tnccs_reason_strings_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/tnccs_reason_strings_msg.c' object='tnccs_reason_strings_msg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs_reason_strings_msg.lo `test -f 'messages/tnccs_reason_strings_msg.c' || echo '$(srcdir)/'`messages/tnccs_reason_strings_msg.c
+
+tnccs_recommendation_msg.lo: messages/tnccs_recommendation_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs_recommendation_msg.lo -MD -MP -MF $(DEPDIR)/tnccs_recommendation_msg.Tpo -c -o tnccs_recommendation_msg.lo `test -f 'messages/tnccs_recommendation_msg.c' || echo '$(srcdir)/'`messages/tnccs_recommendation_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_recommendation_msg.Tpo $(DEPDIR)/tnccs_recommendation_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/tnccs_recommendation_msg.c' object='tnccs_recommendation_msg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs_recommendation_msg.lo `test -f 'messages/tnccs_recommendation_msg.c' || echo '$(srcdir)/'`messages/tnccs_recommendation_msg.c
+
+tnccs_tncs_contact_info_msg.lo: messages/tnccs_tncs_contact_info_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs_tncs_contact_info_msg.lo -MD -MP -MF $(DEPDIR)/tnccs_tncs_contact_info_msg.Tpo -c -o tnccs_tncs_contact_info_msg.lo `test -f 'messages/tnccs_tncs_contact_info_msg.c' || echo '$(srcdir)/'`messages/tnccs_tncs_contact_info_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_tncs_contact_info_msg.Tpo $(DEPDIR)/tnccs_tncs_contact_info_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/tnccs_tncs_contact_info_msg.c' object='tnccs_tncs_contact_info_msg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs_tncs_contact_info_msg.lo `test -f 'messages/tnccs_tncs_contact_info_msg.c' || echo '$(srcdir)/'`messages/tnccs_tncs_contact_info_msg.c
+
mostlyclean-libtool:
-rm -f *.lo
diff --git a/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c b/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c
new file mode 100644
index 000000000..0f6f3a675
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2006 Mike McCauley (mikem@open.com.au)
+ * 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 "tnccs_batch.h"
+#include "messages/tnccs_error_msg.h"
+
+#include <debug.h>
+#include <utils/linked_list.h>
+#include <tnc/tnccs/tnccs.h>
+
+#include <libxml/parser.h>
+
+typedef struct private_tnccs_batch_t private_tnccs_batch_t;
+
+/**
+ * Private data of a tnccs_batch_t object.
+ *
+ */
+struct private_tnccs_batch_t {
+ /**
+ * Public tnccs_batch_t interface.
+ */
+ tnccs_batch_t public;
+
+ /**
+ * Batch ID
+ */
+ int batch_id;
+
+ /**
+ * TNCC if TRUE, TNCS if FALSE
+ */
+ bool is_server;
+
+ /**
+ * linked list of TNCCS messages
+ */
+ linked_list_t *messages;
+
+ /**
+ * linked list of TNCCS error messages
+ */
+ linked_list_t *errors;
+
+ /**
+ * XML document
+ */
+ xmlDocPtr doc;
+
+ /**
+ * Encoded message
+ */
+ chunk_t encoding;
+};
+
+METHOD(tnccs_batch_t, get_encoding, chunk_t,
+ private_tnccs_batch_t *this)
+{
+ return this->encoding;
+}
+
+METHOD(tnccs_batch_t, add_msg, void,
+ private_tnccs_batch_t *this, tnccs_msg_t* msg)
+{
+ xmlNodePtr root;
+
+ DBG2(DBG_TNC, "adding %N message", tnccs_msg_type_names,
+ msg->get_type(msg));
+ this->messages->insert_last(this->messages, msg);
+ root = xmlDocGetRootElement(this->doc);
+ xmlAddChild(root, msg->get_node(msg));
+}
+
+METHOD(tnccs_batch_t, build, void,
+ private_tnccs_batch_t *this)
+{
+ xmlChar *xmlbuf;
+ int buf_size;
+
+ xmlDocDumpFormatMemory(this->doc, &xmlbuf, &buf_size, 1);
+ this->encoding = chunk_create((u_char*)xmlbuf, buf_size);
+ this->encoding = chunk_clone(this->encoding);
+ xmlFree(xmlbuf);
+}
+
+METHOD(tnccs_batch_t, process, status_t,
+ private_tnccs_batch_t *this)
+{
+ tnccs_msg_t *tnccs_msg, *msg;
+ tnccs_error_type_t error_type = TNCCS_ERROR_OTHER;
+ char *error_msg, buf[BUF_LEN];
+ xmlNodePtr cur;
+ xmlNsPtr ns;
+ xmlChar *batchid, *recipient;
+ int batch_id;
+
+ this->doc = xmlParseMemory(this->encoding.ptr, this->encoding.len);
+ if (!this->doc)
+ {
+ error_type = TNCCS_ERROR_MALFORMED_BATCH;
+ error_msg = "failed to parse XML message";
+ goto fatal;
+ }
+
+ /* check out the XML document */
+ cur = xmlDocGetRootElement(this->doc);
+ if (!cur)
+ {
+ error_type = TNCCS_ERROR_MALFORMED_BATCH;
+ error_msg = "empty XML document";
+ goto fatal;
+ }
+
+ /* check TNCCS namespace */
+ ns = xmlSearchNsByHref(this->doc, cur, (const xmlChar*)
+ "http://www.trustedcomputinggroup.org/IWG/TNC/1_0/IF_TNCCS#");
+ if (!ns)
+ {
+ error_type = TNCCS_ERROR_MALFORMED_BATCH;
+ error_msg = "TNCCS namespace not found";
+ goto fatal;
+ }
+
+ /* check XML document type */
+ if (xmlStrcmp(cur->name, (const xmlChar*)"TNCCS-Batch"))
+ {
+ error_type = TNCCS_ERROR_MALFORMED_BATCH;
+ error_msg = buf;
+ snprintf(buf, BUF_LEN, "wrong XML document type '%s', expected TNCCS-Batch",
+ cur->name);
+ goto fatal;
+ }
+
+ /* check presence of BatchID property */
+ batchid = xmlGetProp(cur, (const xmlChar*)"BatchId");
+ if (!batchid)
+ {
+ error_type = TNCCS_ERROR_INVALID_BATCH_ID;
+ error_msg = "BatchId is missing";
+ goto fatal;
+ }
+
+ /* check BatchID */
+ batch_id = atoi((char*)batchid);
+ xmlFree(batchid);
+ if (batch_id != this->batch_id)
+ {
+ error_type = TNCCS_ERROR_INVALID_BATCH_ID;
+ error_msg = buf;
+ snprintf(buf, BUF_LEN, "BatchId %d expected, got %d", this->batch_id,
+ batch_id);
+ goto fatal;
+ }
+
+ /* check presence of Recipient property */
+ recipient = xmlGetProp(cur, (const xmlChar*)"Recipient");
+ if (!recipient)
+ {
+ error_type = TNCCS_ERROR_INVALID_RECIPIENT_TYPE;
+ error_msg = "Recipient is missing";
+ goto fatal;
+ }
+
+ /* check recipient */
+ if (!streq((char*)recipient, this->is_server ? "TNCS" : "TNCC"))
+ {
+ error_type = TNCCS_ERROR_INVALID_RECIPIENT_TYPE;
+ error_msg = buf;
+ snprintf(buf, BUF_LEN, "message recipient expected '%s', got '%s'",
+ this->is_server ? "TNCS" : "TNCC", (char*)recipient);
+ xmlFree(recipient);
+ goto fatal;
+ }
+ xmlFree(recipient);
+
+ DBG2(DBG_TNC, "processing TNCCS Batch #%d", batch_id);
+
+ /* Now walk the tree, handling message nodes as we go */
+ for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next)
+ {
+ /* ignore empty or blank nodes */
+ if (xmlIsBlankNode(cur))
+ {
+ continue;
+ }
+
+ /* ignore nodes with wrong namespace */
+ if (cur->ns != ns)
+ {
+ DBG1(DBG_TNC, "ignoring message node '%s' having wrong namespace",
+ (char*)cur->name);
+ continue;
+ }
+
+ tnccs_msg = tnccs_msg_create_from_node(cur, this->errors);
+
+ /* exit if a message parsing error occurred */
+ if (this->errors->get_count(this->errors) > 0)
+ {
+ return FAILED;
+ }
+
+ /* ignore unrecognized messages */
+ if (!tnccs_msg)
+ {
+ continue;
+ }
+
+ this->messages->insert_last(this->messages, tnccs_msg);
+ }
+ return SUCCESS;
+
+fatal:
+ msg = tnccs_error_msg_create(error_type, error_msg);
+ this->errors->insert_last(this->errors, msg);
+ return FAILED;
+}
+
+METHOD(tnccs_batch_t, create_msg_enumerator, enumerator_t*,
+ private_tnccs_batch_t *this)
+{
+ return this->messages->create_enumerator(this->messages);
+}
+
+METHOD(tnccs_batch_t, create_error_enumerator, enumerator_t*,
+ private_tnccs_batch_t *this)
+{
+ return this->errors->create_enumerator(this->errors);
+}
+
+METHOD(tnccs_batch_t, destroy, void,
+ private_tnccs_batch_t *this)
+{
+ this->messages->destroy_offset(this->messages,
+ offsetof(tnccs_msg_t, destroy));
+ this->errors->destroy_offset(this->errors,
+ offsetof(tnccs_msg_t, destroy));
+ xmlFreeDoc(this->doc);
+ free(this->encoding.ptr);
+ free(this);
+}
+
+/**
+ * See header
+ */
+tnccs_batch_t* tnccs_batch_create(bool is_server, int batch_id)
+{
+ private_tnccs_batch_t *this;
+ xmlNodePtr n;
+ char buf[12];
+ const char *recipient;
+
+ INIT(this,
+ .public = {
+ .get_encoding = _get_encoding,
+ .add_msg = _add_msg,
+ .build = _build,
+ .process = _process,
+ .create_msg_enumerator = _create_msg_enumerator,
+ .create_error_enumerator = _create_error_enumerator,
+ .destroy = _destroy,
+ },
+ .is_server = is_server,
+ .messages = linked_list_create(),
+ .errors = linked_list_create(),
+ .batch_id = batch_id,
+ .doc = xmlNewDoc(BAD_CAST "1.0"),
+ );
+
+ DBG2(DBG_TNC, "creating TNCCS Batch #%d", this->batch_id);
+ n = xmlNewNode(NULL, BAD_CAST "TNCCS-Batch");
+ snprintf(buf, sizeof(buf), "%d", batch_id);
+ recipient = this->is_server ? "TNCC" : "TNCS";
+ xmlNewProp(n, BAD_CAST "BatchId", BAD_CAST buf);
+ xmlNewProp(n, BAD_CAST "Recipient", BAD_CAST recipient);
+ xmlNewProp(n, BAD_CAST "xmlns", BAD_CAST "http://www.trustedcomputinggroup.org/IWG/TNC/1_0/IF_TNCCS#");
+ xmlNewProp(n, BAD_CAST "xmlns:xsi", BAD_CAST "http://www.w3.org/2001/XMLSchema-instance");
+ xmlNewProp(n, BAD_CAST "xsi:schemaLocation", BAD_CAST "http://www.trustedcomputinggroup.org/IWG/TNC/1_0/IF_TNCCS# "
+ "https://www.trustedcomputinggroup.org/XML/SCHEMA/TNCCS_1.0.xsd");
+ xmlDocSetRootElement(this->doc, n);
+
+ return &this->public;
+}
+
+/**
+ * See header
+ */
+tnccs_batch_t* tnccs_batch_create_from_data(bool is_server, int batch_id, chunk_t data)
+{
+ private_tnccs_batch_t *this;
+
+ INIT(this,
+ .public = {
+ .get_encoding = _get_encoding,
+ .add_msg = _add_msg,
+ .build = _build,
+ .process = _process,
+ .create_msg_enumerator = _create_msg_enumerator,
+ .create_error_enumerator = _create_error_enumerator,
+ .destroy = _destroy,
+ },
+ .is_server = is_server,
+ .batch_id = batch_id,
+ .messages = linked_list_create(),
+ .errors = linked_list_create(),
+ .encoding = chunk_clone(data),
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.h b/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.h
new file mode 100644
index 000000000..25301f763
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.h
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup tnccs_batch tnccs_batch
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_BATCH_H_
+#define TNCCS_BATCH_H_
+
+typedef enum tnccs_batch_type_t tnccs_batch_type_t;
+typedef struct tnccs_batch_t tnccs_batch_t;
+
+#include "messages/tnccs_msg.h"
+
+#include <library.h>
+
+/**
+ * Interface for a TNCCS 1.x Batch.
+ */
+struct tnccs_batch_t {
+
+ /**
+ * Get the encoding of the TNCCS 1.x Batch
+ *
+ * @return encoded TNCCS 1.x batch
+ */
+ chunk_t (*get_encoding)(tnccs_batch_t *this);
+
+ /**
+ * Add TNCCS message
+ *
+ * @param msg TNCCS message to be addedd
+ */
+ void (*add_msg)(tnccs_batch_t *this, tnccs_msg_t* msg);
+
+ /**
+ * Build the TNCCS 1.x Batch
+ */
+ void (*build)(tnccs_batch_t *this);
+
+ /**
+ * Process the TNCCS 1.x Batch
+ *
+ * @return return processing status
+ */
+ status_t (*process)(tnccs_batch_t *this);
+
+ /**
+ * Enumerates over all TNCCS Messages
+ *
+ * @return return message enumerator
+ */
+ enumerator_t* (*create_msg_enumerator)(tnccs_batch_t *this);
+
+ /**
+ * Enumerates over all parsing errors
+ *
+ * @return return error enumerator
+ */
+ enumerator_t* (*create_error_enumerator)(tnccs_batch_t *this);
+
+ /**
+ * Destroys a tnccs_batch_t object.
+ */
+ void (*destroy)(tnccs_batch_t *this);
+};
+
+/**
+ * Create an empty TNCCS 1.x Batch
+ *
+ * @param is_server TRUE if server, FALSE if client
+ * @param batch_id number of the batch to be sent
+ */
+tnccs_batch_t* tnccs_batch_create(bool is_server, int batch_id);
+
+/**
+ * Create an unprocessed TNCCS 1.x Batch from data
+ *
+ * @param is_server TRUE if server, FALSE if client
+ * @param batch_id current Batch ID
+ * @param data encoded PB-TNC batch
+ */
+tnccs_batch_t* tnccs_batch_create_from_data(bool is_server, int batch_id,
+ chunk_t data);
+
+#endif /** TNCCS_BATCH_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c
new file mode 100644
index 000000000..f24c0dac9
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2006 Mike McCauley (mikem@open.com.au)
+ * 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 "imc_imv_msg.h"
+
+#include <tnc/tnccs/tnccs.h>
+#include <debug.h>
+#include <utils/lexparser.h>
+
+typedef struct private_imc_imv_msg_t private_imc_imv_msg_t;
+
+#define BYTES_PER_LINE 57
+
+/**
+ * Private data of a imc_imv_msg_t object.
+ *
+ */
+struct private_imc_imv_msg_t {
+ /**
+ * Public imc_imv_msg_t interface.
+ */
+ imc_imv_msg_t public;
+
+ /**
+ * TNCCS message type
+ */
+ tnccs_msg_type_t type;
+
+ /**
+ * XML-encoded message node
+ */
+ xmlNodePtr node;
+
+ /**
+ * IMC-IMV message type
+ */
+ TNC_MessageType msg_type;
+
+ /**
+ * IMC-IMV message body
+ */
+ chunk_t msg_body;
+
+};
+
+/**
+ * Encodes message data into multiple base64-encoded lines
+ */
+static chunk_t encode_base64(chunk_t data)
+{
+ chunk_t encoding;
+ u_char *pos;
+ size_t b64_chars, b64_lines;
+
+ /* handle empty message data object */
+ if (data.len == 0)
+ {
+ encoding = chunk_alloc(1);
+ *encoding.ptr = '\0';
+ return encoding;
+ }
+
+ /* compute and allocate maximum size of base64 object */
+ b64_chars = 4 * ((data.len + 2) / 3);
+ b64_lines = (data.len + BYTES_PER_LINE - 1) / BYTES_PER_LINE;
+ encoding = chunk_alloc(b64_chars + b64_lines);
+ pos = encoding.ptr;
+
+ /* encode lines */
+ while (b64_lines--)
+ {
+ chunk_t data_line, b64_line;
+
+ data_line = chunk_create(data.ptr, min(data.len, BYTES_PER_LINE));
+ data.ptr += data_line.len;
+ data.len -= data_line.len;
+ b64_line = chunk_to_base64(data_line, pos);
+ pos += b64_line.len;
+ *pos = '\n';
+ pos++;
+ }
+ /* terminate last line with NULL character instead of newline */
+ *(pos-1) = '\0';
+
+ return encoding;
+}
+
+/**
+ * Decodes message data from multiple base64-encoded lines
+ */
+static chunk_t decode_base64(chunk_t data)
+{
+ chunk_t decoding, data_line, b64_line;
+ u_char *pos;
+
+ /* compute and allocate maximum size of decoded message data */
+ decoding = chunk_alloc(3 * ((data.len + 3) / 4));
+ pos = decoding.ptr;
+ decoding.len = 0;
+
+ while (fetchline(&data, &b64_line))
+ {
+ data_line = chunk_from_base64(b64_line, pos);
+ pos += data_line.len;
+ decoding.len += data_line.len;
+ }
+
+ return decoding;
+}
+
+METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
+ private_imc_imv_msg_t *this)
+{
+ return this->type;
+}
+
+METHOD(tnccs_msg_t, get_node, xmlNodePtr,
+ private_imc_imv_msg_t *this)
+{
+ return this->node;
+}
+
+METHOD(tnccs_msg_t, destroy, void,
+ private_imc_imv_msg_t *this)
+{
+ free(this->msg_body.ptr);
+ free(this);
+}
+
+METHOD(imc_imv_msg_t, get_msg_type, TNC_MessageType,
+ private_imc_imv_msg_t *this)
+{
+ return this->msg_type;
+}
+
+METHOD(imc_imv_msg_t, get_msg_body, chunk_t,
+ private_imc_imv_msg_t *this)
+{
+ return this->msg_body;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *imc_imv_msg_create_from_node(xmlNodePtr node, linked_list_t *errors)
+{
+ private_imc_imv_msg_t *this;
+ xmlNsPtr ns;
+ xmlNodePtr cur;
+ xmlChar *content;
+ chunk_t b64_body;
+
+ INIT(this,
+ .public = {
+ .tnccs_msg_interface = {
+ .get_type = _get_type,
+ .get_node = _get_node,
+ .destroy = _destroy,
+ },
+ .get_msg_type = _get_msg_type,
+ .get_msg_body = _get_msg_body,
+ },
+ .type = IMC_IMV_MSG,
+ .node = node,
+ );
+
+ ns = node->ns;
+ cur = node->xmlChildrenNode;
+ while (cur)
+ {
+ if (streq((char*)cur->name, "Type") && cur->ns == ns)
+ {
+ content = xmlNodeGetContent(cur);
+ this->msg_type = strtoul((char*)content, NULL, 16);
+ xmlFree(content);
+ }
+ else if (streq((char*)cur->name, "Base64") && cur->ns == ns)
+ {
+ content = xmlNodeGetContent(cur);
+ b64_body = chunk_create((char*)content, strlen((char*)content));
+ this->msg_body = decode_base64(b64_body);
+ xmlFree(content);
+ }
+ cur = cur->next;
+ }
+
+ return &this->public.tnccs_msg_interface;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *imc_imv_msg_create(TNC_MessageType msg_type, chunk_t msg_body)
+{
+ private_imc_imv_msg_t *this;
+ chunk_t b64_body;
+ char buf[10]; /* big enough for hex-encoded message type */
+ xmlNodePtr n;
+
+ INIT(this,
+ .public = {
+ .tnccs_msg_interface = {
+ .get_type = _get_type,
+ .get_node = _get_node,
+ .destroy = _destroy,
+ },
+ .get_msg_type = _get_msg_type,
+ .get_msg_body = _get_msg_body,
+ },
+ .type = IMC_IMV_MSG,
+ .node = xmlNewNode(NULL, BAD_CAST "IMC-IMV-Message"),
+ .msg_type = msg_type,
+ .msg_body = chunk_clone(msg_body),
+ );
+
+ /* add the message type number in hex */
+ n = xmlNewNode(NULL, BAD_CAST "Type");
+ snprintf(buf, 10, "%08x", this->msg_type);
+ xmlNodeSetContent(n, BAD_CAST buf);
+ xmlAddChild(this->node, n);
+
+ /* encode the message as a Base64 node */
+ n = xmlNewNode(NULL, BAD_CAST "Base64");
+ b64_body = encode_base64(this->msg_body);
+ xmlNodeSetContent(n, BAD_CAST b64_body.ptr);
+ xmlAddChild(this->node, n);
+ free(b64_body.ptr);
+
+ return &this->public.tnccs_msg_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h
new file mode 100644
index 000000000..02f07199f
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup imc_imv_msg imc_imv_msg
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef IMC_IMV_MSG_H_
+#define IMC_IMV_MSG_H_
+
+typedef struct imc_imv_msg_t imc_imv_msg_t;
+
+#include "tnccs_msg.h"
+
+#include <tnc/tncif.h>
+
+/**
+ * Classs representing the PB-PA message type.
+ */
+struct imc_imv_msg_t {
+
+ /**
+ * TNCCS Message interface
+ */
+ tnccs_msg_t tnccs_msg_interface;
+
+ /**
+ * Get IMC-IMV message type
+ *
+ * @return IMC-IMV message type
+ */
+ TNC_MessageType (*get_msg_type)(imc_imv_msg_t *this);
+
+ /**
+ * Get IMC-IMV message body
+ *
+ * @return IMC-IMV message body
+ */
+ chunk_t (*get_msg_body)(imc_imv_msg_t *this);
+};
+
+/**
+ * Create an IMC-IMV message from XML-encoded message node
+ *
+ * @param node XML-encoded message node
+ * @param errors linked list of TNCCS error messages
+*/
+tnccs_msg_t *imc_imv_msg_create_from_node(xmlNodePtr node, linked_list_t *errors);
+
+/**
+ * Create an IMC-IMV message from parameters
+ *
+ * @param msg_type IMC-IMV message type
+ * @param msg_body IMC-IMV message body
+ */
+tnccs_msg_t *imc_imv_msg_create(TNC_MessageType msg_type, chunk_t msg_body);
+
+#endif /** IMC_IMV_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.c
new file mode 100644
index 000000000..d0df4e7ca
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2006 Mike McCauley (mikem@open.com.au)
+ * 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 "tnccs_error_msg.h"
+
+#include <debug.h>
+
+ENUM(tnccs_error_type_names, TNCCS_ERROR_BATCH_TOO_LONG, TNCCS_ERROR_OTHER,
+ "batch-too-long",
+ "malformed-batch",
+ "invalid-batch-id",
+ "invalid-recipient-type",
+ "internal-error",
+ "other"
+);
+
+typedef struct private_tnccs_error_msg_t private_tnccs_error_msg_t;
+
+/**
+ * Private data of a tnccs_error_msg_t object.
+ *
+ */
+struct private_tnccs_error_msg_t {
+ /**
+ * Public tnccs_error_msg_t interface.
+ */
+ tnccs_error_msg_t public;
+
+ /**
+ * TNCCS message type
+ */
+ tnccs_msg_type_t type;
+
+ /**
+ * XML-encoded message node
+ */
+ xmlNodePtr node;
+
+ /**
+ * Error type
+ */
+ tnccs_error_type_t error_type;
+
+ /**
+ * Error message
+ */
+ char *error_msg;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
+ private_tnccs_error_msg_t *this)
+{
+ return this->type;
+}
+
+METHOD(tnccs_msg_t, get_node, xmlNodePtr,
+ private_tnccs_error_msg_t *this)
+{
+ return this->node;
+}
+
+METHOD(tnccs_msg_t, get_ref, tnccs_msg_t*,
+ private_tnccs_error_msg_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.tnccs_msg_interface;
+}
+
+METHOD(tnccs_msg_t, destroy, void,
+ private_tnccs_error_msg_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->error_msg);
+ free(this);
+ }
+}
+
+METHOD(tnccs_error_msg_t, get_message, char*,
+ private_tnccs_error_msg_t *this, tnccs_error_type_t *type)
+{
+ *type = this->error_type;
+
+ return this->error_msg;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_error_msg_create_from_node(xmlNodePtr node)
+{
+ private_tnccs_error_msg_t *this;
+ xmlChar *error_type_name, *error_msg;
+
+ INIT(this,
+ .public = {
+ .tnccs_msg_interface = {
+ .get_type = _get_type,
+ .get_node = _get_node,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_message = _get_message,
+ },
+ .type = TNCCS_MSG_ERROR,
+ .ref = 1,
+ .node = node,
+ .error_type = TNCCS_ERROR_OTHER,
+ );
+
+ error_type_name = xmlGetProp(node, (const xmlChar*)"type");
+ if (error_type_name)
+ {
+ this->error_type = enum_from_name(tnccs_error_type_names,
+ (char*)error_type_name);
+ if (this->error_type == -1)
+ {
+ this->error_type = TNCCS_ERROR_OTHER;
+ }
+ xmlFree(error_type_name);
+ }
+
+ error_msg = xmlNodeGetContent(node);
+ if (error_msg)
+ {
+ this->error_msg = strdup((char*)error_msg);
+ xmlFree(error_msg);
+ }
+
+ return &this->public.tnccs_msg_interface;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_error_msg_create(tnccs_error_type_t type, char *msg)
+{
+ private_tnccs_error_msg_t *this;
+ xmlNodePtr n, n2;
+
+ INIT(this,
+ .public = {
+ .tnccs_msg_interface = {
+ .get_type = _get_type,
+ .get_node = _get_node,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_message = _get_message,
+ },
+ .type = TNCCS_MSG_ERROR,
+ .ref = 1,
+ .node = xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"),
+ .error_type = type,
+ .error_msg = strdup(msg),
+ );
+
+ DBG1(DBG_TNC, "%s", msg);
+
+ n = xmlNewNode(NULL, BAD_CAST "Type");
+ xmlNodeSetContent(n, BAD_CAST "00000002");
+ xmlAddChild(this->node, n);
+
+ n = xmlNewNode(NULL, BAD_CAST "XML");
+ xmlAddChild(this->node, n);
+
+ n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
+ xmlNewProp(n2, BAD_CAST "type",
+ BAD_CAST enum_to_name(tnccs_error_type_names, type));
+ xmlNodeSetContent(n2, BAD_CAST msg);
+ xmlAddChild(n, n2);
+
+ return &this->public.tnccs_msg_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.h
new file mode 100644
index 000000000..ce2ce9755
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.h
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup tnccs_error_msg tnccs_error_msg
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_ERROR_MSG_H_
+#define TNCCS_ERROR_MSG_H_
+
+typedef enum tnccs_error_type_t tnccs_error_type_t;
+typedef struct tnccs_error_msg_t tnccs_error_msg_t;
+
+#include "tnccs_msg.h"
+
+/**
+ * TNCCS error types as defined in section 8.1.4 of TCG TNC IF-TNCCS v1.2
+ */
+enum tnccs_error_type_t {
+ TNCCS_ERROR_BATCH_TOO_LONG,
+ TNCCS_ERROR_MALFORMED_BATCH,
+ TNCCS_ERROR_INVALID_BATCH_ID,
+ TNCCS_ERROR_INVALID_RECIPIENT_TYPE,
+ TNCCS_ERROR_INTERNAL_ERROR,
+ TNCCS_ERROR_OTHER
+};
+
+/**
+ * enum name for tnccs_error_type_t.
+ */
+extern enum_name_t *tnccs_error_type_names;
+
+/**
+ * Class representing the TNCCS-Error message type
+ */
+struct tnccs_error_msg_t {
+
+ /**
+ * TNCCS Message interface
+ */
+ tnccs_msg_t tnccs_msg_interface;
+
+ /**
+ * Get error message and type
+ *
+ * @param type TNCCS error type
+ * @return arbitrary error message
+ */
+ char* (*get_message)(tnccs_error_msg_t *this, tnccs_error_type_t *type);
+};
+
+/**
+ * Create a TNCCS-Error message from XML-encoded message node
+ *
+ * @param node XML-encoded message node
+ */
+tnccs_msg_t *tnccs_error_msg_create_from_node(xmlNodePtr node);
+
+/**
+ * Create a TNCCS-Error message from parameters
+ *
+ * @param type TNCCS error type
+ * @param msg arbitrary error message
+ */
+tnccs_msg_t *tnccs_error_msg_create(tnccs_error_type_t type, char *msg);
+
+#endif /** TNCCS_ERROR_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_msg.c
new file mode 100644
index 000000000..5a050393a
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_msg.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2006 Mike McCauley (mikem@open.com.au)
+ * 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 "tnccs_msg.h"
+#include "imc_imv_msg.h"
+#include "tnccs_error_msg.h"
+#include "tnccs_preferred_language_msg.h"
+#include "tnccs_reason_strings_msg.h"
+#include "tnccs_recommendation_msg.h"
+#include "tnccs_tncs_contact_info_msg.h"
+
+#include <library.h>
+#include <debug.h>
+
+ENUM(tnccs_msg_type_names, IMC_IMV_MSG, TNCCS_MSG_ROOF,
+ "IMC-IMV",
+ "TNCCS-Recommendation",
+ "TNCCS-Error",
+ "TNCCS-PreferredLanguage",
+ "TNCCS-ReasonStrings",
+ "TNCCS-TNCSContactInfo"
+);
+
+/**
+ * See header
+ */
+tnccs_msg_t* tnccs_msg_create_from_node(xmlNodePtr node, linked_list_t *errors)
+{
+ char *error_msg, buf[BUF_LEN];
+ tnccs_error_type_t error_type = TNCCS_ERROR_MALFORMED_BATCH;
+ tnccs_msg_t *msg;
+ tnccs_msg_type_t type = IMC_IMV_MSG;
+
+ if (streq((char*)node->name, "IMC-IMV-Message"))
+ {
+ DBG2(DBG_TNC, "processing %N message", tnccs_msg_type_names, type);
+ return imc_imv_msg_create_from_node(node, errors);
+ }
+ else if (streq((char*)node->name, "TNCC-TNCS-Message"))
+ {
+ bool found = FALSE;
+ xmlNsPtr ns = node->ns;
+ xmlNodePtr cur = node->xmlChildrenNode;
+ xmlNodePtr xml_msg_node = NULL;
+
+ while (cur)
+ {
+ if (streq((char*)cur->name, "Type") && cur->ns == ns)
+ {
+ xmlChar *content = xmlNodeGetContent(cur);
+
+ type = strtol((char*)content, NULL, 16);
+ xmlFree(content);
+ found = TRUE;
+ }
+ else if (streq((char*)cur->name, "XML") && cur->ns == ns)
+ {
+ xml_msg_node = cur->xmlChildrenNode;
+ }
+ cur = cur->next;
+ }
+ if (!found)
+ {
+ error_msg = "Type is missing in TNCC-TNCS-Message";
+ goto fatal;
+ }
+ if (!xml_msg_node)
+ {
+ error_msg = "XML node is missing in TNCC-TNCS-Message";
+ goto fatal;
+ }
+ cur = xml_msg_node;
+
+ /* skip empty and blank nodes */
+ while (cur && xmlIsBlankNode(cur))
+ {
+ cur = cur->next;
+ }
+ if (!cur)
+ {
+ error_msg = "XML node is empty";
+ goto fatal;
+ }
+
+ /* check if TNCCS message type and node name agree */
+ if (type >= TNCCS_MSG_RECOMMENDATION && type <= TNCCS_MSG_ROOF)
+ {
+ DBG2(DBG_TNC, "processing %N message", tnccs_msg_type_names, type);
+ if (cur->ns != ns)
+ {
+ error_msg = "node is not in the TNCCS message namespace";
+ goto fatal;
+ }
+ if (type != enum_from_name(tnccs_msg_type_names, (char*)cur->name))
+ {
+ error_msg = buf;
+ snprintf(buf, BUF_LEN, "expected '%N' node but was '%s'",
+ tnccs_msg_type_names, type, (char*)cur->name);
+ goto fatal;
+ }
+ }
+
+ switch (type)
+ {
+ case TNCCS_MSG_RECOMMENDATION:
+ return tnccs_recommendation_msg_create_from_node(cur, errors);
+ case TNCCS_MSG_ERROR:
+ return tnccs_error_msg_create_from_node(cur);
+ case TNCCS_MSG_PREFERRED_LANGUAGE:
+ return tnccs_preferred_language_msg_create_from_node(cur, errors);
+ case TNCCS_MSG_REASON_STRINGS:
+ return tnccs_reason_strings_msg_create_from_node(cur, errors);
+ case TNCCS_MSG_TNCS_CONTACT_INFO:
+ return tnccs_tncs_contact_info_msg_create_from_node(cur, errors);
+ default:
+ DBG1(DBG_TNC, "ignoring TNCC-TNCS-Message with type %d", type);
+ return NULL;
+ }
+ }
+ DBG1(DBG_TNC, "ignoring unknown message node '%s'", (char*)node->name);
+ return NULL;
+
+fatal:
+ msg = tnccs_error_msg_create(error_type, error_msg);
+ errors->insert_last(errors, msg);
+ return NULL;
+}
+
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_msg.h
new file mode 100644
index 000000000..e0b54449a
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_msg.h
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup tnccs_msg tnccs_msg
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_MSG_H_
+#define TNCCS_MSG_H_
+
+typedef enum tnccs_msg_type_t tnccs_msg_type_t;
+typedef struct tnccs_msg_t tnccs_msg_t;
+
+#include <library.h>
+#include <utils/linked_list.h>
+#include <libxml/parser.h>
+
+/**
+ * TNCC-TNCS messages as defined in section 2.8.5 of TCG TNC IF-TNCCS v1.2
+ */
+enum tnccs_msg_type_t {
+ IMC_IMV_MSG = 0,
+ TNCCS_MSG_RECOMMENDATION = 1,
+ TNCCS_MSG_ERROR = 2,
+ TNCCS_MSG_PREFERRED_LANGUAGE = 3,
+ TNCCS_MSG_REASON_STRINGS = 4,
+ TNCCS_MSG_TNCS_CONTACT_INFO = 5,
+ TNCCS_MSG_ROOF = 5
+};
+
+/**
+ * enum name for tnccs_msg_type_t.
+ */
+extern enum_name_t *tnccs_msg_type_names;
+
+/**
+ * Generic interface for all TNCCS message types.
+ *
+ * To handle all messages in a generic way, this interface
+ * must be implemented by each message type.
+ */
+struct tnccs_msg_t {
+
+ /**
+ * Get the TNCCS Message Type
+ *
+ * @return TNCCS Message Type
+ */
+ tnccs_msg_type_t (*get_type)(tnccs_msg_t *this);
+
+ /**
+ * Get the XML-encoded Message Node
+ *
+ * @return Message Node
+ */
+ xmlNodePtr (*get_node)(tnccs_msg_t *this);
+
+ /**
+ * Process the TNCCS Message
+ *
+ * @return return processing status
+ */
+ status_t (*process)(tnccs_msg_t *this);
+
+ /**
+ * Get a new reference to the message.
+ *
+ * @return this, with an increased refcount
+ */
+ tnccs_msg_t* (*get_ref)(tnccs_msg_t *this);
+
+ /**
+ * Destroys a tnccs_msg_t object.
+ */
+ void (*destroy)(tnccs_msg_t *this);
+};
+
+/**
+ * Create a pre-processed TNCCS message
+ *
+ * Useful for the parser which wants a generic constructor for all
+ * tnccs_msg_t types.
+ *
+ * @param node TNCCS message node
+ * @param errors linked list of TNCCS error messages
+ */
+tnccs_msg_t* tnccs_msg_create_from_node(xmlNodePtr node, linked_list_t *errors);
+
+#endif /** TNCCS_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.c
new file mode 100644
index 000000000..fd85350b5
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2006 Mike McCauley (mikem@open.com.au)
+ * 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 "tnccs_preferred_language_msg.h"
+
+#include <debug.h>
+
+typedef struct private_tnccs_preferred_language_msg_t private_tnccs_preferred_language_msg_t;
+
+/**
+ * Private data of a tnccs_preferred_language_msg_t object.
+ *
+ */
+struct private_tnccs_preferred_language_msg_t {
+ /**
+ * Public tnccs_preferred_language_msg_t interface.
+ */
+ tnccs_preferred_language_msg_t public;
+
+ /**
+ * TNCCS message type
+ */
+ tnccs_msg_type_t type;
+
+ /**
+ * XML-encoded message node
+ */
+ xmlNodePtr node;
+
+ /**
+ * Preferred language
+ */
+ char *preferred_language;
+};
+
+METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
+ private_tnccs_preferred_language_msg_t *this)
+{
+ return this->type;
+}
+
+METHOD(tnccs_msg_t, get_node, xmlNodePtr,
+ private_tnccs_preferred_language_msg_t *this)
+{
+ return this->node;
+}
+
+METHOD(tnccs_msg_t, destroy, void,
+ private_tnccs_preferred_language_msg_t *this)
+{
+ free(this->preferred_language);
+ free(this);
+}
+
+METHOD(tnccs_preferred_language_msg_t, get_preferred_language, char*,
+ private_tnccs_preferred_language_msg_t *this)
+{
+ return this->preferred_language;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_preferred_language_msg_create_from_node(xmlNodePtr node,
+ linked_list_t *errors)
+{
+ private_tnccs_preferred_language_msg_t *this;
+ xmlChar *language;
+
+ INIT(this,
+ .public = {
+ .tnccs_msg_interface = {
+ .get_type = _get_type,
+ .get_node = _get_node,
+ .destroy = _destroy,
+ },
+ .get_preferred_language = _get_preferred_language,
+ },
+ .type = TNCCS_MSG_PREFERRED_LANGUAGE,
+ .node = node,
+ );
+
+ language = xmlNodeGetContent(node);
+ this->preferred_language = strdup((char*)language);
+ xmlFree(language);
+
+ return &this->public.tnccs_msg_interface;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_preferred_language_msg_create(char *language)
+{
+ private_tnccs_preferred_language_msg_t *this;
+ xmlNodePtr n, n2;
+
+ INIT(this,
+ .public = {
+ .tnccs_msg_interface = {
+ .get_type = _get_type,
+ .get_node = _get_node,
+ .destroy = _destroy,
+ },
+ .get_preferred_language = _get_preferred_language,
+ },
+ .type = TNCCS_MSG_PREFERRED_LANGUAGE,
+ .node = xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"),
+ .preferred_language = strdup(language),
+ );
+
+ /* add the message type number in hex */
+ n = xmlNewNode(NULL, BAD_CAST "Type");
+ xmlNodeSetContent(n, BAD_CAST "00000003");
+ xmlAddChild(this->node, n);
+
+ n = xmlNewNode(NULL, BAD_CAST "XML");
+ xmlAddChild(this->node, n);
+
+ n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
+ xmlNodeSetContent(n2, BAD_CAST language);
+ xmlAddChild(n, n2);
+
+ return &this->public.tnccs_msg_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h
new file mode 100644
index 000000000..d301ab2bb
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup tnccs_preferred_language_msg tnccs_preferred_language_msg
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_PREFERRED_LANGUAGE_MSG_H_
+#define TNCCS_PREFERRED_LANGUAGE_MSG_H_
+
+typedef struct tnccs_preferred_language_msg_t tnccs_preferred_language_msg_t;
+
+#include "tnccs_msg.h"
+
+#include <tnc/tncif.h>
+
+/**
+ * Class representing the TNCCS-PreferredLanguage message type
+ */
+struct tnccs_preferred_language_msg_t {
+
+ /**
+ * TNCCS Message interface
+ */
+ tnccs_msg_t tnccs_msg_interface;
+
+ /**
+ * Get preferred language string
+ *
+ * @return preferred language string
+ */
+ char* (*get_preferred_language)(tnccs_preferred_language_msg_t *this);
+};
+
+/**
+ * Create a TNCCS-PreferredLanguage message from XML-encoded message node
+ *
+ * @param node XML-encoded message node
+ * @param errors linked list of TNCCS error messages
+ */
+tnccs_msg_t *tnccs_preferred_language_msg_create_from_node(xmlNodePtr node,
+ linked_list_t *errors);
+
+/**
+ * Create a TNCCS-PreferredLanguage message from parameters
+ *
+ * @param language preferred language string
+ */
+tnccs_msg_t *tnccs_preferred_language_msg_create(char *language);
+
+#endif /** TNCCS_PREFERRED_LANGUAGE_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c
new file mode 100644
index 000000000..d4b5d9bf9
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2006 Mike McCauley (mikem@open.com.au)
+ * 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 "tnccs_reason_strings_msg.h"
+
+#include <debug.h>
+
+typedef struct private_tnccs_reason_strings_msg_t private_tnccs_reason_strings_msg_t;
+
+/**
+ * Private data of a tnccs_reason_strings_msg_t object.
+ *
+ */
+struct private_tnccs_reason_strings_msg_t {
+ /**
+ * Public tnccs_reason_strings_msg_t interface.
+ */
+ tnccs_reason_strings_msg_t public;
+
+ /**
+ * TNCCS message type
+ */
+ tnccs_msg_type_t type;
+
+ /**
+ * XML-encoded message node
+ */
+ xmlNodePtr node;
+
+ /**
+ * Reason String
+ */
+ chunk_t reason;
+
+ /**
+ * Reason Language
+ */
+ chunk_t language;
+};
+
+METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
+ private_tnccs_reason_strings_msg_t *this)
+{
+ return this->type;
+}
+
+METHOD(tnccs_msg_t, get_node, xmlNodePtr,
+ private_tnccs_reason_strings_msg_t *this)
+{
+ return this->node;
+}
+
+METHOD(tnccs_msg_t, destroy, void,
+ private_tnccs_reason_strings_msg_t *this)
+{
+ free(this->reason.ptr);
+ free(this->language.ptr);
+ free(this);
+}
+
+METHOD(tnccs_reason_strings_msg_t, get_reason, chunk_t,
+ private_tnccs_reason_strings_msg_t *this, chunk_t *language)
+{
+ *language = this->language;
+
+ return this->reason;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node,
+ linked_list_t *errors)
+{
+ private_tnccs_reason_strings_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .tnccs_msg_interface = {
+ .get_type = _get_type,
+ .get_node = _get_node,
+ .destroy = _destroy,
+ },
+ .get_reason = _get_reason,
+ },
+ .type = TNCCS_MSG_REASON_STRINGS,
+ .node = node,
+ );
+
+ return &this->public.tnccs_msg_interface;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_reason_strings_msg_create(chunk_t reason, chunk_t language)
+{
+ private_tnccs_reason_strings_msg_t *this;
+ xmlNodePtr n, n2, n3;
+
+ INIT(this,
+ .public = {
+ .tnccs_msg_interface = {
+ .get_type = _get_type,
+ .get_node = _get_node,
+ .destroy = _destroy,
+ },
+ .get_reason = _get_reason,
+ },
+ .type = TNCCS_MSG_REASON_STRINGS,
+ .node = xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"),
+ .reason = chunk_create_clone(malloc(reason.len + 1), reason),
+ .language = chunk_create_clone(malloc(language.len + 1), language),
+ );
+
+ /* add NULL termination for XML string representation */
+ this->reason.ptr[this->reason.len] = '\0';
+ this->language.ptr[this->language.len] = '\0';
+
+ /* add the message type number in hex */
+ n = xmlNewNode(NULL, BAD_CAST "Type");
+ xmlNodeSetContent(n, BAD_CAST "00000004");
+ xmlAddChild(this->node, n);
+
+ n = xmlNewNode(NULL, BAD_CAST "XML");
+ xmlAddChild(this->node, n);
+
+ n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
+
+ /* could add multiple reasons here, if we had them */
+ n3 = xmlNewNode(NULL, BAD_CAST "ReasonString");
+ xmlNewProp(n3, BAD_CAST "xml:lang", BAD_CAST this->language.ptr);
+ xmlNodeSetContent(n3, BAD_CAST this->reason.ptr);
+ xmlAddChild(n2, n3);
+
+ return &this->public.tnccs_msg_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.h
new file mode 100644
index 000000000..0046a5789
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.h
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup tnccs_reason_strings_msg tnccs_reason_strings_msg
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_REASON_STRINGS_MSG_H_
+#define TNCCS_REASON_STRINGS_MSG_H_
+
+typedef struct tnccs_reason_strings_msg_t tnccs_reason_strings_msg_t;
+
+#include "tnccs_msg.h"
+
+/**
+ * Class representing the TNCCS-ReasonStrings message type
+ */
+struct tnccs_reason_strings_msg_t {
+
+ /**
+ * TNCCS Message interface
+ */
+ tnccs_msg_t tnccs_msg_interface;
+
+ /**
+ * Get reason string and language
+ *
+ * @param language reason language
+ * @return reason string
+ */
+ chunk_t (*get_reason)(tnccs_reason_strings_msg_t *this, chunk_t *language);
+};
+
+/**
+ * Create a TNCCS-ReasonStrings message from XML-encoded message node
+ *
+ * @param node XML-encoded message node
+ * @param errors linked list of TNCCS error messages
+ */
+tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node,
+ linked_list_t *errors);
+
+/**
+ * Create a TNCCS-ReasonStrings message from parameters
+ *
+ * @param reason reason string
+ * @param language reason language
+ */
+tnccs_msg_t *tnccs_reason_strings_msg_create(chunk_t reason, chunk_t language);
+
+#endif /** TNCCS_REASON_STRINGS_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c
new file mode 100644
index 000000000..adc7b54b9
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2006 Mike McCauley (mikem@open.com.au)
+ * 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 "tnccs_recommendation_msg.h"
+#include "tnccs_error_msg.h"
+
+#include <debug.h>
+
+typedef struct private_tnccs_recommendation_msg_t private_tnccs_recommendation_msg_t;
+
+/**
+ * Private data of a tnccs_recommendation_msg_t object.
+ *
+ */
+struct private_tnccs_recommendation_msg_t {
+ /**
+ * Public tnccs_recommendation_msg_t interface.
+ */
+ tnccs_recommendation_msg_t public;
+
+ /**
+ * TNCCS message type
+ */
+ tnccs_msg_type_t type;
+
+ /**
+ * XML-encoded message node
+ */
+ xmlNodePtr node;
+
+ /**
+ * Action Recommendation
+ */
+ TNC_IMV_Action_Recommendation rec;
+};
+
+METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
+ private_tnccs_recommendation_msg_t *this)
+{
+ return this->type;
+}
+
+METHOD(tnccs_msg_t, get_node, xmlNodePtr,
+ private_tnccs_recommendation_msg_t *this)
+{
+ return this->node;
+}
+
+METHOD(tnccs_msg_t, destroy, void,
+ private_tnccs_recommendation_msg_t *this)
+{
+ free(this);
+}
+
+METHOD(tnccs_recommendation_msg_t, get_recommendation, TNC_IMV_Action_Recommendation,
+ private_tnccs_recommendation_msg_t *this)
+{
+ return this->rec;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_recommendation_msg_create_from_node(xmlNodePtr node,
+ linked_list_t *errors)
+{
+ private_tnccs_recommendation_msg_t *this;
+ xmlChar *rec_string;
+ char *error_msg, buf[BUF_LEN];
+ tnccs_error_type_t error_type = TNCCS_ERROR_MALFORMED_BATCH;
+ tnccs_msg_t *msg;
+
+ INIT(this,
+ .public = {
+ .tnccs_msg_interface = {
+ .get_type = _get_type,
+ .get_node = _get_node,
+ .destroy = _destroy,
+ },
+ .get_recommendation = _get_recommendation,
+ },
+ .type = TNCCS_MSG_RECOMMENDATION,
+ .node = node,
+ );
+
+ rec_string = xmlGetProp(node, (const xmlChar*)"type");
+ if (!rec_string)
+ {
+ error_msg = "type property in TNCCS-Recommendation is missing";
+ goto fatal;
+ }
+ else if (streq((char*)rec_string, "allow"))
+ {
+ this->rec = TNC_IMV_ACTION_RECOMMENDATION_ALLOW;
+ }
+ else if (streq((char*)rec_string, "isolate"))
+ {
+ this->rec = TNC_IMV_ACTION_RECOMMENDATION_ISOLATE;
+ }
+ else if (streq((char*)rec_string, "none"))
+ {
+ this->rec = TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS;
+ }
+ else
+ {
+ error_msg = buf;
+ snprintf(buf, BUF_LEN, "unsupported type property value '%s' "
+ "in TNCCS-Recommendation", rec_string);
+ xmlFree(rec_string);
+ goto fatal;
+ }
+ xmlFree(rec_string);
+
+ return &this->public.tnccs_msg_interface;
+
+fatal:
+ msg = tnccs_error_msg_create(error_type, error_msg);
+ errors->insert_last(errors, msg);
+ _destroy(this);
+ return NULL;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_recommendation_msg_create(TNC_IMV_Action_Recommendation rec)
+{
+ private_tnccs_recommendation_msg_t *this;
+ xmlNodePtr n, n2;
+ char *rec_string;
+
+ INIT(this,
+ .public = {
+ .tnccs_msg_interface = {
+ .get_type = _get_type,
+ .get_node = _get_node,
+ .destroy = _destroy,
+ },
+ .get_recommendation = _get_recommendation,
+ },
+ .type = TNCCS_MSG_RECOMMENDATION,
+ .node = xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"),
+ .rec = rec,
+ );
+
+ /* add the message type number in hex */
+ n = xmlNewNode(NULL, BAD_CAST "Type");
+ xmlNodeSetContent(n, BAD_CAST "00000001");
+ xmlAddChild(this->node, n);
+
+ n = xmlNewNode(NULL, BAD_CAST "XML");
+ xmlAddChild(this->node, n);
+
+ switch (rec)
+ {
+ case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
+ rec_string = "allow";
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
+ rec_string = "isolate";
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
+ case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
+ default:
+ rec_string = "none";
+ }
+
+ n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
+ xmlNewProp(n2, BAD_CAST "type", BAD_CAST rec_string);
+ xmlNodeSetContent(n2, "");
+ xmlAddChild(n, n2);
+
+ return &this->public.tnccs_msg_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h
new file mode 100644
index 000000000..685049e95
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup tnccs_recommendation_msg tnccs_recommendation_msg
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_RECOMMENDATION_MSG_H_
+#define TNCCS_RECOMMENDATION_MSG_H_
+
+typedef struct tnccs_recommendation_msg_t tnccs_recommendation_msg_t;
+
+#include "tnccs_msg.h"
+
+#include <tnc/tncifimv.h>
+
+/**
+ * Class representing the TNCCS-Recommendation message type
+ */
+struct tnccs_recommendation_msg_t {
+
+ /**
+ * TNCCS Message interface
+ */
+ tnccs_msg_t tnccs_msg_interface;
+
+ /**
+ * Get Action Recommendation
+ *
+ * @return Action Recommendation
+ */
+ TNC_IMV_Action_Recommendation (*get_recommendation)(tnccs_recommendation_msg_t *this);
+};
+
+/**
+ * Create a TNCCS-Recommendation message from XML-encoded message node
+ *
+ * @param node XML-encoded message node
+ * @param errors linked list of TNCCS error messages
+ */
+tnccs_msg_t *tnccs_recommendation_msg_create_from_node(xmlNodePtr node,
+ linked_list_t *errors);
+
+/**
+ * Create a TNCCS-Recommendation message from parameters
+ *
+ * @param rec Action Recommendation
+ */
+tnccs_msg_t *tnccs_recommendation_msg_create(TNC_IMV_Action_Recommendation rec);
+
+#endif /** TNCCS_RECOMMENDATION_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.c
new file mode 100644
index 000000000..b8aac30fa
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.c
@@ -0,0 +1,118 @@
+/*
+ * 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 "tnccs_tncs_contact_info_msg.h"
+
+#include <debug.h>
+
+typedef struct private_tnccs_tncs_contact_info_msg_t private_tnccs_tncs_contact_info_msg_t;
+
+/**
+ * Private data of a tnccs_tncs_contact_info_msg_t object.
+ *
+ */
+struct private_tnccs_tncs_contact_info_msg_t {
+ /**
+ * Public tnccs_tncs_contact_info_msg_t interface.
+ */
+ tnccs_tncs_contact_info_msg_t public;
+
+ /**
+ * TNCCS message type
+ */
+ tnccs_msg_type_t type;
+
+ /**
+ * XML-encoded message node
+ */
+ xmlNodePtr node;
+};
+
+METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
+ private_tnccs_tncs_contact_info_msg_t *this)
+{
+ return this->type;
+}
+
+METHOD(tnccs_msg_t, get_node, xmlNodePtr,
+ private_tnccs_tncs_contact_info_msg_t *this)
+{
+ return this->node;
+}
+
+METHOD(tnccs_msg_t, destroy, void,
+ private_tnccs_tncs_contact_info_msg_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_tncs_contact_info_msg_create_from_node(xmlNodePtr node,
+ linked_list_t *errors)
+{
+ private_tnccs_tncs_contact_info_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .tnccs_msg_interface = {
+ .get_type = _get_type,
+ .get_node = _get_node,
+ .destroy = _destroy,
+ },
+ },
+ .type = TNCCS_MSG_TNCS_CONTACT_INFO,
+ .node = node,
+ );
+
+ return &this->public.tnccs_msg_interface;
+}
+
+/**
+ * See header
+ */
+tnccs_msg_t *tnccs_tncs_contact_info_msg_create(void)
+{
+ private_tnccs_tncs_contact_info_msg_t *this;
+ xmlNodePtr n /*, n2 */;
+
+ INIT(this,
+ .public = {
+ .tnccs_msg_interface = {
+ .get_type = _get_type,
+ .get_node = _get_node,
+ .destroy = _destroy,
+ },
+ },
+ .type = TNCCS_MSG_TNCS_CONTACT_INFO,
+ .node = xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"),
+ );
+
+ /* add the message type number in hex */
+ n = xmlNewNode(NULL, BAD_CAST "Type");
+ xmlNodeSetContent(n, BAD_CAST "00000005");
+ xmlAddChild(this->node, n);
+
+ n = xmlNewNode(NULL, BAD_CAST "XML");
+ xmlAddChild(this->node, n);
+
+/* TODO
+ n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
+ xmlNodeSetContent(n2, BAD_CAST language);
+ xmlAddChild(n, n2);
+*/
+
+ return &this->public.tnccs_msg_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.h
new file mode 100644
index 000000000..8ed210a57
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup tnccs_tncs_contact_info_msg tnccs_tncs_contact_info_msg
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_TNCS_CONTACT_INFO_MSG_H_
+#define TNCCS_TNCS_CONTACT_INFO_MSG_H_
+
+typedef struct tnccs_tncs_contact_info_msg_t tnccs_tncs_contact_info_msg_t;
+
+#include "tnccs_msg.h"
+
+/**
+ * Class representing the TNCCS-TNCSContactInfo message type
+ */
+struct tnccs_tncs_contact_info_msg_t {
+
+ /**
+ * TNCCS Message interface
+ */
+ tnccs_msg_t tnccs_msg_interface;
+};
+
+/**
+ * Create a TNCCS-TNCSContactInfo message from XML-encoded message node
+ *
+ * @param node XML-encoded message node
+ * @param errors linked list of TNCCS error messages
+ */
+tnccs_msg_t *tnccs_tncs_contact_info_msg_create_from_node(xmlNodePtr node,
+ linked_list_t *errors);
+
+/**
+ * Create a TNCCS-TNCSContactInfo message from parameters
+ *
+ */
+tnccs_msg_t *tnccs_tncs_contact_info_msg_create(void);
+
+#endif /** TNCCS_TNCS_CONTACT_INFO_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/tnccs_11.c b/src/libcharon/plugins/tnccs_11/tnccs_11.c
index 704bf64ed..2104bf401 100644
--- a/src/libcharon/plugins/tnccs_11/tnccs_11.c
+++ b/src/libcharon/plugins/tnccs_11/tnccs_11.c
@@ -14,81 +14,20 @@
*/
#include "tnccs_11.h"
-
-#include <libtnctncc.h>
-#include <libtnctncs.h>
+#include "batch/tnccs_batch.h"
+#include "messages/tnccs_msg.h"
+#include "messages/imc_imv_msg.h"
+#include "messages/tnccs_error_msg.h"
+#include "messages/tnccs_preferred_language_msg.h"
+#include "messages/tnccs_reason_strings_msg.h"
+#include "messages/tnccs_recommendation_msg.h"
#include <daemon.h>
#include <debug.h>
-
-#define TNC_SEND_BUFFER_SIZE 32
-
-static chunk_t tnc_send_buffer[TNC_SEND_BUFFER_SIZE];
-
-/**
- * Buffers TNCCS batch to be sent (TODO make the buffer scalable)
- */
-static TNC_Result buffer_batch(u_int32_t id, const char *data, size_t len)
-{
- if (id >= TNC_SEND_BUFFER_SIZE)
- {
- DBG1(DBG_TNC, "TNCCS Batch for Connection ID %u cannot be stored in "
- "send buffer with size %d", id, TNC_SEND_BUFFER_SIZE);
- return TNC_RESULT_FATAL;
- }
- if (tnc_send_buffer[id].ptr)
- {
- DBG1(DBG_TNC, "send buffer slot for Connection ID %u is already "
- "occupied", id);
- return TNC_RESULT_FATAL;
- }
- tnc_send_buffer[id] = chunk_alloc(len);
- memcpy(tnc_send_buffer[id].ptr, data, len);
-
- return TNC_RESULT_SUCCESS;
-}
-
-/**
- * Retrieves TNCCS batch to be sent
- */
-static bool retrieve_batch(u_int32_t id, chunk_t *batch)
-{
- if (id >= TNC_SEND_BUFFER_SIZE)
- {
- DBG1(DBG_TNC, "TNCCS Batch for Connection ID %u cannot be retrieved from "
- "send buffer with size %d", id, TNC_SEND_BUFFER_SIZE);
- return FALSE;
- }
-
- *batch = tnc_send_buffer[id];
- return TRUE;
-}
-
-/**
- * Frees TNCCS batch that was sent
- */
-static void free_batch(u_int32_t id)
-{
- if (id < TNC_SEND_BUFFER_SIZE)
- {
- chunk_free(&tnc_send_buffer[id]);
- }
-}
-
-/**
- * Define callback functions called by the libtnc library
- */
-TNC_Result TNC_TNCC_SendBatch(libtnc_tncc_connection* conn,
- const char* messageBuffer, size_t messageLength)
-{
- return buffer_batch(conn->connectionID, messageBuffer, messageLength);
-}
-
-TNC_Result TNC_TNCS_SendBatch(libtnc_tncs_connection* conn,
- const char* messageBuffer, size_t messageLength)
-{
- return buffer_batch(conn->connectionID, messageBuffer, messageLength);
-}
+#include <threading/mutex.h>
+#include <tnc/tncif.h>
+#include <tnc/tncifimv.h>
+#include <tnc/tnccs/tnccs.h>
typedef struct private_tnccs_11_t private_tnccs_11_t;
@@ -108,116 +47,372 @@ struct private_tnccs_11_t {
bool is_server;
/**
- * TNCC Connection to IMCs
+ * Connection ID assigned to this TNCCS connection
+ */
+ TNC_ConnectionID connection_id;
+
+ /**
+ * Last TNCCS batch ID
+ */
+ int batch_id;
+
+ /**
+ * TNCCS batch being constructed
+ */
+ tnccs_batch_t *batch;
+
+ /**
+ * Mutex locking the batch in construction
*/
- libtnc_tncc_connection* tncc_connection;
+ mutex_t *mutex;
/**
- * TNCS Connection to IMVs
+ * Flag set while processing
*/
- libtnc_tncs_connection* tncs_connection;
+ bool fatal_error;
+
+ /**
+ * Flag set by TNCCS-Recommendation message
+ */
+ bool delete_state;
+
+ /**
+ * Flag set by IMC/IMV RequestHandshakeRetry() function
+ */
+ bool request_handshake_retry;
+
+ /**
+ * Set of IMV recommendations (TNC Server only)
+ */
+ recommendations_t *recs;
};
-METHOD(tls_t, process, status_t,
- private_tnccs_11_t *this, void *buf, size_t buflen)
+METHOD(tnccs_t, send_msg, void,
+ private_tnccs_11_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_MessageType msg_type)
{
- u_int32_t conn_id;
+ tnccs_msg_t *tnccs_msg;
- if (this->is_server && !this->tncs_connection)
+ tnccs_msg = imc_imv_msg_create(msg_type, chunk_create(msg, msg_len));
+
+ /* adding an IMC-IMV Message to TNCCS batch */
+ this->mutex->lock(this->mutex);
+ if (!this->batch)
{
- this->tncs_connection = libtnc_tncs_CreateConnection(NULL);
- if (!this->tncs_connection)
+ this->batch = tnccs_batch_create(this->is_server, ++this->batch_id);
+ }
+ this->batch->add_msg(this->batch, tnccs_msg);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Handle a single TNCCS message according to its type
+ */
+static void handle_message(private_tnccs_11_t *this, tnccs_msg_t *msg)
+{
+ switch (msg->get_type(msg))
+ {
+ case IMC_IMV_MSG:
{
- DBG1(DBG_TNC, "TNCS CreateConnection failed");
- return FAILED;
+ imc_imv_msg_t *imc_imv_msg;
+ TNC_MessageType msg_type;
+ chunk_t msg_body;
+
+ imc_imv_msg = (imc_imv_msg_t*)msg;
+ msg_type = imc_imv_msg->get_msg_type(imc_imv_msg);
+ msg_body = imc_imv_msg->get_msg_body(imc_imv_msg);
+
+ DBG2(DBG_TNC, "handling IMC_IMV message type 0x%08x", msg_type);
+
+ if (this->is_server)
+ {
+ charon->imvs->receive_message(charon->imvs,
+ this->connection_id, msg_body.ptr, msg_body.len, msg_type);
+ }
+ else
+ {
+ charon->imcs->receive_message(charon->imcs,
+ this->connection_id, msg_body.ptr, msg_body.len,msg_type);
+ }
+ break;
+ }
+ case TNCCS_MSG_RECOMMENDATION:
+ {
+ tnccs_recommendation_msg_t *rec_msg;
+ TNC_IMV_Action_Recommendation rec;
+ TNC_ConnectionState state = TNC_CONNECTION_STATE_ACCESS_NONE;
+
+ rec_msg = (tnccs_recommendation_msg_t*)msg;
+ rec = rec_msg->get_recommendation(rec_msg);
+ if (this->is_server)
+ {
+ DBG1(DBG_TNC, "ignoring NCCS-Recommendation message from "
+ " TNC client");
+ break;
+ }
+ DBG1(DBG_TNC, "TNC recommendation is '%N'",
+ TNC_IMV_Action_Recommendation_names, rec);
+ switch (rec)
+ {
+ case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
+ state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
+ state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
+ default:
+ state = TNC_CONNECTION_STATE_ACCESS_NONE;
+ }
+ charon->imcs->notify_connection_change(charon->imcs,
+ this->connection_id, state);
+ this->delete_state = TRUE;
+ break;
+ }
+ case TNCCS_MSG_ERROR:
+ {
+ tnccs_error_msg_t *err_msg;
+ tnccs_error_type_t error_type;
+ char *error_msg;
+
+ err_msg = (tnccs_error_msg_t*)msg;
+ error_msg = err_msg->get_message(err_msg, &error_type);
+ DBG1(DBG_TNC, "received '%N' TNCCS-Error: %s",
+ tnccs_error_type_names, error_type, error_msg);
+
+ /* we assume that all errors are fatal */
+ this->fatal_error = TRUE;
+ break;
}
- DBG1(DBG_TNC, "assigned TNCS Connection ID %u",
- this->tncs_connection->connectionID);
- if (libtnc_tncs_BeginSession(this->tncs_connection) != TNC_RESULT_SUCCESS)
+ case TNCCS_MSG_PREFERRED_LANGUAGE:
+ {
+ tnccs_preferred_language_msg_t *lang_msg;
+ char *lang;
+
+ lang_msg = (tnccs_preferred_language_msg_t*)msg;
+ lang = lang_msg->get_preferred_language(lang_msg);
+
+ DBG2(DBG_TNC, "setting preferred language to '%s'", lang);
+ this->recs->set_preferred_language(this->recs,
+ chunk_create(lang, strlen(lang)));
+ break;
+ }
+ case TNCCS_MSG_REASON_STRINGS:
+ {
+ tnccs_reason_strings_msg_t *reason_msg;
+ chunk_t reason_string, reason_lang;
+
+ reason_msg = (tnccs_reason_strings_msg_t*)msg;
+ reason_string = reason_msg->get_reason(reason_msg, &reason_lang);
+ DBG2(DBG_TNC, "reason string is '%.*s", reason_string.len,
+ reason_string.ptr);
+ DBG2(DBG_TNC, "reason language is '%.*s", reason_lang.len,
+ reason_lang.ptr);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+METHOD(tls_t, process, status_t,
+ private_tnccs_11_t *this, void *buf, size_t buflen)
+{
+ chunk_t data;
+ tnccs_batch_t *batch;
+ tnccs_msg_t *msg;
+ enumerator_t *enumerator;
+ status_t status;
+
+ if (this->is_server && !this->connection_id)
+ {
+ this->connection_id = charon->tnccs->create_connection(charon->tnccs,
+ (tnccs_t*)this, _send_msg,
+ &this->request_handshake_retry, &this->recs);
+ if (!this->connection_id)
{
- DBG1(DBG_TNC, "TNCS BeginSession failed");
return FAILED;
}
+ charon->imvs->notify_connection_change(charon->imvs,
+ this->connection_id, TNC_CONNECTION_STATE_CREATE);
}
- conn_id = this->is_server ? this->tncs_connection->connectionID
- : this->tncc_connection->connectionID;
+ data = chunk_create(buf, buflen);
DBG1(DBG_TNC, "received TNCCS Batch (%u bytes) for Connection ID %u",
- buflen, conn_id);
- DBG3(DBG_TNC, "%.*s", buflen, buf);
+ data.len, this->connection_id);
+ DBG3(DBG_TNC, "%.*s", data.len, data.ptr);
+ batch = tnccs_batch_create_from_data(this->is_server, ++this->batch_id, data);
+ status = batch->process(batch);
- if (this->is_server)
+ if (status == FAILED)
{
- if (libtnc_tncs_ReceiveBatch(this->tncs_connection, buf, buflen) !=
- TNC_RESULT_SUCCESS)
+ this->fatal_error = TRUE;
+ this->mutex->lock(this->mutex);
+ if (this->batch)
{
- DBG1(DBG_TNC, "TNCS ReceiveBatch failed");
- return FAILED;
+ DBG1(DBG_TNC, "cancelling TNCCS batch");
+ this->batch->destroy(this->batch);
+ this->batch_id--;
+ }
+ this->batch = tnccs_batch_create(this->is_server, ++this->batch_id);
+
+ /* add error messages to outbound batch */
+ enumerator = batch->create_error_enumerator(batch);
+ while (enumerator->enumerate(enumerator, &msg))
+ {
+ this->batch->add_msg(this->batch, msg->get_ref(msg));
}
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
}
else
{
- if (libtnc_tncc_ReceiveBatch(this->tncc_connection, buf, buflen) !=
- TNC_RESULT_SUCCESS)
+ enumerator = batch->create_msg_enumerator(batch);
+ while (enumerator->enumerate(enumerator, &msg))
{
- DBG1(DBG_TNC, "TNCC ReceiveBatch failed");
+ handle_message(this, msg);
+ }
+ enumerator->destroy(enumerator);
+
+ /* received any TNCCS-Error messages */
+ if (this->fatal_error)
+ {
+ DBG1(DBG_TNC, "a fatal TNCCS-Error occurred, terminating connection");
+ batch->destroy(batch);
return FAILED;
}
+
+ if (this->is_server)
+ {
+ charon->imvs->batch_ending(charon->imvs, this->connection_id);
+ }
+ else
+ {
+ charon->imcs->batch_ending(charon->imcs, this->connection_id);
+ }
}
+ batch->destroy(batch);
+
return NEED_MORE;
}
-METHOD(tls_t, build, status_t,
- private_tnccs_11_t *this, void *buf, size_t *buflen, size_t *msglen)
+/**
+ * Add a recommendation message if a final recommendation is available
+ */
+static void check_and_build_recommendation(private_tnccs_11_t *this)
{
- chunk_t batch;
- u_int32_t conn_id;
- size_t len;
+ TNC_IMV_Action_Recommendation rec;
+ TNC_IMV_Evaluation_Result eval;
+ TNC_IMVID id;
+ chunk_t reason, language;
+ enumerator_t *enumerator;
+ tnccs_msg_t *msg;
- if (!this->is_server && !this->tncc_connection)
+ if (!this->recs->have_recommendation(this->recs, &rec, &eval))
+ {
+ charon->imvs->solicit_recommendation(charon->imvs, this->connection_id);
+ }
+ if (this->recs->have_recommendation(this->recs, &rec, &eval))
{
- this->tncc_connection = libtnc_tncc_CreateConnection(NULL);
- if (!this->tncc_connection)
+ if (!this->batch)
{
- DBG1(DBG_TNC, "TNCC CreateConnection failed");
- return FAILED;
+ this->batch = tnccs_batch_create(this->is_server, ++this->batch_id);
}
- DBG1(DBG_TNC, "assigned TNCC Connection ID %u",
- this->tncc_connection->connectionID);
- if (libtnc_tncc_BeginSession(this->tncc_connection) != TNC_RESULT_SUCCESS)
+
+ msg = tnccs_recommendation_msg_create(rec);
+ this->batch->add_msg(this->batch, msg);
+
+ /* currently we just send the first Reason String */
+ enumerator = this->recs->create_reason_enumerator(this->recs);
+ if (enumerator->enumerate(enumerator, &id, &reason, &language))
{
- DBG1(DBG_TNC, "TNCC BeginSession failed");
- return FAILED;
+ msg = tnccs_reason_strings_msg_create(reason, language);
+ this->batch->add_msg(this->batch, msg);
}
+ enumerator->destroy(enumerator);
+
+ /* we have reache the final state */
+ this->delete_state = TRUE;
}
- conn_id = this->is_server ? this->tncs_connection->connectionID
- : this->tncc_connection->connectionID;
-
- if (!retrieve_batch(conn_id, &batch))
+}
+
+METHOD(tls_t, build, status_t,
+ private_tnccs_11_t *this, void *buf, size_t *buflen, size_t *msglen)
+{
+ status_t status;
+
+ /* Initialize the connection */
+ if (!this->is_server && !this->connection_id)
{
- return FAILED;
+ tnccs_msg_t *msg;
+ char *pref_lang;
+
+ this->connection_id = charon->tnccs->create_connection(charon->tnccs,
+ (tnccs_t*)this, _send_msg,
+ &this->request_handshake_retry, NULL);
+ if (!this->connection_id)
+ {
+ return FAILED;
+ }
+
+ /* Create TNCCS-PreferredLanguage message */
+ pref_lang = charon->imcs->get_preferred_language(charon->imcs);
+ msg = tnccs_preferred_language_msg_create(pref_lang);
+ this->mutex->lock(this->mutex);
+ this->batch = tnccs_batch_create(this->is_server, ++this->batch_id);
+ this->batch->add_msg(this->batch, msg);
+ this->mutex->unlock(this->mutex);
+
+ charon->imcs->notify_connection_change(charon->imcs,
+ this->connection_id, TNC_CONNECTION_STATE_CREATE);
+ charon->imcs->notify_connection_change(charon->imcs,
+ this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
+ charon->imcs->begin_handshake(charon->imcs, this->connection_id);
}
- len = *buflen;
- len = min(len, batch.len);
- *buflen = len;
- if (msglen)
+
+ /* Do not allow any asynchronous IMCs or IMVs to add additional messages */
+ this->mutex->lock(this->mutex);
+
+ if (this->is_server && !this->delete_state &&
+ (!this->batch || this->fatal_error))
{
- *msglen = batch.len;
+ check_and_build_recommendation(this);
}
- if (batch.len)
+ if (this->batch)
{
+ chunk_t data;
+
+ this->batch->build(this->batch);
+ data = this->batch->get_encoding(this->batch);
DBG1(DBG_TNC, "sending TNCCS Batch (%d bytes) for Connection ID %u",
- batch.len, conn_id);
- DBG3(DBG_TNC, "%.*s", batch.len, batch.ptr);
- memcpy(buf, batch.ptr, len);
- free_batch(conn_id);
- return ALREADY_DONE;
+ data.len, this->connection_id);
+ DBG3(DBG_TNC, "%.*s", data.len, data.ptr);
+ *msglen = data.len;
+
+ if (data.len > *buflen)
+ {
+ DBG1(DBG_TNC, "fragmentation of TNCCS batch not supported yet");
+ }
+ else
+ {
+ *buflen = data.len;
+ }
+ memcpy(buf, data.ptr, *buflen);
+ this->batch->destroy(this->batch);
+ this->batch = NULL;
+ status = ALREADY_DONE;
}
else
{
- return INVALID_STATE;
+ DBG1(DBG_TNC, "no TNCCS Batch to send");
+ status = INVALID_STATE;
}
+ this->mutex->unlock(this->mutex);
+
+ return status;
}
METHOD(tls_t, is_server, bool,
@@ -237,39 +432,14 @@ METHOD(tls_t, is_complete, bool,
{
TNC_IMV_Action_Recommendation rec;
TNC_IMV_Evaluation_Result eval;
- char *group;
- identification_t *id;
- ike_sa_t *ike_sa;
- auth_cfg_t *auth;
-
- if (libtnc_tncs_HaveRecommendation(this->tncs_connection, &rec, &eval) ==
- TNC_RESULT_SUCCESS)
+
+ if (this->recs && this->recs->have_recommendation(this->recs, &rec, &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;
- }
- ike_sa = charon->bus->get_sa(charon->bus);
- if (ike_sa)
- {
- 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, "added group membership '%s' based on TNC recommendation", group);
- }
- return TRUE;
+ 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);
}
else
{
@@ -288,19 +458,17 @@ METHOD(tls_t, destroy, void,
{
if (this->is_server)
{
- if (this->tncs_connection)
- {
- libtnc_tncs_DeleteConnection(this->tncs_connection);
- }
+ charon->imvs->notify_connection_change(charon->imvs,
+ this->connection_id, TNC_CONNECTION_STATE_DELETE);
}
else
{
- if (this->tncc_connection)
- {
- libtnc_tncc_DeleteConnection(this->tncc_connection);
- }
- libtnc_tncc_Terminate();
+ charon->imcs->notify_connection_change(charon->imcs,
+ this->connection_id, TNC_CONNECTION_STATE_DELETE);
}
+ charon->tnccs->remove_connection(charon->tnccs, this->connection_id);
+ this->mutex->destroy(this->mutex);
+ DESTROY_IF(this->batch);
free(this);
}
@@ -322,6 +490,7 @@ tls_t *tnccs_11_create(bool is_server)
.destroy = _destroy,
},
.is_server = is_server,
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
);
return &this->public;
diff --git a/src/libcharon/plugins/tnccs_20/Makefile.am b/src/libcharon/plugins/tnccs_20/Makefile.am
index 3018121e3..d72fd3e34 100644
--- a/src/libcharon/plugins/tnccs_20/Makefile.am
+++ b/src/libcharon/plugins/tnccs_20/Makefile.am
@@ -1,21 +1,28 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls \
- `xml2-config --cflags`
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls
AM_CFLAGS = -rdynamic
-libstrongswan_tnccs_20_la_LIBADD = -ltnc
-
if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-tnccs-20.la
else
plugin_LTLIBRARIES = libstrongswan-tnccs-20.la
-libstrongswan_tnccs_20_la_LIBADD += $(top_builddir)/src/libtls/libtls.la
+libstrongswan_tnccs_20_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
endif
libstrongswan_tnccs_20_la_SOURCES = \
- tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c
+ tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c \
+ batch/pb_tnc_batch.h batch/pb_tnc_batch.c \
+ messages/pb_tnc_msg.h messages/pb_tnc_msg.c \
+ messages/pb_experimental_msg.h messages/pb_experimental_msg.c \
+ messages/pb_pa_msg.h messages/pb_pa_msg.c \
+ messages/pb_assessment_result_msg.h messages/pb_assessment_result_msg.c \
+ messages/pb_access_recommendation_msg.h messages/pb_access_recommendation_msg.c \
+ messages/pb_error_msg.h messages/pb_error_msg.c \
+ messages/pb_language_preference_msg.h messages/pb_language_preference_msg.c \
+ messages/pb_reason_string_msg.h messages/pb_reason_string_msg.c \
+ messages/pb_remediation_parameters_msg.h messages/pb_remediation_parameters_msg.c \
+ state_machine/pb_tnc_state_machine.h state_machine/pb_tnc_state_machine.c
libstrongswan_tnccs_20_la_LDFLAGS = -module -avoid-version
-
diff --git a/src/libcharon/plugins/tnccs_20/Makefile.in b/src/libcharon/plugins/tnccs_20/Makefile.in
index 6101f91df..9853be338 100644
--- a/src/libcharon/plugins/tnccs_20/Makefile.in
+++ b/src/libcharon/plugins/tnccs_20/Makefile.in
@@ -34,7 +34,6 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-@MONOLITHIC_FALSE@am__append_1 = $(top_builddir)/src/libtls/libtls.la
subdir = src/libcharon/plugins/tnccs_20
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -75,8 +74,14 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_tnccs_20_la_DEPENDENCIES = $(am__append_1)
-am_libstrongswan_tnccs_20_la_OBJECTS = tnccs_20_plugin.lo tnccs_20.lo
+@MONOLITHIC_FALSE@libstrongswan_tnccs_20_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la
+am_libstrongswan_tnccs_20_la_OBJECTS = tnccs_20_plugin.lo tnccs_20.lo \
+ pb_tnc_batch.lo pb_tnc_msg.lo pb_experimental_msg.lo \
+ pb_pa_msg.lo pb_assessment_result_msg.lo \
+ pb_access_recommendation_msg.lo pb_error_msg.lo \
+ pb_language_preference_msg.lo pb_reason_string_msg.lo \
+ pb_remediation_parameters_msg.lo pb_tnc_state_machine.lo
libstrongswan_tnccs_20_la_OBJECTS = \
$(am_libstrongswan_tnccs_20_la_OBJECTS)
libstrongswan_tnccs_20_la_LINK = $(LIBTOOL) --tag=CC \
@@ -223,9 +228,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +267,8 @@ 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@
@@ -275,15 +280,25 @@ 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 \
- `xml2-config --cflags`
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls
AM_CFLAGS = -rdynamic
-libstrongswan_tnccs_20_la_LIBADD = -ltnc $(am__append_1)
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnccs-20.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnccs-20.la
+@MONOLITHIC_FALSE@libstrongswan_tnccs_20_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
libstrongswan_tnccs_20_la_SOURCES = \
- tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c
+ tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c \
+ batch/pb_tnc_batch.h batch/pb_tnc_batch.c \
+ messages/pb_tnc_msg.h messages/pb_tnc_msg.c \
+ messages/pb_experimental_msg.h messages/pb_experimental_msg.c \
+ messages/pb_pa_msg.h messages/pb_pa_msg.c \
+ messages/pb_assessment_result_msg.h messages/pb_assessment_result_msg.c \
+ messages/pb_access_recommendation_msg.h messages/pb_access_recommendation_msg.c \
+ messages/pb_error_msg.h messages/pb_error_msg.c \
+ messages/pb_language_preference_msg.h messages/pb_language_preference_msg.c \
+ messages/pb_reason_string_msg.h messages/pb_reason_string_msg.c \
+ messages/pb_remediation_parameters_msg.h messages/pb_remediation_parameters_msg.c \
+ state_machine/pb_tnc_state_machine.h state_machine/pb_tnc_state_machine.c
libstrongswan_tnccs_20_la_LDFLAGS = -module -avoid-version
all: all-am
@@ -369,6 +384,17 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pb_access_recommendation_msg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pb_assessment_result_msg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pb_error_msg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pb_experimental_msg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pb_language_preference_msg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pb_pa_msg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pb_reason_string_msg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pb_remediation_parameters_msg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pb_tnc_batch.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pb_tnc_msg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pb_tnc_state_machine.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_20.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_20_plugin.Plo@am__quote@
@@ -393,6 +419,83 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+pb_tnc_batch.lo: batch/pb_tnc_batch.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pb_tnc_batch.lo -MD -MP -MF $(DEPDIR)/pb_tnc_batch.Tpo -c -o pb_tnc_batch.lo `test -f 'batch/pb_tnc_batch.c' || echo '$(srcdir)/'`batch/pb_tnc_batch.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pb_tnc_batch.Tpo $(DEPDIR)/pb_tnc_batch.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='batch/pb_tnc_batch.c' object='pb_tnc_batch.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pb_tnc_batch.lo `test -f 'batch/pb_tnc_batch.c' || echo '$(srcdir)/'`batch/pb_tnc_batch.c
+
+pb_tnc_msg.lo: messages/pb_tnc_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pb_tnc_msg.lo -MD -MP -MF $(DEPDIR)/pb_tnc_msg.Tpo -c -o pb_tnc_msg.lo `test -f 'messages/pb_tnc_msg.c' || echo '$(srcdir)/'`messages/pb_tnc_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pb_tnc_msg.Tpo $(DEPDIR)/pb_tnc_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/pb_tnc_msg.c' object='pb_tnc_msg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pb_tnc_msg.lo `test -f 'messages/pb_tnc_msg.c' || echo '$(srcdir)/'`messages/pb_tnc_msg.c
+
+pb_experimental_msg.lo: messages/pb_experimental_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pb_experimental_msg.lo -MD -MP -MF $(DEPDIR)/pb_experimental_msg.Tpo -c -o pb_experimental_msg.lo `test -f 'messages/pb_experimental_msg.c' || echo '$(srcdir)/'`messages/pb_experimental_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pb_experimental_msg.Tpo $(DEPDIR)/pb_experimental_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/pb_experimental_msg.c' object='pb_experimental_msg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pb_experimental_msg.lo `test -f 'messages/pb_experimental_msg.c' || echo '$(srcdir)/'`messages/pb_experimental_msg.c
+
+pb_pa_msg.lo: messages/pb_pa_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pb_pa_msg.lo -MD -MP -MF $(DEPDIR)/pb_pa_msg.Tpo -c -o pb_pa_msg.lo `test -f 'messages/pb_pa_msg.c' || echo '$(srcdir)/'`messages/pb_pa_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pb_pa_msg.Tpo $(DEPDIR)/pb_pa_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/pb_pa_msg.c' object='pb_pa_msg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pb_pa_msg.lo `test -f 'messages/pb_pa_msg.c' || echo '$(srcdir)/'`messages/pb_pa_msg.c
+
+pb_assessment_result_msg.lo: messages/pb_assessment_result_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pb_assessment_result_msg.lo -MD -MP -MF $(DEPDIR)/pb_assessment_result_msg.Tpo -c -o pb_assessment_result_msg.lo `test -f 'messages/pb_assessment_result_msg.c' || echo '$(srcdir)/'`messages/pb_assessment_result_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pb_assessment_result_msg.Tpo $(DEPDIR)/pb_assessment_result_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/pb_assessment_result_msg.c' object='pb_assessment_result_msg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pb_assessment_result_msg.lo `test -f 'messages/pb_assessment_result_msg.c' || echo '$(srcdir)/'`messages/pb_assessment_result_msg.c
+
+pb_access_recommendation_msg.lo: messages/pb_access_recommendation_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pb_access_recommendation_msg.lo -MD -MP -MF $(DEPDIR)/pb_access_recommendation_msg.Tpo -c -o pb_access_recommendation_msg.lo `test -f 'messages/pb_access_recommendation_msg.c' || echo '$(srcdir)/'`messages/pb_access_recommendation_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pb_access_recommendation_msg.Tpo $(DEPDIR)/pb_access_recommendation_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/pb_access_recommendation_msg.c' object='pb_access_recommendation_msg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pb_access_recommendation_msg.lo `test -f 'messages/pb_access_recommendation_msg.c' || echo '$(srcdir)/'`messages/pb_access_recommendation_msg.c
+
+pb_error_msg.lo: messages/pb_error_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pb_error_msg.lo -MD -MP -MF $(DEPDIR)/pb_error_msg.Tpo -c -o pb_error_msg.lo `test -f 'messages/pb_error_msg.c' || echo '$(srcdir)/'`messages/pb_error_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pb_error_msg.Tpo $(DEPDIR)/pb_error_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/pb_error_msg.c' object='pb_error_msg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pb_error_msg.lo `test -f 'messages/pb_error_msg.c' || echo '$(srcdir)/'`messages/pb_error_msg.c
+
+pb_language_preference_msg.lo: messages/pb_language_preference_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pb_language_preference_msg.lo -MD -MP -MF $(DEPDIR)/pb_language_preference_msg.Tpo -c -o pb_language_preference_msg.lo `test -f 'messages/pb_language_preference_msg.c' || echo '$(srcdir)/'`messages/pb_language_preference_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pb_language_preference_msg.Tpo $(DEPDIR)/pb_language_preference_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/pb_language_preference_msg.c' object='pb_language_preference_msg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pb_language_preference_msg.lo `test -f 'messages/pb_language_preference_msg.c' || echo '$(srcdir)/'`messages/pb_language_preference_msg.c
+
+pb_reason_string_msg.lo: messages/pb_reason_string_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pb_reason_string_msg.lo -MD -MP -MF $(DEPDIR)/pb_reason_string_msg.Tpo -c -o pb_reason_string_msg.lo `test -f 'messages/pb_reason_string_msg.c' || echo '$(srcdir)/'`messages/pb_reason_string_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pb_reason_string_msg.Tpo $(DEPDIR)/pb_reason_string_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/pb_reason_string_msg.c' object='pb_reason_string_msg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pb_reason_string_msg.lo `test -f 'messages/pb_reason_string_msg.c' || echo '$(srcdir)/'`messages/pb_reason_string_msg.c
+
+pb_remediation_parameters_msg.lo: messages/pb_remediation_parameters_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pb_remediation_parameters_msg.lo -MD -MP -MF $(DEPDIR)/pb_remediation_parameters_msg.Tpo -c -o pb_remediation_parameters_msg.lo `test -f 'messages/pb_remediation_parameters_msg.c' || echo '$(srcdir)/'`messages/pb_remediation_parameters_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pb_remediation_parameters_msg.Tpo $(DEPDIR)/pb_remediation_parameters_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/pb_remediation_parameters_msg.c' object='pb_remediation_parameters_msg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pb_remediation_parameters_msg.lo `test -f 'messages/pb_remediation_parameters_msg.c' || echo '$(srcdir)/'`messages/pb_remediation_parameters_msg.c
+
+pb_tnc_state_machine.lo: state_machine/pb_tnc_state_machine.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pb_tnc_state_machine.lo -MD -MP -MF $(DEPDIR)/pb_tnc_state_machine.Tpo -c -o pb_tnc_state_machine.lo `test -f 'state_machine/pb_tnc_state_machine.c' || echo '$(srcdir)/'`state_machine/pb_tnc_state_machine.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pb_tnc_state_machine.Tpo $(DEPDIR)/pb_tnc_state_machine.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='state_machine/pb_tnc_state_machine.c' object='pb_tnc_state_machine.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pb_tnc_state_machine.lo `test -f 'state_machine/pb_tnc_state_machine.c' || echo '$(srcdir)/'`state_machine/pb_tnc_state_machine.c
+
mostlyclean-libtool:
-rm -f *.lo
diff --git a/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c b/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c
new file mode 100644
index 000000000..3f38543ed
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c
@@ -0,0 +1,543 @@
+/*
+ * Copyright (C) 2010 Sansar Choinyanbuu
+ * 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 "pb_tnc_batch.h"
+#include "messages/pb_error_msg.h"
+#include "state_machine/pb_tnc_state_machine.h"
+
+#include <debug.h>
+#include <utils/linked_list.h>
+#include <tls_writer.h>
+#include <tls_reader.h>
+#include <tnc/tnccs/tnccs.h>
+
+ENUM(pb_tnc_batch_type_names, PB_BATCH_CDATA, PB_BATCH_CLOSE,
+ "CDATA",
+ "SDATA",
+ "RESULT",
+ "CRETRY",
+ "SRETRY",
+ "CLOSE"
+);
+
+typedef struct private_pb_tnc_batch_t private_pb_tnc_batch_t;
+
+/**
+ * PB-Batch Header (see section 4.1 of RFC 5793)
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Version |D| Reserved | B-Type|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Batch Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PB_TNC_BATCH_FLAG_NONE 0x00
+#define PB_TNC_BATCH_FLAG_D (1<<7)
+#define PB_TNC_BATCH_HEADER_SIZE 8
+
+/**
+ * PB-TNC Message (see section 4.2 of RFC 5793)
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | PB-TNC Vendor ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | PB-TNC Message Type |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | PB-TNC Message Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | PB-TNC Message Value (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PB_TNC_FLAG_NONE 0x00
+#define PB_TNC_FLAG_NOSKIP (1<<7)
+#define PB_TNC_HEADER_SIZE 12
+
+#define PB_TNC_RESERVED_MSG_TYPE 0xffffffff
+
+/**
+ * Private data of a pb_tnc_batch_t object.
+ *
+ */
+struct private_pb_tnc_batch_t {
+ /**
+ * Public pb_pa_msg_t interface.
+ */
+ pb_tnc_batch_t public;
+
+ /**
+ * TNCC if TRUE, TNCS if FALSE
+ */
+ bool is_server;
+
+ /**
+ * PB-TNC Batch type
+ */
+ pb_tnc_batch_type_t type;
+
+ /**
+ * linked list of PB-TNC messages
+ */
+ linked_list_t *messages;
+
+ /**
+ * linked list of PB-TNC error messages
+ */
+ linked_list_t *errors;
+
+ /**
+ * Encoded message
+ */
+ chunk_t encoding;
+
+ /**
+ * Offset into encoding (used for error reporting)
+ */
+ u_int32_t offset;
+};
+
+METHOD(pb_tnc_batch_t, get_type, pb_tnc_batch_type_t,
+ private_pb_tnc_batch_t *this)
+{
+ return this->type;
+}
+
+METHOD(pb_tnc_batch_t, get_encoding, chunk_t,
+ private_pb_tnc_batch_t *this)
+{
+ return this->encoding;
+}
+
+METHOD(pb_tnc_batch_t, add_msg, void,
+ private_pb_tnc_batch_t *this, pb_tnc_msg_t* msg)
+{
+ DBG2(DBG_TNC, "adding %N message", pb_tnc_msg_type_names,
+ msg->get_type(msg));
+ this->messages->insert_last(this->messages, msg);
+}
+
+METHOD(pb_tnc_batch_t, build, void,
+ private_pb_tnc_batch_t *this)
+{
+ u_int32_t batch_len, msg_len;
+ chunk_t msg_value;
+ enumerator_t *enumerator;
+ pb_tnc_msg_type_t msg_type;
+ pb_tnc_msg_t *msg;
+ tls_writer_t *writer;
+
+ /* compute total PB-TNC batch size by summing over all messages */
+ batch_len = PB_TNC_BATCH_HEADER_SIZE;
+ enumerator = this->messages->create_enumerator(this->messages);
+ while (enumerator->enumerate(enumerator, &msg))
+ {
+ msg->build(msg);
+ msg_value = msg->get_encoding(msg);
+ batch_len += PB_TNC_HEADER_SIZE + msg_value.len;
+ }
+ enumerator->destroy(enumerator);
+
+ /* build PB-TNC batch header */
+ writer = tls_writer_create(batch_len);
+ writer->write_uint8 (writer, PB_TNC_VERSION);
+ writer->write_uint8 (writer, this->is_server ?
+ PB_TNC_BATCH_FLAG_D : PB_TNC_BATCH_FLAG_NONE);
+ writer->write_uint16(writer, this->type);
+ writer->write_uint32(writer, batch_len);
+
+ /* build PB-TNC messages */
+ enumerator = this->messages->create_enumerator(this->messages);
+ while (enumerator->enumerate(enumerator, &msg))
+ {
+ u_int8_t flags = PB_TNC_FLAG_NONE;
+
+ /* build PB-TNC message */
+ msg_value = msg->get_encoding(msg);
+ msg_len = PB_TNC_HEADER_SIZE + msg_value.len;
+ msg_type = msg->get_type(msg);
+ if (pb_tnc_msg_infos[msg_type].has_noskip_flag)
+ {
+ flags |= PB_TNC_FLAG_NOSKIP;
+ }
+ writer->write_uint8 (writer, flags);
+ writer->write_uint24(writer, IETF_VENDOR_ID);
+ writer->write_uint32(writer, msg_type);
+ writer->write_uint32(writer, msg_len);
+ writer->write_data (writer, msg_value);
+ }
+ enumerator->destroy(enumerator);
+
+ this->encoding = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+static status_t process_batch_header(private_pb_tnc_batch_t *this,
+ pb_tnc_state_machine_t *state_machine)
+{
+ tls_reader_t *reader;
+ pb_tnc_msg_t *msg;
+ pb_error_msg_t *err_msg;
+ u_int8_t version, flags, reserved, type;
+ u_int32_t batch_len;
+ bool directionality;
+
+ if (this->encoding.len < PB_TNC_BATCH_HEADER_SIZE)
+ {
+ DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC batch header",
+ this->encoding.len);
+ msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ PB_ERROR_INVALID_PARAMETER, 0);
+ goto fatal;
+ }
+
+ reader = tls_reader_create(this->encoding);
+ reader->read_uint8 (reader, &version);
+ reader->read_uint8 (reader, &flags);
+ reader->read_uint8 (reader, &reserved);
+ reader->read_uint8 (reader, &type);
+ reader->read_uint32(reader, &batch_len);
+ reader->destroy(reader);
+
+ /* Version */
+ if (version != PB_TNC_VERSION)
+ {
+ DBG1(DBG_TNC, "unsupported TNCCS batch version 0x%01x", version);
+ msg = pb_error_msg_create(TRUE, IETF_VENDOR_ID,
+ PB_ERROR_VERSION_NOT_SUPPORTED);
+ err_msg = (pb_error_msg_t*)msg;
+ err_msg->set_bad_version(err_msg, version);
+ goto fatal;
+ }
+
+ /* Directionality */
+ directionality = (flags & PB_TNC_BATCH_FLAG_D) != PB_TNC_BATCH_FLAG_NONE;
+ if (directionality == this->is_server)
+ {
+ DBG1(DBG_TNC, "wrong Directionality: batch is from a PB %s",
+ directionality ? "server" : "client");
+ msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ PB_ERROR_INVALID_PARAMETER, 1);
+ goto fatal;
+ }
+
+ /* Batch Type */
+ this->type = type & 0x0F;
+ if (this->type > PB_BATCH_ROOF)
+ {
+ DBG1(DBG_TNC, "unknown PB-TNC batch type: %d", this->type);
+ msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ PB_ERROR_INVALID_PARAMETER, 3);
+ goto fatal;
+ }
+
+ if (!state_machine->receive_batch(state_machine, this->type))
+ {
+ DBG1(DBG_TNC, "unexpected PB-TNC batch type: %N",
+ pb_tnc_batch_type_names, this->type);
+ msg = pb_error_msg_create(TRUE, IETF_VENDOR_ID,
+ PB_ERROR_UNEXPECTED_BATCH_TYPE);
+ goto fatal;
+ }
+
+ /* Batch Length */
+ if (this->encoding.len != batch_len)
+ {
+ DBG1(DBG_TNC, "%u bytes of data is not equal to batch length of %u bytes",
+ this->encoding.len, batch_len);
+ msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ PB_ERROR_INVALID_PARAMETER, 4);
+ goto fatal;
+ }
+
+ this->offset = PB_TNC_BATCH_HEADER_SIZE;
+ return SUCCESS;
+
+fatal:
+ this->errors->insert_last(this->errors, msg);
+ return FAILED;
+}
+
+static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
+{
+ tls_reader_t *reader;
+ pb_tnc_msg_t *pb_tnc_msg, *msg;
+ u_int8_t flags;
+ u_int32_t vendor_id, msg_type, msg_len, offset;
+ chunk_t data, msg_value;
+ bool noskip_flag;
+ status_t status;
+
+ data = chunk_skip(this->encoding, this->offset);
+
+ if (data.len < PB_TNC_HEADER_SIZE)
+ {
+ DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC message header",
+ data.len);
+ msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ PB_ERROR_INVALID_PARAMETER, this->offset);
+ goto fatal;
+ }
+
+ reader = tls_reader_create(data);
+ reader->read_uint8 (reader, &flags);
+ reader->read_uint24(reader, &vendor_id);
+ reader->read_uint32(reader, &msg_type);
+ reader->read_uint32(reader, &msg_len);
+ reader->destroy(reader);
+
+ noskip_flag = (flags & PB_TNC_FLAG_NOSKIP) != PB_TNC_FLAG_NONE;
+
+ if (msg_len > data.len)
+ {
+ DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC message", data.len);
+ msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ PB_ERROR_INVALID_PARAMETER, this->offset + 8);
+ goto fatal;
+ }
+
+ if (vendor_id == RESERVED_VENDOR_ID)
+ {
+ DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", RESERVED_VENDOR_ID);
+ msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ PB_ERROR_INVALID_PARAMETER, this->offset + 1);
+ goto fatal;
+
+ }
+
+ if (msg_type == PB_TNC_RESERVED_MSG_TYPE)
+ {
+ DBG1(DBG_TNC, "PB-TNC message Type 0x%08x is reserved",
+ PB_TNC_RESERVED_MSG_TYPE);
+ msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ PB_ERROR_INVALID_PARAMETER, this->offset + 4);
+ goto fatal;
+ }
+
+
+ if (vendor_id != IETF_VENDOR_ID || msg_type > PB_MSG_ROOF)
+ {
+ if (msg_len < PB_TNC_HEADER_SIZE)
+ {
+ DBG1(DBG_TNC, "%u bytes too small for PB-TNC message length",
+ msg_len);
+ msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ PB_ERROR_INVALID_PARAMETER, this->offset + 8);
+ goto fatal;
+ }
+
+ if (noskip_flag)
+ {
+ DBG1(DBG_TNC, "reject PB-TNC message (Vendor ID 0x%06x / "
+ "Type 0x%08x)", vendor_id, msg_type);
+ msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ PB_ERROR_UNSUPPORTED_MANDATORY_MSG, this->offset);
+ goto fatal;
+ }
+ else
+ {
+ DBG1(DBG_TNC, "ignore PB-TNC message (Vendor ID 0x%06x / "
+ "Type 0x%08x)", vendor_id, msg_type);
+ this->offset += msg_len;
+ return SUCCESS;
+ }
+ }
+ else
+ {
+ if (pb_tnc_msg_infos[msg_type].has_noskip_flag != TRUE_OR_FALSE &&
+ pb_tnc_msg_infos[msg_type].has_noskip_flag != noskip_flag)
+ {
+ DBG1(DBG_TNC, "%N message must%s have NOSKIP flag set",
+ pb_tnc_msg_type_names, msg_type,
+ pb_tnc_msg_infos[msg_type].has_noskip_flag ? "" : " not");
+ msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ PB_ERROR_INVALID_PARAMETER, this->offset);
+ goto fatal;
+ }
+
+ if (msg_len < pb_tnc_msg_infos[msg_type].min_size ||
+ (pb_tnc_msg_infos[msg_type].exact_size &&
+ msg_len != pb_tnc_msg_infos[msg_type].min_size))
+ {
+ DBG1(DBG_TNC, "%N message length must be %s %u bytes but is %u bytes",
+ pb_tnc_msg_type_names, msg_type,
+ pb_tnc_msg_infos[msg_type].exact_size ? "exactly" : "at least",
+ pb_tnc_msg_infos[msg_type].min_size, msg_len);
+ msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ PB_ERROR_INVALID_PARAMETER, this->offset);
+ goto fatal;
+ }
+ }
+
+ if (pb_tnc_msg_infos[msg_type].in_result_batch &&
+ this->type != PB_BATCH_RESULT)
+ {
+ if (this->is_server)
+ {
+ DBG1(DBG_TNC,"reject %N message received from a PB-TNC client",
+ pb_tnc_msg_type_names, msg_type);
+ msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ PB_ERROR_INVALID_PARAMETER, this->offset);
+ goto fatal;
+ }
+ else
+ {
+ DBG1(DBG_TNC,"ignore %N message not received within RESULT batch",
+ pb_tnc_msg_type_names, msg_type);
+ this->offset += msg_len;
+ return SUCCESS;
+ }
+ }
+
+ DBG2(DBG_TNC, "processing %N message (%u bytes)", pb_tnc_msg_type_names,
+ msg_type, msg_len);
+ data.len = msg_len;
+ msg_value = chunk_skip(data, PB_TNC_HEADER_SIZE);
+ pb_tnc_msg = pb_tnc_msg_create_from_data(msg_type, msg_value);
+
+ status = pb_tnc_msg->process(pb_tnc_msg, &offset);
+ if (status == FAILED || status == VERIFY_ERROR)
+ {
+ msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ PB_ERROR_INVALID_PARAMETER, this->offset);
+ this->errors->insert_last(this->errors, msg);
+ }
+ if (status == FAILED)
+ {
+ pb_tnc_msg->destroy(pb_tnc_msg);
+ return FAILED;
+ }
+ this->messages->insert_last(this->messages, pb_tnc_msg);
+ this->offset += msg_len;
+ return status;
+
+fatal:
+ this->errors->insert_last(this->errors, msg);
+ return FAILED;
+}
+
+METHOD(pb_tnc_batch_t, process, status_t,
+ private_pb_tnc_batch_t *this, pb_tnc_state_machine_t *state_machine)
+{
+ status_t status;
+
+ status = process_batch_header(this, state_machine);
+ if (status != SUCCESS)
+ {
+ return FAILED;
+ }
+ DBG1(DBG_TNC, "processing PB-TNC %N batch", pb_tnc_batch_type_names,
+ this->type);
+ while (this->offset < this->encoding.len)
+ {
+ switch (process_tnc_msg(this))
+ {
+ case FAILED:
+ return FAILED;
+ case VERIFY_ERROR:
+ status = VERIFY_ERROR;
+ break;
+ case SUCCESS:
+ default:
+ break;
+ }
+ }
+ return status;
+}
+
+METHOD(pb_tnc_batch_t, create_msg_enumerator, enumerator_t*,
+ private_pb_tnc_batch_t *this)
+{
+ return this->messages->create_enumerator(this->messages);
+}
+
+METHOD(pb_tnc_batch_t, create_error_enumerator, enumerator_t*,
+ private_pb_tnc_batch_t *this)
+{
+ return this->errors->create_enumerator(this->errors);
+}
+
+METHOD(pb_tnc_batch_t, destroy, void,
+ private_pb_tnc_batch_t *this)
+{
+ this->messages->destroy_offset(this->messages,
+ offsetof(pb_tnc_msg_t, destroy));
+ this->errors->destroy_offset(this->errors,
+ offsetof(pb_tnc_msg_t, destroy));
+ free(this->encoding.ptr);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pb_tnc_batch_t* pb_tnc_batch_create(bool is_server, pb_tnc_batch_type_t type)
+{
+ private_pb_tnc_batch_t *this;
+
+ INIT(this,
+ .public = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .add_msg = _add_msg,
+ .build = _build,
+ .process = _process,
+ .create_msg_enumerator = _create_msg_enumerator,
+ .create_error_enumerator = _create_error_enumerator,
+ .destroy = _destroy,
+ },
+ .is_server = is_server,
+ .type = type,
+ .messages = linked_list_create(),
+ .errors = linked_list_create(),
+ );
+
+ DBG2(DBG_TNC, "creating PB-TNC %N batch", pb_tnc_batch_type_names, type);
+
+ return &this->public;
+}
+
+/**
+ * See header
+ */
+pb_tnc_batch_t* pb_tnc_batch_create_from_data(bool is_server, chunk_t data)
+{
+ private_pb_tnc_batch_t *this;
+
+ INIT(this,
+ .public = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .add_msg = _add_msg,
+ .build = _build,
+ .process = _process,
+ .create_msg_enumerator = _create_msg_enumerator,
+ .create_error_enumerator = _create_error_enumerator,
+ .destroy = _destroy,
+ },
+ .is_server = is_server,
+ .messages = linked_list_create(),
+ .errors = linked_list_create(),
+ .encoding = chunk_clone(data),
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.h b/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.h
new file mode 100644
index 000000000..17e5fff4c
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.h
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup pb_tnc_batch pb_tnc_batch
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef PB_TNC_BATCH_H_
+#define PB_TNC_BATCH_H_
+
+typedef enum pb_tnc_batch_type_t pb_tnc_batch_type_t;
+typedef struct pb_tnc_batch_t pb_tnc_batch_t;
+
+#include "messages/pb_tnc_msg.h"
+#include "state_machine/pb_tnc_state_machine.h"
+
+#include <library.h>
+
+/**
+ * PB-TNC Batch Types as defined in section 4.1 of RFC 5793
+ */
+enum pb_tnc_batch_type_t {
+ PB_BATCH_CDATA = 1,
+ PB_BATCH_SDATA = 2,
+ PB_BATCH_RESULT = 3,
+ PB_BATCH_CRETRY = 4,
+ PB_BATCH_SRETRY = 5,
+ PB_BATCH_CLOSE = 6,
+ PB_BATCH_ROOF = 6
+};
+
+/**
+ * enum name for pb_tnc_batch_type_t.
+ */
+extern enum_name_t *pb_tnc_batch_type_names;
+
+/**
+ * Interface for all PB-TNC Batch Types.
+ */
+struct pb_tnc_batch_t {
+
+ /**
+ * Get the PB-TNC Message Type
+ *
+ * @return PB-TNC batch type
+ */
+ pb_tnc_batch_type_t (*get_type)(pb_tnc_batch_t *this);
+
+ /**
+ * Get the encoding of the PB-TNC Batch
+ *
+ * @return encoded PB-TNC batch
+ */
+ chunk_t (*get_encoding)(pb_tnc_batch_t *this);
+
+ /**
+ * Add a PB-TNC Message
+ *
+ * @param msg PB-TNC message to be addedd
+ */
+ void (*add_msg)(pb_tnc_batch_t *this, pb_tnc_msg_t* msg);
+
+ /**
+ * Build the PB-TNC Batch
+ */
+ void (*build)(pb_tnc_batch_t *this);
+
+ /**
+ * Process the PB-TNC Batch
+ *
+ * @param PB-TNC state machine
+ * @return return processing status
+ */
+ status_t (*process)(pb_tnc_batch_t *this,
+ pb_tnc_state_machine_t *state_machine);
+
+ /**
+ * Enumerates over all PB-TNC Messages
+ *
+ * @return return message enumerator
+ */
+ enumerator_t* (*create_msg_enumerator)(pb_tnc_batch_t *this);
+
+ /**
+ * Enumerates over all parsing errors
+ *
+ * @return return error enumerator
+ */
+ enumerator_t* (*create_error_enumerator)(pb_tnc_batch_t *this);
+
+ /**
+ * Destroys a pb_tnc_batch_t object.
+ */
+ void (*destroy)(pb_tnc_batch_t *this);
+};
+
+/**
+ * Create an empty PB-TNC Batch of a given type
+ *
+ * @param is_server TRUE if server, FALSE if client
+ * @param type PB-TNC batch type
+ */
+pb_tnc_batch_t* pb_tnc_batch_create(bool is_server, pb_tnc_batch_type_t type);
+
+/**
+ * Create an unprocessed PB-TNC Batch from data
+ *
+ * @param is_server TRUE if server, FALSE if client
+ * @param data encoded PB-TNC batch
+ */
+pb_tnc_batch_t* pb_tnc_batch_create_from_data(bool is_server, chunk_t data);
+
+#endif /** PB_TNC_BATCH_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.c
new file mode 100644
index 000000000..41b9e31f6
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2010 Sansar Choinyambuu
+ * 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 "pb_access_recommendation_msg.h"
+
+#include <tls_writer.h>
+#include <tls_reader.h>
+#include <debug.h>
+
+ENUM(pb_access_recommendation_code_names, PB_REC_ACCESS_ALLOWED, PB_REC_QUARANTINED,
+ "Access Allowed",
+ "Access Denied",
+ "Quarantined"
+);
+
+typedef struct private_pb_access_recommendation_msg_t private_pb_access_recommendation_msg_t;
+
+/**
+ * PB-Access-Recommendation message (see section 4.7 of RFC 5793)
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved | Access Recommendation Code |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define ACCESS_RECOMMENDATION_RESERVED 0x0000
+#define ACCESS_RECOMMENDATION_MSG_SIZE 4
+/**
+ * Private data of a pb_access_recommendation_msg_t object.
+ *
+ */
+struct private_pb_access_recommendation_msg_t {
+ /**
+ * Public pb_access_recommendation_msg_t interface.
+ */
+ pb_access_recommendation_msg_t public;
+
+ /**
+ * PB-TNC message type
+ */
+ pb_tnc_msg_type_t type;
+
+ /**
+ * Access recommendation code
+ */
+ u_int16_t recommendation;
+
+ /**
+ * Encoded message
+ */
+ chunk_t encoding;
+};
+
+METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
+ private_pb_access_recommendation_msg_t *this)
+{
+ return this->type;
+}
+
+METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
+ private_pb_access_recommendation_msg_t *this)
+{
+ return this->encoding;
+}
+
+METHOD(pb_tnc_msg_t, build, void,
+ private_pb_access_recommendation_msg_t *this)
+{
+ tls_writer_t *writer;
+
+ /* build message */
+ writer = tls_writer_create(ACCESS_RECOMMENDATION_MSG_SIZE);
+ writer->write_uint16(writer, ACCESS_RECOMMENDATION_RESERVED);
+ writer->write_uint16(writer, this->recommendation);
+ free(this->encoding.ptr);
+ this->encoding = writer->get_buf(writer);
+ this->encoding = chunk_clone(this->encoding);
+ writer->destroy(writer);
+}
+
+METHOD(pb_tnc_msg_t, process, status_t,
+ private_pb_access_recommendation_msg_t *this, u_int32_t *offset)
+{
+ tls_reader_t *reader;
+ u_int16_t reserved;
+
+ /* process message */
+ reader = tls_reader_create(this->encoding);
+ reader->read_uint16(reader, &reserved);
+ reader->read_uint16(reader, &this->recommendation);
+ reader->destroy(reader);
+
+ if (this->recommendation < PB_REC_ACCESS_ALLOWED ||
+ this->recommendation > PB_REC_QUARANTINED)
+ {
+ DBG1(DBG_TNC, "invalid access recommendation code (%u)",
+ this->recommendation);
+ *offset = 2;
+ return FAILED;
+ }
+
+ return SUCCESS;
+}
+
+METHOD(pb_tnc_msg_t, destroy, void,
+ private_pb_access_recommendation_msg_t *this)
+{
+ free(this->encoding.ptr);
+ free(this);
+}
+
+METHOD(pb_access_recommendation_msg_t, get_access_recommendation, u_int16_t,
+ private_pb_access_recommendation_msg_t *this)
+{
+ return this->recommendation;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_access_recommendation_msg_create_from_data(chunk_t data)
+{
+ private_pb_access_recommendation_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_access_recommendation = _get_access_recommendation,
+ },
+ .type = PB_MSG_ACCESS_RECOMMENDATION,
+ .encoding = chunk_clone(data),
+ );
+
+ return &this->public.pb_interface;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_access_recommendation_msg_create(u_int16_t recommendation)
+{
+ private_pb_access_recommendation_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_access_recommendation = _get_access_recommendation,
+ },
+ .type = PB_MSG_ACCESS_RECOMMENDATION,
+ .recommendation = recommendation,
+ );
+
+ return &this->public.pb_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.h b/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.h
new file mode 100644
index 000000000..01b83cfd7
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2010 Sansar Choinyambuu
+ * 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 pb_access_recommendation_msg pb_access_recommendation_msg
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef PB_ACCESS_RECOMMENDATION_MSG_H_
+#define PB_ACCESS_RECOMMENDATION_MSG_H_
+
+typedef enum pb_access_recommendation_code_t pb_access_recommendation_code_t;
+typedef struct pb_access_recommendation_msg_t pb_access_recommendation_msg_t;
+
+#include "pb_tnc_msg.h"
+
+/**
+ * PB Access Recommendation Codes as defined in section 4.7 of RFC 5793
+ */
+enum pb_access_recommendation_code_t {
+ PB_REC_ACCESS_ALLOWED = 1,
+ PB_REC_ACCESS_DENIED = 2,
+ PB_REC_QUARANTINED = 3,
+};
+
+/**
+ * enum name for pb_access_recommendation_code_t.
+ */
+extern enum_name_t *pb_access_recommendation_code_names;
+
+
+/**
+ * Class representing the PB-Access-Recommendation message type.
+ */
+struct pb_access_recommendation_msg_t {
+
+ /**
+ * PB-TNC Message interface
+ */
+ pb_tnc_msg_t pb_interface;
+
+ /**
+ * Get PB Access Recommendation
+ *
+ * @return PB Access Recommendation
+ */
+ u_int16_t (*get_access_recommendation)(pb_access_recommendation_msg_t *this);
+};
+
+/**
+ * Create a PB-Access-Recommendation message from parameters
+ *
+ * @param recommendation Access Recommendation code
+ */
+pb_tnc_msg_t* pb_access_recommendation_msg_create(u_int16_t recommendation);
+
+/**
+ * Create an unprocessed PB-Access-Recommendation message from raw data
+ *
+ * @param data PB-Access-Recommendation message data
+ */
+pb_tnc_msg_t* pb_access_recommendation_msg_create_from_data(chunk_t data);
+
+#endif /** PB_PA_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.c
new file mode 100644
index 000000000..c91e54176
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2010 Sansar Choinyambuu
+ * 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 "pb_assessment_result_msg.h"
+
+#include <tls_writer.h>
+#include <tls_reader.h>
+#include <tnc/tncifimv.h>
+#include <debug.h>
+
+typedef struct private_pb_assessment_result_msg_t private_pb_assessment_result_msg_t;
+
+/**
+ * PB-Assessment-Result message (see section 4.6 of RFC 5793)
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Assessment Result |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define ASSESSMENT_RESULT_MSG_SIZE 4
+
+/**
+ * Private data of a pb_assessment_result_msg_t object.
+ *
+ */
+struct private_pb_assessment_result_msg_t {
+ /**
+ * Public pb_assessment_result_msg_t interface.
+ */
+ pb_assessment_result_msg_t public;
+
+ /**
+ * PB-TNC message type
+ */
+ pb_tnc_msg_type_t type;
+
+ /**
+ * Assessment result code
+ */
+ u_int32_t assessment_result;
+
+ /**
+ * Encoded message
+ */
+ chunk_t encoding;
+};
+
+METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
+ private_pb_assessment_result_msg_t *this)
+{
+ return this->type;
+}
+
+METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
+ private_pb_assessment_result_msg_t *this)
+{
+ return this->encoding;
+}
+
+METHOD(pb_tnc_msg_t, build, void,
+ private_pb_assessment_result_msg_t *this)
+{
+ tls_writer_t *writer;
+
+ /* build message */
+ writer = tls_writer_create(ASSESSMENT_RESULT_MSG_SIZE);
+ writer->write_uint32(writer, this->assessment_result);
+ free(this->encoding.ptr);
+ this->encoding = writer->get_buf(writer);
+ this->encoding = chunk_clone(this->encoding);
+ writer->destroy(writer);
+}
+
+METHOD(pb_tnc_msg_t, process, status_t,
+ private_pb_assessment_result_msg_t *this, u_int32_t *offset)
+{
+ tls_reader_t *reader;
+
+ /* process message */
+ reader = tls_reader_create(this->encoding);
+ reader->read_uint32(reader, &this->assessment_result);
+ reader->destroy(reader);
+
+ if (this->assessment_result < TNC_IMV_EVALUATION_RESULT_COMPLIANT ||
+ this->assessment_result > TNC_IMV_EVALUATION_RESULT_DONT_KNOW)
+ {
+ DBG1(DBG_TNC, "invalid assessment result (%u)",
+ this->assessment_result);
+ *offset = 0;
+ return FAILED;
+ }
+
+ return SUCCESS;
+}
+
+METHOD(pb_tnc_msg_t, destroy, void,
+ private_pb_assessment_result_msg_t *this)
+{
+ free(this->encoding.ptr);
+ free(this);
+}
+
+METHOD(pb_assessment_result_msg_t, get_assessment_result, u_int32_t,
+ private_pb_assessment_result_msg_t *this)
+{
+ return this->assessment_result;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_assessment_result_msg_create_from_data(chunk_t data)
+{
+ private_pb_assessment_result_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_assessment_result = _get_assessment_result,
+ },
+ .type = PB_MSG_ASSESSMENT_RESULT,
+ .encoding = chunk_clone(data),
+ );
+
+ return &this->public.pb_interface;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_assessment_result_msg_create(u_int32_t assessment_result)
+{
+ private_pb_assessment_result_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_assessment_result = _get_assessment_result,
+ },
+ .type = PB_MSG_ASSESSMENT_RESULT,
+ .assessment_result = assessment_result,
+ );
+
+ return &this->public.pb_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.h b/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.h
new file mode 100644
index 000000000..d2b005114
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 Sansar Choinyambuu
+ * 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 pb_assessment_result_msg pb_assessment_result_msg
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef PB_ASSESSMENT_RESULT_MSG_H_
+#define PB_ASSESSMENT_RESULT_MSG_H_
+
+typedef struct pb_assessment_result_msg_t pb_assessment_result_msg_t;
+
+#include "pb_tnc_msg.h"
+
+/**
+ * Class representing the PB-Assessment-Result message type.
+ */
+struct pb_assessment_result_msg_t {
+
+ /**
+ * PB-TNC Message interface
+ */
+ pb_tnc_msg_t pb_interface;
+
+ /**
+ * Get PB Assessment result
+ *
+ * @return PB Assessment result
+ */
+ u_int32_t (*get_assessment_result)(pb_assessment_result_msg_t *this);
+};
+
+/**
+ * Create a PB-Assessment-Result message from parameters
+ *
+ * @param assessment_result Assessment result code
+ */
+pb_tnc_msg_t* pb_assessment_result_msg_create(u_int32_t assessment_result);
+
+/**
+ * Create an unprocessed PB-Assessment-Result message from raw data
+ *
+ * @param data PB-Assessment-Result message data
+ */
+pb_tnc_msg_t* pb_assessment_result_msg_create_from_data(chunk_t data);
+
+#endif /** PB_PA_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.c
new file mode 100644
index 000000000..e1755c512
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2010 Sansar Choinyambuu
+ * 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 "pb_error_msg.h"
+
+#include <debug.h>
+#include <tls_writer.h>
+#include <tls_reader.h>
+#include <tnc/tnccs/tnccs.h>
+
+ENUM(pb_tnc_error_code_names, PB_ERROR_UNEXPECTED_BATCH_TYPE,
+ PB_ERROR_VERSION_NOT_SUPPORTED,
+ "Unexpected Batch Type",
+ "Invalid Parameter",
+ "Local Error",
+ "Unsupported Mandatory Message",
+ "Version Not Supported"
+);
+
+typedef struct private_pb_error_msg_t private_pb_error_msg_t;
+
+/**
+ * PB-Error message (see section 4.9 of RFC 5793)
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | Error Code Vendor ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Error Code | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Error Parameters (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define ERROR_FLAG_NONE 0x00
+#define ERROR_FLAG_FATAL (1<<7)
+#define ERROR_RESERVED 0x0000
+#define ERROR_HEADER_SIZE 8
+
+/**
+ * Private data of a pb_error_msg_t object.
+ *
+ */
+struct private_pb_error_msg_t {
+ /**
+ * Public pb_error_msg_t interface.
+ */
+ pb_error_msg_t public;
+
+ /**
+ * PB-TNC message type
+ */
+ pb_tnc_msg_type_t type;
+
+ /**
+ * Fatal flag
+ */
+ bool fatal;
+
+ /**
+ * PB Error Code Vendor ID
+ */
+ u_int32_t vendor_id;
+
+ /**
+ * PB Error Code
+ */
+ u_int16_t error_code;
+
+ /**
+ * PB Error Offset
+ */
+ u_int32_t error_offset;
+
+ /**
+ * Bad PB-TNC version received
+ */
+ u_int8_t bad_version;
+
+ /**
+ * Encoded message
+ */
+ chunk_t encoding;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
+ private_pb_error_msg_t *this)
+{
+ return this->type;
+}
+
+METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
+ private_pb_error_msg_t *this)
+{
+ return this->encoding;
+}
+
+METHOD(pb_tnc_msg_t, build, void,
+ private_pb_error_msg_t *this)
+{
+ tls_writer_t *writer;
+
+ /* build message header */
+ writer = tls_writer_create(ERROR_HEADER_SIZE);
+ writer->write_uint8 (writer, this->fatal ?
+ ERROR_FLAG_FATAL : ERROR_FLAG_NONE);
+ writer->write_uint24(writer, this->vendor_id);
+ writer->write_uint16(writer, this->error_code);
+ writer->write_uint16(writer, ERROR_RESERVED);
+
+ /* build message body */
+ if (this->error_code == PB_ERROR_VERSION_NOT_SUPPORTED)
+ {
+ /* Bad version */
+ writer->write_uint8(writer, this->bad_version);
+ writer->write_uint8(writer, PB_TNC_VERSION); /* Max version */
+ writer->write_uint8(writer, PB_TNC_VERSION); /* Min version */
+ writer->write_uint8(writer, 0x00); /* Reserved */
+ }
+ else
+ {
+ /* Error Offset */
+ writer->write_uint32(writer, this->error_offset);
+ }
+
+ free(this->encoding.ptr);
+ this->encoding = writer->get_buf(writer);
+ this->encoding = chunk_clone(this->encoding);
+ writer->destroy(writer);
+}
+
+METHOD(pb_tnc_msg_t, process, status_t,
+ private_pb_error_msg_t *this, u_int32_t *offset)
+{
+ u_int8_t flags, max_version, min_version;
+ u_int16_t reserved;
+ tls_reader_t *reader;
+
+ if (this->encoding.len < ERROR_HEADER_SIZE)
+ {
+ DBG1(DBG_TNC,"%N message is shorter than header size of %u bytes",
+ pb_tnc_msg_type_names, PB_MSG_ERROR, ERROR_HEADER_SIZE);
+ return FAILED;
+ }
+
+ /* process message header */
+ reader = tls_reader_create(this->encoding);
+ reader->read_uint8 (reader, &flags);
+ reader->read_uint24(reader, &this->vendor_id);
+ reader->read_uint16(reader, &this->error_code);
+ reader->read_uint16(reader, &reserved);
+ this->fatal = (flags & ERROR_FLAG_FATAL) != ERROR_FLAG_NONE;
+
+ if (this->vendor_id == IETF_VENDOR_ID && reader->remaining(reader) == 4)
+ {
+ if (this->error_code == PB_ERROR_VERSION_NOT_SUPPORTED)
+ {
+ reader->read_uint8(reader, &this->bad_version);
+ reader->read_uint8(reader, &max_version);
+ reader->read_uint8(reader, &min_version);
+ }
+ else
+ {
+ reader->read_uint32(reader, &this->error_offset);
+ }
+ }
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pb_tnc_msg_t, get_ref, pb_tnc_msg_t*,
+ private_pb_error_msg_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pb_interface;
+}
+
+METHOD(pb_tnc_msg_t, destroy, void,
+ private_pb_error_msg_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->encoding.ptr);
+ free(this);
+ }
+}
+
+METHOD(pb_error_msg_t, get_fatal_flag, bool,
+ private_pb_error_msg_t *this)
+{
+ return this->fatal;
+}
+
+METHOD(pb_error_msg_t, get_vendor_id, u_int32_t,
+ private_pb_error_msg_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pb_error_msg_t, get_error_code, u_int16_t,
+ private_pb_error_msg_t *this)
+{
+ return this->error_code;
+}
+
+METHOD(pb_error_msg_t, get_offset, u_int32_t,
+ private_pb_error_msg_t *this)
+{
+ return this->error_offset;
+}
+
+METHOD(pb_error_msg_t, get_bad_version, u_int8_t,
+ private_pb_error_msg_t *this)
+{
+ return this->bad_version;
+}
+
+METHOD(pb_error_msg_t, set_bad_version, void,
+ private_pb_error_msg_t *this, u_int8_t version)
+{
+ this->bad_version = version;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t* pb_error_msg_create(bool fatal, u_int32_t vendor_id,
+ pb_tnc_error_code_t error_code)
+{
+ private_pb_error_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_fatal_flag = _get_fatal_flag,
+ .get_vendor_id = _get_vendor_id,
+ .get_error_code = _get_error_code,
+ .get_offset = _get_offset,
+ .get_bad_version = _get_bad_version,
+ .set_bad_version = _set_bad_version,
+ },
+ .type = PB_MSG_ERROR,
+ .ref = 1,
+ .fatal = fatal,
+ .vendor_id = vendor_id,
+ .error_code = error_code,
+ );
+
+ return &this->public.pb_interface;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t* pb_error_msg_create_with_offset(bool fatal, u_int32_t vendor_id,
+ pb_tnc_error_code_t error_code,
+ u_int32_t error_offset)
+{
+ private_pb_error_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_fatal_flag = _get_fatal_flag,
+ .get_vendor_id = _get_vendor_id,
+ .get_error_code = _get_error_code,
+ .get_offset = _get_offset,
+ .get_bad_version = _get_bad_version,
+ .set_bad_version = _set_bad_version,
+ },
+ .type = PB_MSG_ERROR,
+ .ref = 1,
+ .fatal = fatal,
+ .vendor_id = vendor_id,
+ .error_code = error_code,
+ .error_offset = error_offset,
+ );
+
+ return &this->public.pb_interface;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_error_msg_create_from_data(chunk_t data)
+{
+ private_pb_error_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_fatal_flag = _get_fatal_flag,
+ .get_vendor_id = _get_vendor_id,
+ .get_error_code = _get_error_code,
+ .get_offset = _get_offset,
+ .get_bad_version = _get_bad_version,
+ .set_bad_version = _set_bad_version,
+ },
+ .type = PB_MSG_ERROR,
+ .ref = 1,
+ .encoding = chunk_clone(data),
+ );
+
+ return &this->public.pb_interface;
+}
+
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.h b/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.h
new file mode 100644
index 000000000..8b92742b5
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2010 Sansar Choinyambuu
+ * 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 pb_error_msg pb_error_msg
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef PB_ERROR_MSG_H_
+#define PB_ERROR_MSG_H_
+
+typedef enum pb_tnc_error_code_t pb_tnc_error_code_t;
+typedef struct pb_error_msg_t pb_error_msg_t;
+
+#include "pb_tnc_msg.h"
+
+/**
+ * PB-TNC Error Codes as defined in section 4.9.1 of RFC 5793
+ */
+enum pb_tnc_error_code_t {
+ PB_ERROR_UNEXPECTED_BATCH_TYPE = 0,
+ PB_ERROR_INVALID_PARAMETER = 1,
+ PB_ERROR_LOCAL_ERROR = 2,
+ PB_ERROR_UNSUPPORTED_MANDATORY_MSG = 3,
+ PB_ERROR_VERSION_NOT_SUPPORTED = 4
+};
+
+/**
+ * enum name for pb_tnc_error_code_t.
+ */
+extern enum_name_t *pb_tnc_error_code_names;
+
+/**
+ * Class representing the PB-Error message type.
+ */
+struct pb_error_msg_t {
+
+ /**
+ * PB-TNC Message interface
+ */
+ pb_tnc_msg_t pb_interface;
+
+ /**
+ * Get the fatal flag
+ *
+ * @return fatal flag
+ */
+ bool (*get_fatal_flag)(pb_error_msg_t *this);
+
+ /**
+ * Get PB Error code Vendor ID
+ *
+ * @return PB Error Code Vendor ID
+ */
+ u_int32_t (*get_vendor_id)(pb_error_msg_t *this);
+
+ /**
+ * Get PB Error Code
+ *
+ * @return PB Error Code
+ */
+ u_int16_t (*get_error_code)(pb_error_msg_t *this);
+
+ /**
+ * Get the PB Error Offset
+ *
+ * @return PB Error Offset
+ */
+ u_int32_t (*get_offset)(pb_error_msg_t *this);
+
+ /**
+ * Get the PB Bad Version
+ *
+ * @return PB Bad Version
+ */
+ u_int8_t (*get_bad_version)(pb_error_msg_t *this);
+
+ /**
+ * Set the PB Bad Version
+ *
+ * @param version PB Bad Version
+ */
+ void (*set_bad_version)(pb_error_msg_t *this, u_int8_t version);
+};
+
+/**
+ * Create a PB-Error message from parameters
+ *
+ * @param fatal fatal flag
+ * @param vendor_id Error Code Vendor ID
+ * @param error_code Error Code
+ */
+pb_tnc_msg_t* pb_error_msg_create(bool fatal, u_int32_t vendor_id,
+ pb_tnc_error_code_t error_code);
+
+/**
+ * Create a PB-Error message from parameters with offset field
+ *
+ * @param fatal fatal flag
+ * @param vendor_id Error Code Vendor ID
+ * @param error_code Error Code
+ * @param error_offset Error Offset
+ */
+pb_tnc_msg_t* pb_error_msg_create_with_offset(bool fatal, u_int32_t vendor_id,
+ pb_tnc_error_code_t error_code,
+ u_int32_t error_offset);
+
+/**
+ * Create an unprocessed PB-Error message from raw data
+ *
+ * @param data PB-Error message data
+ */
+pb_tnc_msg_t* pb_error_msg_create_from_data(chunk_t data);
+
+#endif /** PB_PA_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_experimental_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_experimental_msg.c
new file mode 100644
index 000000000..7dfba136f
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_experimental_msg.c
@@ -0,0 +1,102 @@
+/*
+ * 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 "pb_experimental_msg.h"
+
+typedef struct private_pb_experimental_msg_t private_pb_experimental_msg_t;
+
+/**
+ * Private data of a pb_experimental_msg_t object.
+ *
+ */
+struct private_pb_experimental_msg_t {
+ /**
+ * Public pb_experimental_msg_t interface.
+ */
+ pb_experimental_msg_t public;
+
+ /**
+ * PB-TNC message type
+ */
+ pb_tnc_msg_type_t type;
+
+ /**
+ * Encoded message
+ */
+ chunk_t encoding;
+};
+
+METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
+ private_pb_experimental_msg_t *this)
+{
+ return this->type;
+}
+
+METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
+ private_pb_experimental_msg_t *this)
+{
+ return this->encoding;
+}
+
+METHOD(pb_tnc_msg_t, build, void,
+ private_pb_experimental_msg_t *this)
+{
+ /* nothing to do since message contents equal encoding */
+}
+
+METHOD(pb_tnc_msg_t, process, status_t,
+ private_pb_experimental_msg_t *this, u_int32_t *offset)
+{
+ return SUCCESS;
+}
+
+METHOD(pb_tnc_msg_t, destroy, void,
+ private_pb_experimental_msg_t *this)
+{
+ free(this->encoding.ptr);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_experimental_msg_create_from_data(chunk_t data)
+{
+ private_pb_experimental_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ },
+ .type = PB_MSG_EXPERIMENTAL,
+ .encoding = chunk_clone(data),
+ );
+
+ return &this->public.pb_interface;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_experimental_msg_create(chunk_t body)
+{
+ return pb_experimental_msg_create_from_data(body);
+}
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_experimental_msg.h b/src/libcharon/plugins/tnccs_20/messages/pb_experimental_msg.h
new file mode 100644
index 000000000..b1cc4f46e
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_experimental_msg.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 Sansar Choinyambuu
+ * 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 pb_experimental_msg pb_experimental_msg
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef PB_EXPERIMENTAL_MSG_H_
+#define PB_EXPERIMENTAL_MSG_H_
+
+typedef struct pb_experimental_msg_t pb_experimental_msg_t;
+
+#include "pb_tnc_msg.h"
+
+/**
+ * Class representing the PB-Experimental message type.
+ */
+struct pb_experimental_msg_t {
+
+ /**
+ * PB-TNC Message interface
+ */
+ pb_tnc_msg_t pb_interface;
+};
+
+/**
+ * Create a PB-Experimental message from parameters
+ *
+ * @param body message body
+ */
+pb_tnc_msg_t* pb_experimental_msg_create(chunk_t body);
+
+/**
+ * Create an unprocessed PB-Experimental message from raw data
+ *
+ * @param data PB-Experimental message data
+ */
+pb_tnc_msg_t* pb_experimental_msg_create_from_data(chunk_t data);
+
+#endif /** PB_EXPERIMENTAL_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.c
new file mode 100644
index 000000000..9a94edf30
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2010 Sansar Choinyambuu
+ * 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 "pb_language_preference_msg.h"
+
+#include <tls_writer.h>
+#include <tls_reader.h>
+#include <debug.h>
+
+typedef struct private_pb_language_preference_msg_t private_pb_language_preference_msg_t;
+
+/**
+ * PB-Language-Preference message (see section 4.10 of RFC 5793)
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Language Preference (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PB_LANG_PREFIX "Accept-Language: "
+#define PB_LANG_PREFIX_LEN strlen(PB_LANG_PREFIX)
+
+/**
+ * Private data of a pb_language_preference_msg_t object.
+ *
+ */
+struct private_pb_language_preference_msg_t {
+ /**
+ * Public pb_access_recommendation_msg_t interface.
+ */
+ pb_language_preference_msg_t public;
+
+ /**
+ * PB-TNC message type
+ */
+ pb_tnc_msg_type_t type;
+
+ /**
+ * Language preference
+ */
+ chunk_t language_preference;
+
+ /**
+ * Encoded message
+ */
+ chunk_t encoding;
+};
+
+METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
+ private_pb_language_preference_msg_t *this)
+{
+ return this->type;
+}
+
+METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
+ private_pb_language_preference_msg_t *this)
+{
+ return this->encoding;
+}
+
+METHOD(pb_tnc_msg_t, build, void,
+ private_pb_language_preference_msg_t *this)
+{
+ this->encoding = chunk_cat("cc",
+ chunk_create(PB_LANG_PREFIX, PB_LANG_PREFIX_LEN),
+ this->language_preference);
+}
+
+METHOD(pb_tnc_msg_t, process, status_t,
+ private_pb_language_preference_msg_t *this, u_int32_t *offset)
+{
+ chunk_t lang;
+
+ if (this->encoding.len >= PB_LANG_PREFIX_LEN &&
+ memeq(this->encoding.ptr, PB_LANG_PREFIX, PB_LANG_PREFIX_LEN))
+ {
+ lang = chunk_skip(this->encoding, PB_LANG_PREFIX_LEN);
+ this->language_preference = lang.len ? chunk_clone(lang) : chunk_empty;
+ }
+ else
+ {
+ DBG1(DBG_TNC, "language preference must be preceded by '%s'",
+ PB_LANG_PREFIX);
+ *offset = 0;
+ return FAILED;
+ }
+
+ if (this->language_preference.len &&
+ this->language_preference.ptr[this->language_preference.len-1] == '\0')
+ {
+ DBG1(DBG_TNC, "language preference must not be null terminated");
+ *offset = PB_LANG_PREFIX_LEN + this->language_preference.len - 1;
+ return FAILED;
+ }
+
+ return SUCCESS;
+}
+
+METHOD(pb_tnc_msg_t, destroy, void,
+ private_pb_language_preference_msg_t *this)
+{
+ free(this->encoding.ptr);
+ free(this->language_preference.ptr);
+ free(this);
+}
+
+METHOD(pb_language_preference_msg_t, get_language_preference, chunk_t,
+ private_pb_language_preference_msg_t *this)
+{
+ return this->language_preference;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_language_preference_msg_create_from_data(chunk_t data)
+{
+ private_pb_language_preference_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_language_preference = _get_language_preference,
+ },
+ .type = PB_MSG_LANGUAGE_PREFERENCE,
+ .encoding = chunk_clone(data),
+ );
+
+ return &this->public.pb_interface;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_language_preference_msg_create(chunk_t language_preference)
+{
+ private_pb_language_preference_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_language_preference = _get_language_preference,
+ },
+ .type = PB_MSG_LANGUAGE_PREFERENCE,
+ .language_preference = chunk_clone(language_preference),
+ );
+
+ return &this->public.pb_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.h b/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.h
new file mode 100644
index 000000000..17106f6fa
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 Sansar Choinyambuu
+ * 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 pb_language_preference_msg pb_language_preference_msg
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef PB_LANGUAGE_PREFERENCE_MSG_H_
+#define PB_LANGUAGE_PREFERENCE_MSG_H_
+
+typedef struct pb_language_preference_msg_t pb_language_preference_msg_t;
+
+#include "pb_tnc_msg.h"
+
+/**
+ * Class representing the PB-Language-Preference message type.
+ */
+struct pb_language_preference_msg_t {
+
+ /**
+ * PB-TNC Message interface
+ */
+ pb_tnc_msg_t pb_interface;
+
+ /**
+ * Get PB Language Preference
+ *
+ * @return Language preference
+ */
+ chunk_t (*get_language_preference)(pb_language_preference_msg_t *this);
+};
+
+/**
+ * Create a PB-Language-Preference message from parameters
+ *
+ * @param language_preference Preferred language(s)
+ */
+pb_tnc_msg_t* pb_language_preference_msg_create(chunk_t language_preference);
+
+/**
+ * Create an unprocessed PB-Language-Preference message from raw data
+ *
+ * @param data PB-Language-Preference message data
+ */
+pb_tnc_msg_t* pb_language_preference_msg_create_from_data(chunk_t data);
+
+#endif /** PB_PA_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.c
new file mode 100644
index 000000000..8315bfb76
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.c
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2010 Sansar Choinyanbuu
+ * 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 "pb_pa_msg.h"
+
+#include <tls_writer.h>
+#include <tls_reader.h>
+#include <tnc/tnccs/tnccs.h>
+#include <debug.h>
+
+ENUM(pa_tnc_subtype_names, PA_SUBTYPE_TESTING, PA_SUBTYPE_NEA_CLIENT,
+ "Testing",
+ "Operating System",
+ "Anti-Virus",
+ "Anti-Spyware",
+ "Anti-Malware",
+ "Firewall",
+ "IDPS",
+ "VPN",
+ "NEA Client"
+);
+
+typedef struct private_pb_pa_msg_t private_pb_pa_msg_t;
+
+/**
+ * PB-PA message
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | PA Message Vendor ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | PA Subtype |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Posture Collector Identifier | Posture Validator Identifier |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | PA Message Body (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PA_FLAG_NONE 0x00
+#define PA_FLAG_EXCL (1<<7)
+#define PA_RESERVED_SUBTYPE 0xffffffff
+
+
+/**
+ * Private data of a pb_pa_msg_t object.
+ *
+ */
+struct private_pb_pa_msg_t {
+ /**
+ * Public pb_pa_msg_t interface.
+ */
+ pb_pa_msg_t public;
+
+ /**
+ * PB-TNC message type
+ */
+ pb_tnc_msg_type_t type;
+
+ /**
+ * Exclusive flag
+ */
+ bool excl;
+
+ /**
+ * PA Message Vendor ID
+ */
+ u_int32_t vendor_id;
+
+ /**
+ * PA Subtype
+ */
+ u_int32_t subtype;
+
+ /**
+ * Posture Validator Identifier
+ */
+ u_int16_t collector_id;
+
+ /**
+ * Posture Validator Identifier
+ */
+ u_int16_t validator_id;
+
+ /**
+ * PA Message Body
+ */
+ chunk_t msg_body;
+
+ /**
+ * Encoded message
+ */
+ chunk_t encoding;
+};
+
+METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
+ private_pb_pa_msg_t *this)
+{
+ return this->type;
+}
+
+METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
+ private_pb_pa_msg_t *this)
+{
+ return this->encoding;
+}
+
+METHOD(pb_tnc_msg_t, build, void,
+ private_pb_pa_msg_t *this)
+{
+ chunk_t msg_header;
+ tls_writer_t *writer;
+
+ /* build message header */
+ writer = tls_writer_create(64);
+ writer->write_uint8 (writer, this->excl ? PA_FLAG_EXCL : PA_FLAG_NONE);
+ writer->write_uint24(writer, this->vendor_id);
+ writer->write_uint32(writer, this->subtype);
+ writer->write_uint16(writer, this->collector_id);
+ writer->write_uint16(writer, this->validator_id);
+ msg_header = writer->get_buf(writer);
+
+ /* create encoding by concatenating message header and message body */
+ free(this->encoding.ptr);
+ this->encoding = chunk_cat("cc", msg_header, this->msg_body);
+ writer->destroy(writer);
+}
+
+METHOD(pb_tnc_msg_t, process, status_t,
+ private_pb_pa_msg_t *this, u_int32_t *offset)
+{
+ u_int8_t flags;
+ size_t msg_body_len;
+ tls_reader_t *reader;
+
+ /* process message header */
+ reader = tls_reader_create(this->encoding);
+ reader->read_uint8 (reader, &flags);
+ reader->read_uint24(reader, &this->vendor_id);
+ reader->read_uint32(reader, &this->subtype);
+ reader->read_uint16(reader, &this->collector_id);
+ reader->read_uint16(reader, &this->validator_id);
+ this->excl = ((flags & PA_FLAG_EXCL) != PA_FLAG_NONE);
+
+ /* process message body */
+ msg_body_len = reader->remaining(reader);
+ if (msg_body_len)
+ {
+ reader->read_data(reader, msg_body_len, &this->msg_body);
+ this->msg_body = chunk_clone(this->msg_body);
+ }
+ reader->destroy(reader);
+
+ if (this->vendor_id == RESERVED_VENDOR_ID)
+ {
+ DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", RESERVED_VENDOR_ID);
+ *offset = 1;
+ return FAILED;
+ }
+
+ if (this->subtype == PA_RESERVED_SUBTYPE)
+ {
+ DBG1(DBG_TNC, "PA Subtype 0x%08x is reserved", PA_RESERVED_SUBTYPE);
+ *offset = 4;
+ }
+
+ return SUCCESS;
+}
+
+METHOD(pb_tnc_msg_t, destroy, void,
+ private_pb_pa_msg_t *this)
+{
+ free(this->encoding.ptr);
+ free(this->msg_body.ptr);
+ free(this);
+}
+
+METHOD(pb_pa_msg_t, get_vendor_id, u_int32_t,
+ private_pb_pa_msg_t *this, u_int32_t *subtype)
+{
+ *subtype = this->subtype;
+ return this->vendor_id;
+}
+
+METHOD(pb_pa_msg_t, get_collector_id, u_int16_t,
+ private_pb_pa_msg_t *this)
+{
+ return this->collector_id;
+}
+
+METHOD(pb_pa_msg_t, get_validator_id, u_int16_t,
+ private_pb_pa_msg_t *this)
+{
+ return this->validator_id;
+}
+
+METHOD(pb_pa_msg_t, get_body, chunk_t,
+ private_pb_pa_msg_t *this)
+{
+ return this->msg_body;
+}
+
+METHOD(pb_pa_msg_t, get_exclusive_flag, bool,
+ private_pb_pa_msg_t *this)
+{
+ return this->excl;
+}
+
+METHOD(pb_pa_msg_t, set_exclusive_flag, void,
+ private_pb_pa_msg_t *this, bool excl)
+{
+ this->excl = excl;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_pa_msg_create_from_data(chunk_t data)
+{
+ private_pb_pa_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_vendor_id = _get_vendor_id,
+ .get_collector_id = _get_collector_id,
+ .get_validator_id = _get_validator_id,
+ .get_body = _get_body,
+ .get_exclusive_flag = _get_exclusive_flag,
+ .set_exclusive_flag = _set_exclusive_flag,
+ },
+ .type = PB_MSG_PA,
+ .encoding = chunk_clone(data),
+ );
+
+ return &this->public.pb_interface;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_pa_msg_create(u_int32_t vendor_id, u_int32_t subtype,
+ u_int16_t collector_id, u_int16_t validator_id,
+ chunk_t msg_body)
+{
+ private_pb_pa_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_vendor_id = _get_vendor_id,
+ .get_collector_id = _get_collector_id,
+ .get_validator_id = _get_validator_id,
+ .get_body = _get_body,
+ .get_exclusive_flag = _get_exclusive_flag,
+ .set_exclusive_flag = _set_exclusive_flag,
+ },
+ .type = PB_MSG_PA,
+ .vendor_id = vendor_id,
+ .subtype = subtype,
+ .collector_id = collector_id,
+ .validator_id = validator_id,
+ .msg_body = chunk_clone(msg_body),
+ );
+
+ return &this->public.pb_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.h b/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.h
new file mode 100644
index 000000000..366d790f6
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.h
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup pb_pa_msg pb_pa_msg
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef PB_PA_MSG_H_
+#define PB_PA_MSG_H_
+
+typedef enum pa_tnc_subtype_t pa_tnc_subtype_t;
+typedef struct pb_pa_msg_t pb_pa_msg_t;
+
+#include "pb_tnc_msg.h"
+
+/**
+ * PA-TNC Subtypes as defined in section 3.5 of RFC 5792
+ */
+ enum pa_tnc_subtype_t {
+ PA_SUBTYPE_TESTING = 0,
+ PA_SUBTYPE_OPERATING_SYSTEM = 1,
+ PA_SUBTYPE_ANTI_VIRUS = 2,
+ PA_SUBTYPE_ANTI_SPYWARE = 3,
+ PA_SUBTYPE_ANTI_MALWARE = 4,
+ PA_SUBTYPE_FIREWALL = 5,
+ PA_SUBTYPE_IDPS = 6,
+ PA_SUBTYPE_VPN = 7,
+ PA_SUBTYPE_NEA_CLIENT = 8
+};
+
+/**
+ * enum name for pa_tnc_subtype_t.
+ */
+extern enum_name_t *pa_tnc_subtype_names;
+
+/**
+ * Class representing the PB-PA message type.
+ */
+struct pb_pa_msg_t {
+
+ /**
+ * PB-TNC Message interface
+ */
+ pb_tnc_msg_t pb_interface;
+
+ /**
+ * Get PA Message Vendor ID and Subtype
+ *
+ * @param subtype PA Subtype
+ * @return PA Message Vendor ID
+ */
+ u_int32_t (*get_vendor_id)(pb_pa_msg_t *this, u_int32_t *subtype);
+
+ /**
+ * Get Posture Collector ID
+ *
+ * @return Posture Collector ID
+ */
+ u_int16_t (*get_collector_id)(pb_pa_msg_t *this);
+
+ /**
+ * Get Posture Validator ID
+ *
+ * @return Posture Validator ID
+ */
+ u_int16_t (*get_validator_id)(pb_pa_msg_t *this);
+
+ /**
+ * Get the PA Message Body
+ *
+ * @return PA Message Body
+ */
+ chunk_t (*get_body)(pb_pa_msg_t *this);
+
+ /**
+ * Get the exclusive flag
+ *
+ * @return exclusive flag
+ */
+ bool (*get_exclusive_flag)(pb_pa_msg_t *this);
+
+ /**
+ * Set the exclusive flag
+ *
+ * @param excl vexclusive flag
+ */
+ void (*set_exclusive_flag)(pb_pa_msg_t *this, bool excl);
+};
+
+/**
+ * Create a PB-PA message from parameters
+ *
+ * @param vendor_id PA Message Vendor ID
+ * @param subtype PA Subtype
+ * @param collector_id Posture Collector ID
+ * @param validator_id Posture Validator ID
+ * @param msg_body PA Message Body
+ */
+pb_tnc_msg_t *pb_pa_msg_create(u_int32_t vendor_id, u_int32_t subtype,
+ u_int16_t collector_id, u_int16_t validator_id,
+ chunk_t msg_body);
+
+/**
+ * Create an unprocessed PB-PA message from raw data
+ *
+ * @param data PB-PA message data
+ */
+pb_tnc_msg_t* pb_pa_msg_create_from_data(chunk_t data);
+
+#endif /** PB_PA_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.c
new file mode 100644
index 000000000..e361cf2b2
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2010 Sansar Choinyambuu
+ * 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 "pb_reason_string_msg.h"
+
+#include <tls_writer.h>
+#include <tls_reader.h>
+#include <debug.h>
+
+typedef struct private_pb_reason_string_msg_t private_pb_reason_string_msg_t;
+
+/**
+ * PB-Language-Preference message (see section 4.11 of RFC 5793)
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reason String Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reason String (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Lang Code Len | Reason String Language Code (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/**
+ * Private data of a pb_reason_string_msg_t object.
+ *
+ */
+struct private_pb_reason_string_msg_t {
+ /**
+ * Public pb_reason_string_msg_t interface.
+ */
+ pb_reason_string_msg_t public;
+
+ /**
+ * PB-TNC message type
+ */
+ pb_tnc_msg_type_t type;
+
+ /**
+ * Reason string
+ */
+ chunk_t reason_string;
+
+ /**
+ * Language code
+ */
+ chunk_t language_code;
+
+ /**
+ * Encoded message
+ */
+ chunk_t encoding;
+};
+
+METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
+ private_pb_reason_string_msg_t *this)
+{
+ return this->type;
+}
+
+METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
+ private_pb_reason_string_msg_t *this)
+{
+ return this->encoding;
+}
+
+METHOD(pb_tnc_msg_t, build, void,
+ private_pb_reason_string_msg_t *this)
+{
+ tls_writer_t *writer;
+
+ /* build message */
+ writer = tls_writer_create(64);
+ writer->write_data32(writer, this->reason_string);
+ writer->write_data8 (writer, this->language_code);
+
+ free(this->encoding.ptr);
+ this->encoding = writer->get_buf(writer);
+ this->encoding = chunk_clone(this->encoding);
+ writer->destroy(writer);
+}
+
+METHOD(pb_tnc_msg_t, process, status_t,
+ private_pb_reason_string_msg_t *this, u_int32_t *offset)
+{
+ tls_reader_t *reader;
+
+ /* process message */
+ reader = tls_reader_create(this->encoding);
+ if (!reader->read_data32(reader, &this->reason_string))
+ {
+ DBG1(DBG_TNC, "could not parse reason string");
+ reader->destroy(reader);
+ *offset = 0;
+ return FAILED;
+ };
+ this->reason_string = chunk_clone(this->reason_string);
+
+ if (this->reason_string.len &&
+ this->reason_string.ptr[this->reason_string.len-1] == '\0')
+ {
+ DBG1(DBG_TNC, "reason string must not be null terminated");
+ reader->destroy(reader);
+ *offset = 3 + this->reason_string.len;
+ return FAILED;
+ }
+
+ if (!reader->read_data8(reader, &this->language_code))
+ {
+ DBG1(DBG_TNC, "could not parse language code");
+ reader->destroy(reader);
+ *offset = 4 + this->reason_string.len;
+ return FAILED;
+ };
+ this->language_code = chunk_clone(this->language_code);
+ reader->destroy(reader);
+
+ if (this->language_code.len &&
+ this->language_code.ptr[this->language_code.len-1] == '\0')
+ {
+ DBG1(DBG_TNC, "language code must not be null terminated");
+ *offset = 4 + this->reason_string.len + this->language_code.len;
+ return FAILED;
+ }
+
+ return SUCCESS;
+}
+
+METHOD(pb_tnc_msg_t, destroy, void,
+ private_pb_reason_string_msg_t *this)
+{
+ free(this->encoding.ptr);
+ free(this->reason_string.ptr);
+ free(this->language_code.ptr);
+ free(this);
+}
+
+METHOD(pb_reason_string_msg_t, get_reason_string, chunk_t,
+ private_pb_reason_string_msg_t *this)
+{
+ return this->reason_string;
+}
+
+METHOD(pb_reason_string_msg_t, get_language_code, chunk_t,
+ private_pb_reason_string_msg_t *this)
+{
+ return this->language_code;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_reason_string_msg_create_from_data(chunk_t data)
+{
+ private_pb_reason_string_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_reason_string = _get_reason_string,
+ .get_language_code = _get_language_code,
+ },
+ .type = PB_MSG_REASON_STRING,
+ .encoding = chunk_clone(data),
+ );
+
+ return &this->public.pb_interface;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_reason_string_msg_create(chunk_t reason_string,
+ chunk_t language_code)
+{
+ private_pb_reason_string_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_reason_string = _get_reason_string,
+ .get_language_code = _get_language_code,
+ },
+ .type = PB_MSG_REASON_STRING,
+ .reason_string = chunk_clone(reason_string),
+ .language_code = chunk_clone(language_code),
+ );
+
+ return &this->public.pb_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.h b/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.h
new file mode 100644
index 000000000..bb296a90c
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010 Sansar Choinyambuu
+ * 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 pb_reason_string_msg pb_reason_string_msg
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef PB_REASON_STRING_MSG_H_
+#define PB_REASON_STRING_MSG_H_
+
+typedef struct pb_reason_string_msg_t pb_reason_string_msg_t;
+
+#include "pb_tnc_msg.h"
+
+/**
+ * Class representing the PB-Reason-String message type.
+ */
+struct pb_reason_string_msg_t {
+
+ /**
+ * PB-TNC Message interface
+ */
+ pb_tnc_msg_t pb_interface;
+
+ /**
+ * Get Reason String
+ *
+ * @return Reason string
+ */
+ chunk_t (*get_reason_string)(pb_reason_string_msg_t *this);
+
+ /**
+ * Get Reason String Language Code
+ *
+ * @return Language code
+ */
+ chunk_t (*get_language_code)(pb_reason_string_msg_t *this);
+};
+
+/**
+ * Create a PB-Reason-String message from parameters
+ *
+ * @param reason_string Reason string
+ * @param language_code Language code
+ */
+pb_tnc_msg_t* pb_reason_string_msg_create(chunk_t reason_string,
+ chunk_t language_code);
+
+/**
+ * Create an unprocessed PB-Reason-String message from raw data
+ *
+ * @param data PB-Reason-String message data
+ */
+pb_tnc_msg_t* pb_reason_string_msg_create_from_data(chunk_t data);
+
+#endif /** PB_PA_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c
new file mode 100644
index 000000000..79381a7b1
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c
@@ -0,0 +1,259 @@
+/*
+ * 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 "pb_remediation_parameters_msg.h"
+
+#include <tls_writer.h>
+#include <tls_reader.h>
+#include <debug.h>
+
+ENUM(pb_tnc_remed_param_type_names, PB_REMEDIATION_URI, PB_REMEDIATION_STRING,
+ "Remediation-URI",
+ "Remediation-String"
+);
+
+typedef struct private_pb_remediation_parameters_msg_t private_pb_remediation_parameters_msg_t;
+
+/**
+ * PB-Remediation-Parameters message (see section 4.8 of RFC 5793)
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved | Remediation Parameters Vendor ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Remediation Parameters Type |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Remediation Parameters (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Remediation String Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Remediation String (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Lang Code Len | Remediation String Lang Code (Variable Len) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/**
+ * Private data of a pb_remediation_parameters_msg_t object.
+ *
+ */
+struct private_pb_remediation_parameters_msg_t {
+ /**
+ * Public pb_remediation_parameters_msg_t interface.
+ */
+ pb_remediation_parameters_msg_t public;
+
+ /**
+ * PB-TNC message type
+ */
+ pb_tnc_msg_type_t type;
+
+ /**
+ * Remediation Parameters Vendor ID
+ */
+ u_int32_t vendor_id;
+
+ /**
+ * Remediation Parameters Type
+ */
+ u_int32_t parameters_type;
+
+ /**
+ * Remediation Parameters string
+ */
+ chunk_t remediation_string;
+
+ /**
+ * Language code
+ */
+ chunk_t language_code;
+
+ /**
+ * Encoded message
+ */
+ chunk_t encoding;
+};
+
+METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
+ private_pb_remediation_parameters_msg_t *this)
+{
+ return this->type;
+}
+
+METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
+ private_pb_remediation_parameters_msg_t *this)
+{
+ return this->encoding;
+}
+
+METHOD(pb_tnc_msg_t, build, void,
+ private_pb_remediation_parameters_msg_t *this)
+{
+ tls_writer_t *writer;
+
+ /* build message */
+ writer = tls_writer_create(64);
+ writer->write_uint32(writer, this->vendor_id);
+ writer->write_uint32(writer, this->parameters_type);
+ writer->write_data32(writer, this->remediation_string);
+ writer->write_data8 (writer, this->language_code);
+
+ free(this->encoding.ptr);
+ this->encoding = writer->get_buf(writer);
+ this->encoding = chunk_clone(this->encoding);
+ writer->destroy(writer);
+}
+
+METHOD(pb_tnc_msg_t, process, status_t,
+ private_pb_remediation_parameters_msg_t *this, u_int32_t *offset)
+{
+ tls_reader_t *reader;
+
+ /* process message */
+ reader = tls_reader_create(this->encoding);
+ reader->read_uint32(reader, &this->vendor_id);
+ reader->read_uint32(reader, &this->parameters_type);
+
+ if (!reader->read_data32(reader, &this->remediation_string))
+ {
+ DBG1(DBG_TNC, "could not parse remediation string");
+ reader->destroy(reader);
+ *offset = 8;
+ return FAILED;
+ };
+ this->remediation_string = chunk_clone(this->remediation_string);
+
+ if (this->remediation_string.len &&
+ this->remediation_string.ptr[this->remediation_string.len-1] == '\0')
+ {
+ DBG1(DBG_TNC, "remediation string must not be null terminated");
+ reader->destroy(reader);
+ *offset = 11 + this->remediation_string.len;
+ return FAILED;
+ }
+
+ if (!reader->read_data8(reader, &this->language_code))
+ {
+ DBG1(DBG_TNC, "could not parse language code");
+ reader->destroy(reader);
+ *offset = 12 + this->remediation_string.len;
+ return FAILED;
+ };
+ this->language_code = chunk_clone(this->language_code);
+ reader->destroy(reader);
+
+ if (this->language_code.len &&
+ this->language_code.ptr[this->language_code.len-1] == '\0')
+ {
+ DBG1(DBG_TNC, "language code must not be null terminated");
+ *offset = 12 + this->remediation_string.len + this->language_code.len;
+ return FAILED;
+ }
+
+ return SUCCESS;
+}
+
+METHOD(pb_tnc_msg_t, destroy, void,
+ private_pb_remediation_parameters_msg_t *this)
+{
+ free(this->encoding.ptr);
+ free(this->remediation_string.ptr);
+ free(this->language_code.ptr);
+ free(this);
+}
+
+METHOD(pb_remediation_parameters_msg_t, get_vendor_id, u_int32_t,
+ private_pb_remediation_parameters_msg_t *this, u_int32_t *type)
+{
+ *type = this->parameters_type;
+ return this->vendor_id;
+}
+
+METHOD(pb_remediation_parameters_msg_t, get_remediation_string, chunk_t,
+ private_pb_remediation_parameters_msg_t *this)
+{
+ return this->remediation_string;
+}
+
+METHOD(pb_remediation_parameters_msg_t, get_language_code, chunk_t,
+ private_pb_remediation_parameters_msg_t *this)
+{
+ return this->language_code;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_remediation_parameters_msg_create_from_data(chunk_t data)
+{
+ private_pb_remediation_parameters_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_vendor_id = _get_vendor_id,
+ .get_remediation_string = _get_remediation_string,
+ .get_language_code = _get_language_code,
+ },
+ .type = PB_MSG_REASON_STRING,
+ .encoding = chunk_clone(data),
+ );
+
+ return &this->public.pb_interface;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t* pb_remediation_parameters_msg_create(u_int32_t vendor_id,
+ u_int32_t type,
+ chunk_t remediation_string,
+ chunk_t language_code)
+{
+ private_pb_remediation_parameters_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_vendor_id = _get_vendor_id,
+ .get_remediation_string = _get_remediation_string,
+ .get_language_code = _get_language_code,
+ },
+ .type = PB_MSG_REASON_STRING,
+ .vendor_id = vendor_id,
+ .parameters_type = type,
+ .remediation_string = chunk_clone(remediation_string),
+ .language_code = chunk_clone(language_code),
+ );
+
+ return &this->public.pb_interface;
+}
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.h b/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.h
new file mode 100644
index 000000000..258d495ec
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.h
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup pb_remediation_parameters_msg pb_remediation_parameters_msg
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef PB_REMEDIATION_PARAMETERS_MSG_H_
+#define PB_REMEDIATION_PARAMETERS_MSG_H_
+
+typedef enum pb_tnc_remed_param_type_t pb_tnc_remed_param_type_t;
+typedef struct pb_remediation_parameters_msg_t pb_remediation_parameters_msg_t;
+
+#include "pb_tnc_msg.h"
+
+/**
+ * PB-TNC Remediation Parameter Types as defined in section 4.8.1 of RFC 5793
+ */
+enum pb_tnc_remed_param_type_t {
+ PB_REMEDIATION_URI = 1,
+ PB_REMEDIATION_STRING = 2,
+};
+
+/**
+ * enum name for pb_tnc_remed_param_type_t.
+ */
+extern enum_name_t *pb_tnc_remed_param_type_names;
+
+/**
+ * Class representing the PB-Remediation-Parameters message type.
+ */
+struct pb_remediation_parameters_msg_t {
+
+ /**
+ * PB-TNC Message interface
+ */
+ pb_tnc_msg_t pb_interface;
+
+ /**
+ * Get Remediation Parameters Vendor ID and Type
+ *
+ * @param type Remediation Parameters Type
+ * @return Remediation Parameters Vendor ID
+ */
+ u_int32_t (*get_vendor_id)(pb_remediation_parameters_msg_t *this,
+ u_int32_t *type);
+
+ /**
+ * Get Remediation String
+ *
+ * @return Remediation String
+ */
+ chunk_t (*get_remediation_string)(pb_remediation_parameters_msg_t *this);
+
+ /**
+ * Get Reason String Language Code
+ *
+ * @return Language Code
+ */
+ chunk_t (*get_language_code)(pb_remediation_parameters_msg_t *this);
+};
+
+/**
+ * Create a PB-Remediation-Parameters message from parameters
+ *
+ * @param vendor_id Remediation Parameters Vendor ID
+ * @param type Remediation Parameters Type
+ * @param remediation_string Remediation String
+ * @param language_code Language Code
+ */
+pb_tnc_msg_t* pb_remediation_parameters_msg_create(u_int32_t vendor_id,
+ u_int32_t type,
+ chunk_t remediation_string,
+ chunk_t language_code);
+
+/**
+ * Create an unprocessed PB-Remediation-Parameters message from raw data
+ *
+ * @param data PB-Remediation-Parameters message data
+ */
+pb_tnc_msg_t* pb_remediation_parameters_msg_create_from_data(chunk_t data);
+
+#endif /** PB_PA_MSG_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_tnc_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_tnc_msg.c
new file mode 100644
index 000000000..3565c2d84
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_tnc_msg.c
@@ -0,0 +1,75 @@
+/*
+ * 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 "pb_tnc_msg.h"
+#include "pb_experimental_msg.h"
+#include "pb_pa_msg.h"
+#include "pb_error_msg.h"
+#include "pb_language_preference_msg.h"
+#include "pb_assessment_result_msg.h"
+#include "pb_access_recommendation_msg.h"
+#include "pb_remediation_parameters_msg.h"
+#include "pb_reason_string_msg.h"
+
+#include <library.h>
+
+ENUM(pb_tnc_msg_type_names, PB_MSG_EXPERIMENTAL, PB_MSG_REASON_STRING,
+ "PB-Experimental",
+ "PB-PA",
+ "PB-Assessment-Result",
+ "PB-Access-Recommendation",
+ "PB-Remediation-Parameters",
+ "PB-Error",
+ "PB-Language-Preference",
+ "PB-Reason-String"
+);
+
+pb_tnc_msg_info_t pb_tnc_msg_infos[] = {
+ { 12, FALSE, FALSE, TRUE_OR_FALSE },
+ { 24, FALSE, FALSE, TRUE },
+ { 16, TRUE, TRUE, TRUE },
+ { 16, TRUE, TRUE, FALSE },
+ { 20, FALSE, TRUE, FALSE },
+ { 20, FALSE, FALSE, TRUE },
+ { 12, FALSE, FALSE, FALSE },
+ { 17, FALSE, TRUE, FALSE },
+};
+
+/**
+ * See header
+ */
+pb_tnc_msg_t* pb_tnc_msg_create_from_data(pb_tnc_msg_type_t type, chunk_t value)
+{
+ switch (type)
+ {
+ case PB_MSG_PA:
+ return pb_pa_msg_create_from_data(value);
+ case PB_MSG_ERROR:
+ return pb_error_msg_create_from_data(value);
+ case PB_MSG_EXPERIMENTAL:
+ return pb_experimental_msg_create_from_data(value);
+ case PB_MSG_LANGUAGE_PREFERENCE:
+ return pb_language_preference_msg_create_from_data(value);
+ case PB_MSG_ASSESSMENT_RESULT:
+ return pb_assessment_result_msg_create_from_data(value);
+ case PB_MSG_ACCESS_RECOMMENDATION:
+ return pb_access_recommendation_msg_create_from_data(value);
+ case PB_MSG_REMEDIATION_PARAMETERS:
+ return pb_remediation_parameters_msg_create_from_data(value);
+ case PB_MSG_REASON_STRING:
+ return pb_reason_string_msg_create_from_data(value);
+ }
+ return NULL;
+}
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_tnc_msg.h b/src/libcharon/plugins/tnccs_20/messages/pb_tnc_msg.h
new file mode 100644
index 000000000..e20c8d8ff
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_tnc_msg.h
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup pb_tnc_msg pb_tnc_msg
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef PB_TNC_MSG_H_
+#define PB_TNC_MSG_H_
+
+typedef enum pb_tnc_msg_type_t pb_tnc_msg_type_t;
+typedef struct pb_tnc_msg_info_t pb_tnc_msg_info_t;
+typedef struct pb_tnc_msg_t pb_tnc_msg_t;
+
+#include <library.h>
+
+#define PB_TNC_VERSION 2
+
+/**
+ * PB-TNC Message Types as defined in section 4.3 of RFC 5793
+ */
+enum pb_tnc_msg_type_t {
+ PB_MSG_EXPERIMENTAL = 0,
+ PB_MSG_PA = 1,
+ PB_MSG_ASSESSMENT_RESULT = 2,
+ PB_MSG_ACCESS_RECOMMENDATION = 3,
+ PB_MSG_REMEDIATION_PARAMETERS = 4,
+ PB_MSG_ERROR = 5,
+ PB_MSG_LANGUAGE_PREFERENCE = 6,
+ PB_MSG_REASON_STRING = 7,
+ PB_MSG_ROOF = 7
+};
+
+/**
+ * enum name for pb_tnc_msg_type_t.
+ */
+extern enum_name_t *pb_tnc_msg_type_names;
+
+/**
+ * Information entry describing a PB-TNC Message Type
+ */
+struct pb_tnc_msg_info_t {
+ u_int32_t min_size;
+ bool exact_size;
+ bool in_result_batch;
+ bool has_noskip_flag;
+};
+
+#define TRUE_OR_FALSE 2
+
+/**
+ * Information on PB-TNC Message Types
+ */
+extern pb_tnc_msg_info_t pb_tnc_msg_infos[];
+
+/**
+ * Generic interface for all PB-TNC message types.
+ *
+ * To handle all messages in a generic way, this interface
+ * must be implemented by each message type.
+ */
+struct pb_tnc_msg_t {
+
+ /**
+ * Get the PB-TNC Message Type
+ *
+ * @return PB-TNC Message Type
+ */
+ pb_tnc_msg_type_t (*get_type)(pb_tnc_msg_t *this);
+
+ /**
+ * Get the encoding of the PB-TNC Message Value
+ *
+ * @return encoded PB-TNC Message Value
+ */
+ chunk_t (*get_encoding)(pb_tnc_msg_t *this);
+
+ /**
+ * Build the PB-TNC Message Value
+ */
+ void (*build)(pb_tnc_msg_t *this);
+
+ /**
+ * Process the PB-TNC Message Value
+ *
+ * @param relative offset where an error occurred
+ * @return return processing status
+ */
+ status_t (*process)(pb_tnc_msg_t *this, u_int32_t *offset);
+
+ /**
+ * Get a new reference to the message.
+ *
+ * @return this, with an increased refcount
+ */
+ pb_tnc_msg_t* (*get_ref)(pb_tnc_msg_t *this);
+
+ /**
+ * Destroys a pb_tnc_msg_t object.
+ */
+ void (*destroy)(pb_tnc_msg_t *this);
+};
+
+/**
+ * Create an unprocessed PB-TNC message
+ *
+ * Useful for the parser which wants a generic constructor for all
+ * pb_tnc_message_t types.
+ *
+ * @param type PB-TNC message type
+ * @param value PB-TNC message value
+ */
+pb_tnc_msg_t* pb_tnc_msg_create_from_data(pb_tnc_msg_type_t type, chunk_t value);
+
+#endif /** PB_TNC_MSG_H_ @}*/
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
new file mode 100644
index 000000000..a46dc0ab9
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.c
@@ -0,0 +1,287 @@
+/*
+ * 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 "pb_tnc_state_machine.h"
+
+#include <debug.h>
+
+ENUM(pb_tnc_state_names, PB_STATE_INIT, PB_STATE_END,
+ "Init",
+ "Server Working",
+ "Client Working",
+ "Decided",
+ "End"
+);
+
+/**
+ * PB-TNC State Machine (see section 3.2 of RFC 5793)
+ *
+ * Receive CRETRY SRETRY
+ * or SRETRY +----------------+
+ * +--+ | |
+ * v | v |
+ * +---------+ CRETRY +---------+
+ * CDATA | Server |<---------| Decided | CLOSE
+ * +----------->| Working |--------->| |-------+
+ * | +---------+ RESULT +---------+ |
+ * | ^ | | v
+ * | | | +---------------------->=======
+ * ======== | | CLOSE " End "
+ * " Init " CDATA| |SDATA =======
+ * ======== | | ^ ^
+ * | | | v | |
+ * | | SDATA +---------+ CLOSE | |
+ * | +-------->| Client |----------------------+ |
+ * | | Working | |
+ * | +---------+ |
+ * | | ^ |
+ * | +--+ |
+ * | Receive CRETRY |
+ * | CLOSE |
+ * +--------------------------------------------------+
+ */
+
+typedef struct private_pb_tnc_state_machine_t private_pb_tnc_state_machine_t;
+
+/**
+ * Private data of a pb_tnc_state_machine_t object.
+ *
+ */
+struct private_pb_tnc_state_machine_t {
+ /**
+ * Public pb_pa_message_t interface.
+ */
+ pb_tnc_state_machine_t public;
+
+ /**
+ * PB-TNC Server if TRUE, PB-TNC Client if FALSE
+ */
+ bool is_server;
+
+ /**
+ * Current PB-TNC state
+ */
+ pb_tnc_state_t state;
+};
+
+METHOD(pb_tnc_state_machine_t, get_state, pb_tnc_state_t,
+ private_pb_tnc_state_machine_t *this)
+{
+ return this->state;
+}
+
+METHOD(pb_tnc_state_machine_t, receive_batch, bool,
+ private_pb_tnc_state_machine_t *this, pb_tnc_batch_type_t type)
+{
+ pb_tnc_state_t old_state = this->state;
+
+ switch (this->state)
+ {
+ case PB_STATE_INIT:
+ if (this->is_server && type == PB_BATCH_CDATA)
+ {
+ this->state = PB_STATE_SERVER_WORKING;
+ break;
+ }
+ if (!this->is_server && type == PB_BATCH_SDATA)
+ {
+ this->state = PB_STATE_CLIENT_WORKING;
+ break;
+ }
+ if (type == PB_BATCH_CLOSE)
+ {
+ this->state = PB_STATE_END;
+ break;
+ }
+ return FALSE;
+ case PB_STATE_SERVER_WORKING:
+ if (!this->is_server && type == PB_BATCH_SDATA)
+ {
+ this->state = PB_STATE_CLIENT_WORKING;
+ break;
+ }
+ if (!this->is_server && type == PB_BATCH_RESULT)
+ {
+ this->state = PB_STATE_DECIDED;
+ break;
+ }
+ if ((this->is_server && type == PB_BATCH_CRETRY) ||
+ (!this->is_server && type == PB_BATCH_SRETRY))
+ {
+ break;
+ }
+ if (type == PB_BATCH_CLOSE)
+ {
+ this->state = PB_STATE_END;
+ break;
+ }
+ return FALSE;
+ case PB_STATE_CLIENT_WORKING:
+ if (this->is_server && type == PB_BATCH_CDATA)
+ {
+ this->state = PB_STATE_SERVER_WORKING;
+ break;
+ }
+ if (this->is_server && type == PB_BATCH_CRETRY)
+ {
+ break;
+ }
+ if (type == PB_BATCH_CLOSE)
+ {
+ this->state = PB_STATE_END;
+ break;
+ }
+ return FALSE;
+ case PB_STATE_DECIDED:
+ if ((this->is_server && type == PB_BATCH_CRETRY) ||
+ (!this->is_server && type == PB_BATCH_SRETRY))
+ {
+ this->state = PB_STATE_SERVER_WORKING;
+ break;
+ }
+ if (type == PB_BATCH_CLOSE)
+ {
+ this->state = PB_STATE_END;
+ break;
+ }
+ return FALSE;
+ case PB_STATE_END:
+ if (type == PB_BATCH_CLOSE)
+ {
+ break;
+ }
+ return FALSE;
+ }
+
+ if (this->state != old_state)
+ {
+ DBG2(DBG_TNC, "PB-TNC state transition from '%N' to '%N'",
+ pb_tnc_state_names, old_state, pb_tnc_state_names, this->state);
+ }
+ return TRUE;
+}
+
+METHOD(pb_tnc_state_machine_t, send_batch, bool,
+ private_pb_tnc_state_machine_t *this, pb_tnc_batch_type_t type)
+{
+ pb_tnc_state_t old_state = this->state;
+
+ switch (this->state)
+ {
+ case PB_STATE_INIT:
+ if (!this->is_server && type == PB_BATCH_CDATA)
+ {
+ this->state = PB_STATE_SERVER_WORKING;
+ break;
+ }
+ if (this->is_server && type == PB_BATCH_SDATA)
+ {
+ this->state = PB_STATE_CLIENT_WORKING;
+ break;
+ }
+ if (type == PB_BATCH_CLOSE)
+ {
+ this->state = PB_STATE_END;
+ break;
+ }
+ return FALSE;
+ case PB_STATE_SERVER_WORKING:
+ if (this->is_server && type == PB_BATCH_SDATA)
+ {
+ this->state = PB_STATE_CLIENT_WORKING;
+ break;
+ }
+ if (this->is_server && type == PB_BATCH_RESULT)
+ {
+ this->state = PB_STATE_DECIDED;
+ break;
+ }
+ if (this->is_server && type == PB_BATCH_SRETRY)
+ {
+ break;
+ }
+ if (type == PB_BATCH_CLOSE)
+ {
+ this->state = PB_STATE_END;
+ break;
+ }
+ return FALSE;
+ case PB_STATE_CLIENT_WORKING:
+ if (!this->is_server && type == PB_BATCH_CDATA)
+ {
+ this->state = PB_STATE_SERVER_WORKING;
+ break;
+ }
+ if (type == PB_BATCH_CLOSE)
+ {
+ this->state = PB_STATE_END;
+ break;
+ }
+ return FALSE;
+ case PB_STATE_DECIDED:
+ if ((this->is_server && type == PB_BATCH_SRETRY) ||
+ (!this->is_server && type == PB_BATCH_CRETRY))
+ {
+ this->state = PB_STATE_SERVER_WORKING;
+ break;
+ }
+ if (type == PB_BATCH_CLOSE)
+ {
+ this->state = PB_STATE_END;
+ break;
+ }
+ return FALSE;
+ case PB_STATE_END:
+ if (type == PB_BATCH_CLOSE)
+ {
+ break;
+ }
+ return FALSE;
+ }
+
+ if (this->state != old_state)
+ {
+ DBG2(DBG_TNC, "PB-TNC state transition from '%N' to '%N'",
+ pb_tnc_state_names, old_state, pb_tnc_state_names, this->state);
+ }
+ return TRUE;
+}
+
+METHOD(pb_tnc_state_machine_t, destroy, void,
+ private_pb_tnc_state_machine_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header
+ */
+pb_tnc_state_machine_t* pb_tnc_state_machine_create(bool is_server)
+{
+ private_pb_tnc_state_machine_t *this;
+
+ INIT(this,
+ .public = {
+ .get_state = _get_state,
+ .receive_batch = _receive_batch,
+ .send_batch = _send_batch,
+ .destroy = _destroy,
+ },
+ .is_server = is_server,
+ .state = PB_STATE_INIT,
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.h b/src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.h
new file mode 100644
index 000000000..8076b6ded
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.h
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup pb_tnc_state_machine pb_tnc_state_machine
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef PB_TNC_STATE_MACHINE_H_
+#define PB_TNC_STATE_MACHINE_H_
+
+typedef struct pb_tnc_state_machine_t pb_tnc_state_machine_t;
+typedef enum pb_tnc_state_t pb_tnc_state_t;
+
+#include "batch/pb_tnc_batch.h"
+
+#include <library.h>
+
+/**
+ * PB-TNC States (state machine) as defined in section 3.2 of RFC 5793
+ */
+enum pb_tnc_state_t {
+ PB_STATE_INIT,
+ PB_STATE_SERVER_WORKING,
+ PB_STATE_CLIENT_WORKING,
+ PB_STATE_DECIDED,
+ PB_STATE_END,
+};
+
+/**
+ * enum name for pb_tnc_state_t.
+ */
+extern enum_name_t *pb_tnc_state_names;
+
+/**
+ * Interface for the PB-TNC state machine.
+ */
+struct pb_tnc_state_machine_t {
+
+ /**
+ * Get the current PB-TNC STATE
+ *
+ * @return current state
+ */
+ pb_tnc_state_t (*get_state)(pb_tnc_state_machine_t *this);
+
+ /**
+ * Compute state transition due to received PB-TNC Batch
+ *
+ * @param type type of received batch
+ * @result TRUE if a valid transition was found, FALSE otherwise
+ */
+ bool (*receive_batch)(pb_tnc_state_machine_t *this, pb_tnc_batch_type_t type);
+
+ /**
+ * Compute state transition due to sent PB-TNC Batch
+ *
+ * @param type type of sent batch
+ * @result TRUE if a valid transition was found, FALSE otherwise
+ */
+ bool (*send_batch)(pb_tnc_state_machine_t *this, pb_tnc_batch_type_t type);
+
+ /**
+ * Destroys a pb_tnc_state_machine_t object.
+ */
+ void (*destroy)(pb_tnc_state_machine_t *this);
+};
+
+/**
+ * Create and initialize a PB-TNC state machine
+ *
+ * @param is_server TRUE if PB-TNC server, FALSE if PB-TNC client
+ */
+pb_tnc_state_machine_t* pb_tnc_state_machine_create(bool is_server);
+
+#endif /** PB_TNC_STATE_MACHINE_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_20/tnccs_20.c b/src/libcharon/plugins/tnccs_20/tnccs_20.c
index 2bd1bc476..d53fd8eb7 100644
--- a/src/libcharon/plugins/tnccs_20/tnccs_20.c
+++ b/src/libcharon/plugins/tnccs_20/tnccs_20.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2010 Sansar Choinyanbuu
* Copyright (C) 2010 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
@@ -14,10 +15,23 @@
*/
#include "tnccs_20.h"
+#include "batch/pb_tnc_batch.h"
+#include "messages/pb_tnc_msg.h"
+#include "messages/pb_pa_msg.h"
+#include "messages/pb_error_msg.h"
+#include "messages/pb_assessment_result_msg.h"
+#include "messages/pb_access_recommendation_msg.h"
+#include "messages/pb_remediation_parameters_msg.h"
+#include "messages/pb_reason_string_msg.h"
+#include "messages/pb_language_preference_msg.h"
+#include "state_machine/pb_tnc_state_machine.h"
#include <debug.h>
-
-static chunk_t tncc_output;
+#include <daemon.h>
+#include <threading/mutex.h>
+#include <tnc/tncif.h>
+#include <tnc/tncifimv.h>
+#include <tnc/tnccs/tnccs.h>
typedef struct private_tnccs_20_t private_tnccs_20_t;
@@ -35,18 +49,541 @@ struct private_tnccs_20_t {
* TNCC if TRUE, TNCS if FALSE
*/
bool is_server;
+
+ /**
+ * PB-TNC State Machine
+ */
+ pb_tnc_state_machine_t *state_machine;
+
+ /**
+ * Connection ID assigned to this TNCCS connection
+ */
+ TNC_ConnectionID connection_id;
+
+ /**
+ * PB-TNC batch being constructed
+ */
+ pb_tnc_batch_t *batch;
+
+ /**
+ * Mutex locking the batch in construction
+ */
+ mutex_t *mutex;
+
+ /**
+ * Flag set while processing
+ */
+ bool fatal_error;
+
+ /**
+ * Flag set by IMC/IMV RequestHandshakeRetry() function
+ */
+ bool request_handshake_retry;
+
+ /**
+ * Set of IMV recommendations (TNC Server only)
+ */
+ recommendations_t *recs;
};
+METHOD(tnccs_t, send_msg, void,
+ private_tnccs_20_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_MessageType msg_type)
+{
+ TNC_MessageSubtype msg_sub_type;
+ TNC_VendorID msg_vendor_id;
+ pb_tnc_msg_t *pb_tnc_msg;
+ pb_tnc_batch_type_t batch_type;
+
+ msg_sub_type = msg_type & TNC_SUBTYPE_ANY;
+ msg_vendor_id = (msg_type >> 8) & TNC_VENDORID_ANY;
+
+ pb_tnc_msg = pb_pa_msg_create(msg_vendor_id, msg_sub_type, imc_id, imv_id,
+ chunk_create(msg, msg_len));
+
+ /* adding PA message to SDATA or CDATA batch only */
+ batch_type = this->is_server ? PB_BATCH_SDATA : PB_BATCH_CDATA;
+ this->mutex->lock(this->mutex);
+ if (!this->batch)
+ {
+ this->batch = pb_tnc_batch_create(this->is_server, batch_type);
+ }
+ if (this->batch->get_type(this->batch) == batch_type)
+ {
+ this->batch->add_msg(this->batch, pb_tnc_msg);
+ }
+ else
+ {
+ pb_tnc_msg->destroy(pb_tnc_msg);
+ }
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Handle a single PB-TNC message according to its type
+ */
+static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
+{
+ switch (msg->get_type(msg))
+ {
+ case PB_MSG_EXPERIMENTAL:
+ /* nothing to do */
+ break;
+ case PB_MSG_PA:
+ {
+ pb_pa_msg_t *pa_msg;
+ TNC_MessageType msg_type;
+ u_int32_t vendor_id, subtype;
+ chunk_t msg_body;
+
+ pa_msg = (pb_pa_msg_t*)msg;
+ vendor_id = pa_msg->get_vendor_id(pa_msg, &subtype);
+ msg_type = (vendor_id << 8) | (subtype & 0xff);
+ msg_body = pa_msg->get_body(pa_msg);
+
+ DBG2(DBG_TNC, "handling PB-PA message type 0x%08x", msg_type);
+
+ if (this->is_server)
+ {
+ charon->imvs->receive_message(charon->imvs,
+ this->connection_id, msg_body.ptr, msg_body.len, msg_type);
+ }
+ else
+ {
+ charon->imcs->receive_message(charon->imcs,
+ this->connection_id, msg_body.ptr, msg_body.len,msg_type);
+ }
+ break;
+ }
+ case PB_MSG_ASSESSMENT_RESULT:
+ {
+ pb_assessment_result_msg_t *assess_msg;
+ u_int32_t result;
+
+ assess_msg = (pb_assessment_result_msg_t*)msg;
+ result = assess_msg->get_assessment_result(assess_msg);
+ DBG1(DBG_TNC, "PB-TNC assessment result is '%N'",
+ TNC_IMV_Evaluation_Result_names, result);
+ break;
+ }
+ case PB_MSG_ACCESS_RECOMMENDATION:
+ {
+ pb_access_recommendation_msg_t *rec_msg;
+ pb_access_recommendation_code_t rec;
+ TNC_ConnectionState state = TNC_CONNECTION_STATE_ACCESS_NONE;
+
+ rec_msg = (pb_access_recommendation_msg_t*)msg;
+ rec = rec_msg->get_access_recommendation(rec_msg);
+ DBG1(DBG_TNC, "PB-TNC access recommendation is '%N'",
+ pb_access_recommendation_code_names, rec);
+ switch (rec)
+ {
+ case PB_REC_ACCESS_ALLOWED:
+ state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
+ break;
+ case PB_REC_ACCESS_DENIED:
+ state = TNC_CONNECTION_STATE_ACCESS_NONE;
+ break;
+ case PB_REC_QUARANTINED:
+ state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
+ }
+ charon->imcs->notify_connection_change(charon->imcs,
+ this->connection_id, state);
+ break;
+ }
+ case PB_MSG_REMEDIATION_PARAMETERS:
+ {
+ /* TODO : Remediation parameters message processing */
+ break;
+ }
+ case PB_MSG_ERROR:
+ {
+ pb_error_msg_t *err_msg;
+ bool fatal;
+ u_int32_t vendor_id;
+ u_int16_t error_code;
+
+ err_msg = (pb_error_msg_t*)msg;
+ fatal = err_msg->get_fatal_flag(err_msg);
+ vendor_id = err_msg->get_vendor_id(err_msg);
+ error_code = err_msg->get_error_code(err_msg);
+
+ if (fatal)
+ {
+ this->fatal_error = TRUE;
+ }
+
+ if (vendor_id == IETF_VENDOR_ID)
+ {
+ switch (error_code)
+ {
+ case PB_ERROR_INVALID_PARAMETER:
+ case PB_ERROR_UNSUPPORTED_MANDATORY_MSG:
+ DBG1(DBG_TNC, "received %s PB-TNC error '%N' "
+ "(offset %u bytes)",
+ fatal ? "fatal" : "non-fatal",
+ pb_tnc_error_code_names, error_code,
+ err_msg->get_offset(err_msg));
+ break;
+ case PB_ERROR_VERSION_NOT_SUPPORTED:
+ DBG1(DBG_TNC, "received %s PB-TNC error '%N' "
+ "caused by bad version 0x%02x",
+ fatal ? "fatal" : "non-fatal",
+ pb_tnc_error_code_names, error_code,
+ err_msg->get_bad_version(err_msg));
+ break;
+ case PB_ERROR_UNEXPECTED_BATCH_TYPE:
+ case PB_ERROR_LOCAL_ERROR:
+ default:
+ DBG1(DBG_TNC, "received %s PB-TNC error '%N'",
+ fatal ? "fatal" : "non-fatal",
+ pb_tnc_error_code_names, error_code);
+ break;
+ }
+ }
+ else
+ {
+ DBG1(DBG_TNC, "received %s PB-TNC error (%u) "
+ "with Vendor ID 0x%06x",
+ fatal ? "fatal" : "non-fatal",
+ error_code, vendor_id);
+ }
+ break;
+ }
+ case PB_MSG_LANGUAGE_PREFERENCE:
+ {
+ pb_language_preference_msg_t *lang_msg;
+ chunk_t lang;
+
+ lang_msg = (pb_language_preference_msg_t*)msg;
+ lang = lang_msg->get_language_preference(lang_msg);
+
+ DBG2(DBG_TNC, "setting language preference to '%.*s'",
+ lang.len, lang.ptr);
+ this->recs->set_preferred_language(this->recs, lang);
+ break;
+ }
+ case PB_MSG_REASON_STRING:
+ {
+ pb_reason_string_msg_t *reason_msg;
+ chunk_t reason_string, language_code;
+
+ reason_msg = (pb_reason_string_msg_t*)msg;
+ reason_string = reason_msg->get_reason_string(reason_msg);
+ language_code = reason_msg->get_language_code(reason_msg);
+ DBG2(DBG_TNC, "reason string is '%.*s", reason_string.len,
+ reason_string.ptr);
+ DBG2(DBG_TNC, "language code is '%.*s", language_code.len,
+ language_code.ptr);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/**
+ * Build a CRETRY or SRETRY batch
+ */
+static void build_retry_batch(private_tnccs_20_t *this)
+{
+ if (this->batch)
+ {
+ 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);
+}
+
METHOD(tls_t, process, status_t,
private_tnccs_20_t *this, void *buf, size_t buflen)
{
+ chunk_t data;
+ pb_tnc_batch_t *batch;
+ pb_tnc_msg_t *msg;
+ enumerator_t *enumerator;
+ status_t status;
+
+ if (this->is_server && !this->connection_id)
+ {
+ this->connection_id = charon->tnccs->create_connection(charon->tnccs,
+ (tnccs_t*)this, _send_msg,
+ &this->request_handshake_retry, &this->recs);
+ if (!this->connection_id)
+ {
+ return FAILED;
+ }
+ charon->imvs->notify_connection_change(charon->imvs,
+ this->connection_id, TNC_CONNECTION_STATE_CREATE);
+ }
+
+ data = chunk_create(buf, buflen);
+ DBG1(DBG_TNC, "received TNCCS batch (%u bytes) for Connection ID %u",
+ data.len, this->connection_id);
+ DBG3(DBG_TNC, "%B", &data);
+ batch = pb_tnc_batch_create_from_data(this->is_server, data);
+ status = batch->process(batch, this->state_machine);
+
+ if (status != FAILED)
+ {
+ enumerator_t *enumerator;
+ pb_tnc_msg_t *msg;
+ pb_tnc_batch_type_t batch_type;
+ bool empty = TRUE;
+
+ batch_type = batch->get_type(batch);
+
+ if (batch_type == PB_BATCH_CRETRY)
+ {
+ /* Send an SRETRY batch in response */
+ this->mutex->lock(this->mutex);
+ build_retry_batch(this);
+ this->mutex->unlock(this->mutex);
+ }
+ else if (batch_type == PB_BATCH_SRETRY)
+ {
+ /* Restart the measurements */
+ charon->imcs->notify_connection_change(charon->imcs,
+ this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
+ charon->imcs->begin_handshake(charon->imcs, this->connection_id);
+ }
+
+ enumerator = batch->create_msg_enumerator(batch);
+ while (enumerator->enumerate(enumerator, &msg))
+ {
+ handle_message(this, msg);
+ empty = FALSE;
+ }
+ enumerator->destroy(enumerator);
+
+ /* received an empty CLOSE batch from PB-TNC client */
+ if (this->is_server && batch_type == PB_BATCH_CLOSE && empty)
+ {
+ batch->destroy(batch);
+ if (this->fatal_error)
+ {
+ DBG1(DBG_TNC, "a fatal PB-TNC error occurred, "
+ "terminating connection");
+ return FAILED;
+ }
+ else
+ {
+ return SUCCESS;
+ }
+ }
+
+ if (this->is_server)
+ {
+ charon->imvs->batch_ending(charon->imvs, this->connection_id);
+ }
+ else
+ {
+ charon->imcs->batch_ending(charon->imcs, this->connection_id);
+ }
+ }
+
+ switch (status)
+ {
+ case FAILED:
+ this->fatal_error = TRUE;
+ this->mutex->lock(this->mutex);
+ if (this->batch)
+ {
+ 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, PB_BATCH_CLOSE);
+ this->mutex->unlock(this->mutex);
+ /* fall through to add error messages to outbound batch */
+ case VERIFY_ERROR:
+ enumerator = batch->create_error_enumerator(batch);
+ while (enumerator->enumerate(enumerator, &msg))
+ {
+ this->mutex->lock(this->mutex);
+ this->batch->add_msg(this->batch, msg->get_ref(msg));
+ this->mutex->unlock(this->mutex);
+ }
+ enumerator->destroy(enumerator);
+ break;
+ case SUCCESS:
+ default:
+ break;
+ }
+ batch->destroy(batch);
+
return NEED_MORE;
}
+/**
+ * Build a RESULT batch if a final recommendation is available
+ */
+static void check_and_build_recommendation(private_tnccs_20_t *this)
+{
+ TNC_IMV_Action_Recommendation rec;
+ TNC_IMV_Evaluation_Result eval;
+ TNC_IMVID id;
+ chunk_t reason, language;
+ enumerator_t *enumerator;
+ pb_tnc_msg_t *msg;
+
+ if (!this->recs->have_recommendation(this->recs, &rec, &eval))
+ {
+ charon->imvs->solicit_recommendation(charon->imvs, this->connection_id);
+ }
+ if (this->recs->have_recommendation(this->recs, &rec, &eval))
+ {
+ this->batch = pb_tnc_batch_create(this->is_server, PB_BATCH_RESULT);
+
+ msg = pb_assessment_result_msg_create(eval);
+ this->batch->add_msg(this->batch, msg);
+
+ /**
+ * IMV Action Recommendation and PB Access Recommendation codes
+ * are shifted by one.
+ */
+ msg = pb_access_recommendation_msg_create(rec + 1);
+ this->batch->add_msg(this->batch, msg);
+
+ enumerator = this->recs->create_reason_enumerator(this->recs);
+ while (enumerator->enumerate(enumerator, &id, &reason, &language))
+ {
+ msg = pb_reason_string_msg_create(reason, language);
+ this->batch->add_msg(this->batch, msg);
+ }
+ enumerator->destroy(enumerator);
+ }
+}
+
METHOD(tls_t, build, status_t,
private_tnccs_20_t *this, void *buf, size_t *buflen, size_t *msglen)
{
- return ALREADY_DONE;
+ status_t status;
+
+ /* Initialize the connection */
+ if (!this->is_server && !this->connection_id)
+ {
+ pb_tnc_msg_t *msg;
+ char *pref_lang;
+
+ this->connection_id = charon->tnccs->create_connection(charon->tnccs,
+ (tnccs_t*)this, _send_msg,
+ &this->request_handshake_retry, NULL);
+ if (!this->connection_id)
+ {
+ return FAILED;
+ }
+
+ /* Create PB-TNC Language Preference message */
+ pref_lang = charon->imcs->get_preferred_language(charon->imcs);
+ msg = pb_language_preference_msg_create(chunk_create(pref_lang,
+ strlen(pref_lang)));
+ this->mutex->lock(this->mutex);
+ this->batch = pb_tnc_batch_create(this->is_server, PB_BATCH_CDATA);
+ this->batch->add_msg(this->batch, msg);
+ this->mutex->unlock(this->mutex);
+
+ charon->imcs->notify_connection_change(charon->imcs,
+ this->connection_id, TNC_CONNECTION_STATE_CREATE);
+ charon->imcs->notify_connection_change(charon->imcs,
+ this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
+ charon->imcs->begin_handshake(charon->imcs, this->connection_id);
+ }
+
+ if (this->is_server && this->fatal_error &&
+ this->state_machine->get_state(this->state_machine) == PB_STATE_END)
+ {
+ DBG1(DBG_TNC, "a fatal PB-TNC error occurred, terminating connection");
+ return FAILED;
+ }
+
+ /* Do not allow any asynchronous IMCs or IMVs to add additional messages */
+ this->mutex->lock(this->mutex);
+
+ if (this->request_handshake_retry)
+ {
+ build_retry_batch(this);
+
+ /* Reset the flag for the next handshake retry request */
+ this->request_handshake_retry = FALSE;
+ }
+
+ 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)
+ {
+ check_and_build_recommendation(this);
+ }
+ }
+ else
+ {
+ /**
+ * if the DECIDED state has been reached and no CRETRY is under way
+ * or if a CLOSE batch with error messages has been received,
+ * a PB-TNC client replies with an empty CLOSE batch.
+ */
+ if (state == PB_STATE_DECIDED || state == PB_STATE_END)
+ {
+ this->batch = pb_tnc_batch_create(this->is_server, PB_BATCH_CLOSE);
+ }
+ }
+ }
+
+ if (this->batch)
+ {
+ pb_tnc_batch_type_t batch_type;
+ chunk_t data;
+
+ batch_type = this->batch->get_type(this->batch);
+
+ if (this->state_machine->send_batch(this->state_machine, batch_type))
+ {
+ this->batch->build(this->batch);
+ data = this->batch->get_encoding(this->batch);
+ DBG1(DBG_TNC, "sending PB-TNC %N batch (%d bytes) for Connection ID %u",
+ pb_tnc_batch_type_names, batch_type, data.len,
+ this->connection_id);
+ DBG3(DBG_TNC, "%B", &data);
+ *msglen = data.len;
+
+ if (data.len > *buflen)
+ {
+ DBG1(DBG_TNC, "fragmentation of PB-TNC batch not supported yet");
+ }
+ else
+ {
+ *buflen = data.len;
+ }
+ memcpy(buf, data.ptr, *buflen);
+ status = ALREADY_DONE;
+ }
+ else
+ {
+ DBG1(DBG_TNC, "cancelling unexpected PB-TNC batch type: %N",
+ pb_tnc_batch_type_names, batch_type);
+ status = INVALID_STATE;
+ }
+
+ this->batch->destroy(this->batch);
+ this->batch = NULL;
+ }
+ else
+ {
+ DBG1(DBG_TNC, "no PB-TNC batch to send");
+ status = INVALID_STATE;
+ }
+ this->mutex->unlock(this->mutex);
+
+ return status;
}
METHOD(tls_t, is_server, bool,
@@ -64,7 +601,21 @@ METHOD(tls_t, get_purpose, tls_purpose_t,
METHOD(tls_t, is_complete, bool,
private_tnccs_20_t *this)
{
- return FALSE;
+ TNC_IMV_Action_Recommendation rec;
+ TNC_IMV_Evaluation_Result eval;
+
+ 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);
+ }
+ else
+ {
+ return FALSE;
+ }
}
METHOD(tls_t, get_eap_msk, chunk_t,
@@ -76,6 +627,20 @@ 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);
+ this->state_machine->destroy(this->state_machine);
+ this->mutex->destroy(this->mutex);
+ DESTROY_IF(this->batch);
free(this);
}
@@ -97,6 +662,8 @@ tls_t *tnccs_20_create(bool is_server)
.destroy = _destroy,
},
.is_server = is_server,
+ .state_machine = pb_tnc_state_machine_create(is_server),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
);
return &this->public;
diff --git a/src/libcharon/plugins/tnccs_dynamic/Makefile.am b/src/libcharon/plugins/tnccs_dynamic/Makefile.am
new file mode 100644
index 000000000..9a81d065f
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_dynamic/Makefile.am
@@ -0,0 +1,17 @@
+
+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-tnccs-dynamic.la
+else
+plugin_LTLIBRARIES = libstrongswan-tnccs-dynamic.la
+libstrongswan_tnccs_dynamic_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
+endif
+
+libstrongswan_tnccs_dynamic_la_SOURCES = \
+ tnccs_dynamic_plugin.h tnccs_dynamic_plugin.c tnccs_dynamic.h tnccs_dynamic.c
+
+libstrongswan_tnccs_dynamic_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/tnccs_dynamic/Makefile.in b/src/libcharon/plugins/tnccs_dynamic/Makefile.in
new file mode 100644
index 000000000..722da2830
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_dynamic/Makefile.in
@@ -0,0 +1,607 @@
+# 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/tnccs_dynamic
+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_tnccs_dynamic_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la
+am_libstrongswan_tnccs_dynamic_la_OBJECTS = tnccs_dynamic_plugin.lo \
+ tnccs_dynamic.lo
+libstrongswan_tnccs_dynamic_la_OBJECTS = \
+ $(am_libstrongswan_tnccs_dynamic_la_OBJECTS)
+libstrongswan_tnccs_dynamic_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_tnccs_dynamic_la_LDFLAGS) $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_tnccs_dynamic_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_tnccs_dynamic_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_tnccs_dynamic_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_tnccs_dynamic_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@
+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@
+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-tnccs-dynamic.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnccs-dynamic.la
+@MONOLITHIC_FALSE@libstrongswan_tnccs_dynamic_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
+libstrongswan_tnccs_dynamic_la_SOURCES = \
+ tnccs_dynamic_plugin.h tnccs_dynamic_plugin.c tnccs_dynamic.h tnccs_dynamic.c
+
+libstrongswan_tnccs_dynamic_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/tnccs_dynamic/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/tnccs_dynamic/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-tnccs-dynamic.la: $(libstrongswan_tnccs_dynamic_la_OBJECTS) $(libstrongswan_tnccs_dynamic_la_DEPENDENCIES)
+ $(libstrongswan_tnccs_dynamic_la_LINK) $(am_libstrongswan_tnccs_dynamic_la_rpath) $(libstrongswan_tnccs_dynamic_la_OBJECTS) $(libstrongswan_tnccs_dynamic_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_dynamic.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_dynamic_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/tnccs_dynamic/tnccs_dynamic.c b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic.c
new file mode 100644
index 000000000..b7985fa51
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2011 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 "tnccs_dynamic.h"
+
+#include <tnc/tnccs/tnccs.h>
+#include <daemon.h>
+
+typedef struct private_tnccs_dynamic_t private_tnccs_dynamic_t;
+
+/**
+ * Private data of a tnccs_dynamic_t object.
+ */
+struct private_tnccs_dynamic_t {
+
+ /**
+ * Public tls_t interface.
+ */
+ tls_t public;
+
+ /**
+ * Detected TNC IF-TNCCS stack
+ */
+ tls_t *tls;
+};
+
+/**
+ * Determine the version of the IF-TNCCS protocol used by analyzing the first
+ * byte of the TNCCS batch received from a TNC Client according to the rules
+ * defined by section 3.5 "Interoperability with older IF-TNCCS versions" of
+ * the TCG TNC IF-TNCCS TLV Bindings Version 2.0 standard.
+ */
+tnccs_type_t determine_tnccs_protocol(char version)
+{
+ switch (version)
+ {
+ case '\t':
+ case '\n':
+ case '\r':
+ case ' ':
+ case '<':
+ return TNCCS_1_1;
+ case 0x00:
+ return TNCCS_SOH;
+ case 0x02:
+ return TNCCS_2_0;
+ default:
+ return TNCCS_UNKNOWN;
+ }
+}
+
+METHOD(tls_t, process, status_t,
+ private_tnccs_dynamic_t *this, void *buf, size_t buflen)
+{
+ tnccs_type_t type;
+
+ if (!this->tls)
+ {
+ if (buflen == 0)
+ {
+ return FAILED;
+ }
+ type = determine_tnccs_protocol(*(char*)buf);
+ DBG1(DBG_TNC, "%N protocol detected dynamically",
+ tnccs_type_names, type);
+ this->tls = (tls_t*)charon->tnccs->create_instance(charon->tnccs,
+ type, TRUE);
+ if (!this->tls)
+ {
+ DBG1(DBG_TNC, "N% protocol not supported", tnccs_type_names, type);
+ return FAILED;
+ }
+ }
+ return this->tls->process(this->tls, buf, buflen);
+}
+
+METHOD(tls_t, build, status_t,
+ private_tnccs_dynamic_t *this, void *buf, size_t *buflen, size_t *msglen)
+{
+ return this->tls->build(this->tls, buf, buflen, msglen);
+}
+
+METHOD(tls_t, is_server, bool,
+ private_tnccs_dynamic_t *this)
+{
+ return TRUE;
+}
+
+METHOD(tls_t, get_purpose, tls_purpose_t,
+ private_tnccs_dynamic_t *this)
+{
+ return TLS_PURPOSE_EAP_TNC;
+}
+
+METHOD(tls_t, is_complete, bool,
+ private_tnccs_dynamic_t *this)
+{
+ return this->tls ? this->tls->is_complete(this->tls) : FALSE;
+}
+
+METHOD(tls_t, get_eap_msk, chunk_t,
+ private_tnccs_dynamic_t *this)
+{
+ return chunk_empty;
+}
+
+METHOD(tls_t, destroy, void,
+ private_tnccs_dynamic_t *this)
+{
+ DESTROY_IF(this->tls);
+ free(this);
+}
+
+/**
+ * See header
+ */
+tls_t *tnccs_dynamic_create(bool is_server)
+{
+ private_tnccs_dynamic_t *this;
+
+ INIT(this,
+ .public = {
+ .process = _process,
+ .build = _build,
+ .is_server = _is_server,
+ .get_purpose = _get_purpose,
+ .is_complete = _is_complete,
+ .get_eap_msk = _get_eap_msk,
+ .destroy = _destroy,
+ },
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic.h b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic.h
new file mode 100644
index 000000000..42410b17f
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/**
+ * @defgroup tnccs_dynamic_h tnccs_dynamic
+ * @{ @ingroup tnccs_dynamic
+ */
+
+#ifndef TNCCS_DYNAMIC_H_
+#define TNCCS_DYNAMIC_H_
+
+#include <library.h>
+
+#include <tls.h>
+
+/**
+ * Create an instance of a dynamic TNC IF-TNCCS protocol handler.
+ *
+ * @param is_server TRUE to act as TNC Server, FALSE for TNC Client
+ * @return dynamic TNC IF-TNCCS protocol stack
+ */
+tls_t *tnccs_dynamic_create(bool is_server);
+
+#endif /** TNCCS_DYNAMIC_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c
new file mode 100644
index 000000000..dbbf222e0
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 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 "tnccs_dynamic_plugin.h"
+#include "tnccs_dynamic.h"
+
+#include <daemon.h>
+
+METHOD(plugin_t, destroy, void,
+ tnccs_dynamic_plugin_t *this)
+{
+ charon->tnccs->remove_method(charon->tnccs,
+ (tnccs_constructor_t)tnccs_dynamic_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *tnccs_dynamic_plugin_create()
+{
+ tnccs_dynamic_plugin_t *this;
+
+ INIT(this,
+ .plugin = {
+ .destroy = _destroy,
+ },
+ );
+
+ charon->tnccs->add_method(charon->tnccs, TNCCS_DYNAMIC,
+ (tnccs_constructor_t)tnccs_dynamic_create);
+
+ return &this->plugin;
+}
+
diff --git a/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h
new file mode 100644
index 000000000..b518e1278
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/**
+ * @defgroup tnccs_dynamic tnccs_dynamic
+ * @ingroup cplugins
+ *
+ * @defgroup tnccs_dynamic_plugin tnccs_dynamic_plugin
+ * @{ @ingroup tnccs_dynamic
+ */
+
+#ifndef TNCCS_DYNAMIC_PLUGIN_H_
+#define TNCCS_DYNAMIC_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct tnccs_dynamic_plugin_t tnccs_dynamic_plugin_t;
+
+/**
+ * EAP-TNC plugin
+ */
+struct tnccs_dynamic_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** TNCCS_DYNAMIC_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/uci/Makefile.in b/src/libcharon/plugins/uci/Makefile.in
index 9cb5f794a..f7162d800 100644
--- a/src/libcharon/plugins/uci/Makefile.in
+++ b/src/libcharon/plugins/uci/Makefile.in
@@ -220,9 +220,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -261,6 +259,8 @@ 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@
diff --git a/src/libcharon/plugins/uci/uci_config.c b/src/libcharon/plugins/uci/uci_config.c
index ddddae782..4e43388ec 100644
--- a/src/libcharon/plugins/uci/uci_config.c
+++ b/src/libcharon/plugins/uci/uci_config.c
@@ -196,8 +196,8 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
this->peer_cfg->add_auth_cfg(this->peer_cfg, auth, FALSE);
child_cfg = child_cfg_create(name, &lifetime, NULL, TRUE, MODE_TUNNEL,
- ACTION_NONE, ACTION_NONE, FALSE, 0, 0,
- NULL, NULL);
+ ACTION_NONE, ACTION_NONE, ACTION_NONE,
+ FALSE, 0, 0, NULL, NULL, 0);
child_cfg->add_proposal(child_cfg, create_proposal(esp_proposal, PROTO_ESP));
child_cfg->add_traffic_selector(child_cfg, TRUE, create_ts(local_net));
child_cfg->add_traffic_selector(child_cfg, FALSE, create_ts(remote_net));
diff --git a/src/libcharon/plugins/unit_tester/Makefile.in b/src/libcharon/plugins/unit_tester/Makefile.in
index 47fff7e1d..5fa749e56 100644
--- a/src/libcharon/plugins/unit_tester/Makefile.in
+++ b/src/libcharon/plugins/unit_tester/Makefile.in
@@ -226,9 +226,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +265,8 @@ 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@
diff --git a/src/libcharon/plugins/updown/Makefile.in b/src/libcharon/plugins/updown/Makefile.in
index e93955d71..5dd2dc843 100644
--- a/src/libcharon/plugins/updown/Makefile.in
+++ b/src/libcharon/plugins/updown/Makefile.in
@@ -222,9 +222,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +261,8 @@ 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@