]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
Implemented PT-TLS handover on client side pt-tls-handover
authorAndreas Steffen <andreas.steffen@strongswan.org>
Sat, 26 Oct 2013 14:04:07 +0000 (16:04 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 12 Feb 2014 09:51:38 +0000 (10:51 +0100)
src/libcharon/plugins/eap_tnc/eap_tnc.c
src/libcharon/plugins/tnc_pt_tls/Makefile.am
src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_connection.c
src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_listener.c [new file with mode: 0644]
src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_listener.h [new file with mode: 0644]
src/libcharon/plugins/tnc_pt_tls/tnc_pt_tls_plugin.c
src/libpttls/pt_tls_client.c
src/libpttls/pt_tls_client.h
src/libpttls/pt_tls_connection.h
src/libpttls/pt_tls_manager.c
src/libpttls/pt_tls_manager.h

index d0b3ec8f757cbeb4d9966680cfa1319b76e1e72d..dcbfa01fb12e4c66a9e8ab6b8f65016908ecd2ec 100644 (file)
@@ -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);
index b58f54a98e3de4b586e7ab6d3791b35d2ae868a4..1b27d45ccf83bd3779da1d787b472979672e0f95 100644 (file)
@@ -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
index d26efb17a3a26396431d5c9dc89e4d4e1874b9ab..2e6024630506d76230e00b5edaab11ef4bbac1bc 100644 (file)
@@ -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 (file)
index 0000000..14fc691
--- /dev/null
@@ -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 <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_pt_tls_listener.h"
+
+#include <daemon.h>
+#include <config/child_cfg.h>
+
+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 (file)
index 0000000..1b0d25d
--- /dev/null
@@ -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 <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_pt_tls_listener tnc_pt_tls_listener
+ * @{ @ingroup updown
+ */
+
+#ifndef TNC_PT_TLS_LISTENER_H_
+#define TNC_PT_TLS_LISTENER_H_
+
+#include <bus/bus.h>
+
+#include <pt_tls_manager.h>
+
+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_ @}*/
index d66759334550b0b405b2788cd032532121012bd9..0927b006753bba81b6da8a88c08772dbd002e13b 100644 (file)
@@ -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;
index 01a84cd149bae999dd39330a506c628dda50e442..284b04bf4e4465424cc268aa074872b1a430aec8 100644 (file)
@@ -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,
                },
index 1d418d18106e3cc84b875b41fc0b134291ff6f85..6f91250ff7d7dedfcafa2098aa69d42d786f6d15 100644 (file)
@@ -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);
index e5a7c2dd2b0447182ffa200d5c2c366cdad16fdc..64a91699d97460f793eab6536ca81c9a6f4655c3 100644 (file)
@@ -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.
         */
index 1513acd8bca747785fad1b3fd46798daefd3e0aa..d759a6ddb82367598fcf15a7c22a2718ff80c920 100644 (file)
@@ -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,
index b7ece979b8a603798fc43bcf0cec1f4c48b1b88c..4827341586af63c98fd4dd27fccbcd8f4b85f3cd 100644 (file)
@@ -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.
         */