From: Andreas Steffen Date: Sat, 26 Oct 2013 14:04:07 +0000 (+0200) Subject: Implemented PT-TLS handover on client side X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3fcbd954c19d7bc28dda9a7f09365b109b3b482f;p=thirdparty%2Fstrongswan.git Implemented PT-TLS handover on client side --- diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc.c b/src/libcharon/plugins/eap_tnc/eap_tnc.c index d0b3ec8f75..dcbfa01fb1 100644 --- a/src/libcharon/plugins/eap_tnc/eap_tnc.c +++ b/src/libcharon/plugins/eap_tnc/eap_tnc.c @@ -242,7 +242,7 @@ METHOD(eap_method_t, destroy, void, } else { - DBG1(DBG_TNC, "could not resolve hostname '%s'", pdp_server); + DBG1(DBG_TNC, "could not resolve PDP hostname '%s'", pdp_server); } } this->tls_eap->destroy(this->tls_eap); diff --git a/src/libcharon/plugins/tnc_pt_tls/Makefile.am b/src/libcharon/plugins/tnc_pt_tls/Makefile.am index b58f54a98e..1b27d45ccf 100644 --- a/src/libcharon/plugins/tnc_pt_tls/Makefile.am +++ b/src/libcharon/plugins/tnc_pt_tls/Makefile.am @@ -22,6 +22,7 @@ endif libstrongswan_tnc_pt_tls_la_SOURCES = \ tnc_pt_tls_plugin.h tnc_pt_tls_plugin.c \ - tnc_pt_tls_connection.h tnc_pt_tls_connection.c + tnc_pt_tls_connection.h tnc_pt_tls_connection.c \ + tnc_pt_tls_listener.h tnc_pt_tls_listener.c libstrongswan_tnc_pt_tls_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_connection.c b/src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_connection.c index d26efb17a3..2e60246305 100644 --- a/src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_connection.c +++ b/src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_connection.c @@ -34,13 +34,34 @@ struct private_tnc_pt_tls_connection_t { */ pt_tls_client_t *pt_tls_client; + /** + * IF-TNCCS layer to be transported + */ + tnccs_t *tnccs; + }; +METHOD(pt_tls_connection_t, get_host, host_t*, + private_tnc_pt_tls_connection_t *this) +{ + return this->pt_tls_client->get_address(this->pt_tls_client); +} + +METHOD(pt_tls_connection_t, start, status_t, + private_tnc_pt_tls_connection_t *this) +{ + return this->pt_tls_client->start(this->pt_tls_client, this->tnccs); +} + METHOD(pt_tls_connection_t, destroy, void, private_tnc_pt_tls_connection_t *this) { + tls_t *tls; + DBG2(DBG_TNC, "destroying PT-TLS connection"); this->pt_tls_client->destroy(this->pt_tls_client); + tls = &this->tnccs->tls; + tls->destroy(tls); free(this); } @@ -52,12 +73,13 @@ pt_tls_connection_t *tnc_pt_tls_connection_create(tnccs_t *tnccs, host_t *host, { private_tnc_pt_tls_connection_t *this; - DBG2(DBG_TNC, "TODO: setup PT-TLS connection to '%Y' at %#H", server, host); - INIT(this, .public = { + .get_host = _get_host, + .start = _start, .destroy = _destroy, }, + .tnccs = tnccs, .pt_tls_client = pt_tls_client_create(host, server, client), ); diff --git a/src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_listener.c b/src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_listener.c new file mode 100644 index 0000000000..14fc691342 --- /dev/null +++ b/src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_listener.c @@ -0,0 +1,110 @@ +/* + * 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 . + * + * 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_pt_tls_listener.h" + +#include +#include + +typedef struct private_tnc_pt_tls_listener_t private_tnc_pt_tls_listener_t; + +/** + * Private data of an tnc_pt_tls_listener_t object. + */ +struct private_tnc_pt_tls_listener_t { + + /** + * Public tnc_pt_tls_listener_t interface. + */ + tnc_pt_tls_listener_t public; + + /** + * PT-TLS connection manager + */ + pt_tls_manager_t *mgr; +}; + +METHOD(listener_t, child_updown, bool, + private_tnc_pt_tls_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, + bool up) +{ + traffic_selector_t *my_ts, *other_ts; + pt_tls_connection_t *connection; + host_t *host; + enumerator_t *e1, *e2; + bool found = FALSE; + + e1 = this->mgr->create_connection_enumerator(this->mgr); + while (e1->enumerate(e1, &connection)) + { + host = connection->get_host(connection); + + e2 = child_sa->create_policy_enumerator(child_sa); + while (e2->enumerate(e2, &my_ts, &other_ts)) + { + if (other_ts->includes(other_ts, host)) + { + if (up) + { + DBG1(DBG_TNC, "starting PT-TLS connection with %#H", host); + connection->start(connection); + } + else + { + DBG1(DBG_TNC, "stopping PT-TLS connection with %#H", host); + this->mgr->remove_connection(this->mgr, connection); + connection->destroy(connection); + } + found = TRUE; + break; + } + } + e2->destroy(e2); + + if (found) + { + break; + } + } + e1->destroy(e1); + + return TRUE; +} + +METHOD(tnc_pt_tls_listener_t, destroy, void, + private_tnc_pt_tls_listener_t *this) +{ + free(this); +} + +/** + * See header + */ +tnc_pt_tls_listener_t *tnc_pt_tls_listener_create(pt_tls_manager_t *mgr) +{ + private_tnc_pt_tls_listener_t *this; + + INIT(this, + .public = { + .listener = { + .child_updown = _child_updown, + }, + .destroy = _destroy, + }, + .mgr = mgr, + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_listener.h b/src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_listener.h new file mode 100644 index 0000000000..1b0d25d895 --- /dev/null +++ b/src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_listener.h @@ -0,0 +1,51 @@ +/* + * 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 . + * + * 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_pt_tls_listener tnc_pt_tls_listener + * @{ @ingroup updown + */ + +#ifndef TNC_PT_TLS_LISTENER_H_ +#define TNC_PT_TLS_LISTENER_H_ + +#include + +#include + +typedef struct tnc_pt_tls_listener_t tnc_pt_tls_listener_t; + +/** + * Listener which invokes the scripts on CHILD_SA up/down. + */ +struct tnc_pt_tls_listener_t { + + /** + * Implements listener_t. + */ + listener_t listener; + + /** + * Destroy a tnc_pt_tls_listener_t. + */ + void (*destroy)(tnc_pt_tls_listener_t *this); +}; + +/** + * Create a tnc_pt_tls_listener instance. + */ +tnc_pt_tls_listener_t *tnc_pt_tls_listener_create(pt_tls_manager_t *mgr); + +#endif /** TNC_PT_TLS_LISTENER_H_ @}*/ diff --git a/src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_plugin.c b/src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_plugin.c index d667593345..0927b00675 100644 --- a/src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_plugin.c +++ b/src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_plugin.c @@ -14,6 +14,7 @@ */ #include "tnc_pt_tls_plugin.h" +#include "tnc_pt_tls_listener.h" #include "tnc_pt_tls_connection.h" #include "pt_tls_manager.h" @@ -33,9 +34,14 @@ struct private_tnc_pt_tls_plugin_t { pt_tls_plugin_t public; /** - * PT-TLS backend manager + * PT-TLS connection manager */ pt_tls_manager_t *mgr; + + /** + * Listener interface, listens to CHILD_SA state changes + */ + tnc_pt_tls_listener_t *listener; }; @@ -54,9 +60,13 @@ static bool plugin_cb(private_tnc_pt_tls_plugin_t *this, if (reg) { lib->set(lib, "pt-tls-manager", this->mgr); + this->listener = tnc_pt_tls_listener_create(this->mgr); + charon->bus->add_listener(charon->bus, &this->listener->listener); } else { + charon->bus->remove_listener(charon->bus, &this->listener->listener); + this->listener->destroy(this->listener); lib->set(lib, "pt-tls-manager", NULL); } return TRUE; diff --git a/src/libpttls/pt_tls_client.c b/src/libpttls/pt_tls_client.c index 01a84cd149..284b04bf4e 100644 --- a/src/libpttls/pt_tls_client.c +++ b/src/libpttls/pt_tls_client.c @@ -426,6 +426,33 @@ static bool assess(private_pt_tls_client_t *this, tls_t *tnccs) } } +METHOD(pt_tls_client_t, start, status_t, + private_pt_tls_client_t *this, tnccs_t *tnccs) +{ + if (!this->tls) + { + DBG1(DBG_TNC, "entering PT-TLS setup phase"); + if (!make_connection(this)) + { + return FAILED; + } + } + + DBG1(DBG_TNC, "entering PT-TLS negotiation phase"); + if (!negotiate_version(this)) + { + return FAILED; + } + + DBG1(DBG_TNC, "doing SASL client authentication"); + if (!authenticate(this)) + { + return FAILED; + } + + return SUCCESS; +} + METHOD(pt_tls_client_t, run_assessment, status_t, private_pt_tls_client_t *this, tnccs_t *tnccs) { @@ -458,6 +485,11 @@ METHOD(pt_tls_client_t, run_assessment, status_t, return SUCCESS; } +METHOD(pt_tls_client_t, get_address, host_t*, + private_pt_tls_client_t *this) +{ + return this->address; +} METHOD(pt_tls_client_t, destroy, void, private_pt_tls_client_t *this) @@ -486,6 +518,8 @@ pt_tls_client_t *pt_tls_client_create(host_t *address, identification_t *server, INIT(this, .public = { + .get_address = _get_address, + .start = _start, .run_assessment = _run_assessment, .destroy = _destroy, }, diff --git a/src/libpttls/pt_tls_client.h b/src/libpttls/pt_tls_client.h index 1d418d1810..6f91250ff7 100644 --- a/src/libpttls/pt_tls_client.h +++ b/src/libpttls/pt_tls_client.h @@ -33,10 +33,25 @@ typedef struct pt_tls_client_t pt_tls_client_t; */ struct pt_tls_client_t { + /** + * Get destination IP address. + * + * @return IP address of PT-TLS server + */ + host_t* (*get_address)(pt_tls_client_t *this); + + /** + * Start a connection to a PT-TLS server + * + * @param tnccs layer PT-TLS client is transporting + * @return connection status + */ + status_t (*start)(pt_tls_client_t *this, tnccs_t *tnccs); + /** * Perform an assessment. * - * @param tnccs upper layer TNC client used for assessment + * @param tnccs layer PT-TNC client used for assessment * @return status of assessment */ status_t (*run_assessment)(pt_tls_client_t *this, tnccs_t *tnccs); diff --git a/src/libpttls/pt_tls_connection.h b/src/libpttls/pt_tls_connection.h index e5a7c2dd2b..64a91699d9 100644 --- a/src/libpttls/pt_tls_connection.h +++ b/src/libpttls/pt_tls_connection.h @@ -39,6 +39,20 @@ typedef pt_tls_connection_t* (*pt_tls_connection_constructor_t)(tnccs_t *tnccs, */ struct pt_tls_connection_t { + /** + * Get IP address of PDP server + * + * @return PDP server address + */ + host_t* (*get_host)(pt_tls_connection_t *this); + + /** + * Start the PT-TLS connection. + * + * @return Connection status + */ + status_t (*start)(pt_tls_connection_t *this); + /** * Destroy a pt_tls_connection_t object. */ diff --git a/src/libpttls/pt_tls_manager.c b/src/libpttls/pt_tls_manager.c index 1513acd8bc..d759a6ddb8 100644 --- a/src/libpttls/pt_tls_manager.c +++ b/src/libpttls/pt_tls_manager.c @@ -69,6 +69,12 @@ METHOD(pt_tls_manager_t, remove_connection, void, this->lock->unlock(this->lock); } +METHOD(pt_tls_manager_t, create_connection_enumerator, enumerator_t*, + private_pt_tls_manager_t *this) +{ + return this->connections->create_enumerator(this->connections); +} + METHOD(pt_tls_manager_t, destroy, void, private_pt_tls_manager_t *this) { @@ -90,6 +96,7 @@ pt_tls_manager_t *pt_tls_manager_create(pt_tls_connection_constructor_t create) .create_connection = _create_connection, .add_connection = _add_connection, .remove_connection = _remove_connection, + .create_connection_enumerator = _create_connection_enumerator, .destroy = _destroy, }, .create = create, diff --git a/src/libpttls/pt_tls_manager.h b/src/libpttls/pt_tls_manager.h index b7ece979b8..4827341586 100644 --- a/src/libpttls/pt_tls_manager.h +++ b/src/libpttls/pt_tls_manager.h @@ -59,6 +59,13 @@ struct pt_tls_manager_t { void (*remove_connection)(pt_tls_manager_t *this, pt_tls_connection_t *connection); + /** + * Enumerate over all registered PT-TLS connections + * + * @return PT-TLS connection enumerator + */ + enumerator_t* (*create_connection_enumerator)(pt_tls_manager_t *this); + /** * Destroy a manager instance. */