Keep a copy of the tnccs instance for PT-TLS handover
authorAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 9 Oct 2013 17:03:07 +0000 (19:03 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 9 Oct 2013 17:03:07 +0000 (19:03 +0200)
src/libcharon/plugins/eap_tnc/eap_tnc.c
src/libtnccs/plugins/tnccs_11/tnccs_11.c
src/libtnccs/plugins/tnccs_20/tnccs_20.c
src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.c
src/libtnccs/tnc/tnccs/tnccs.h

index d14672e..cf4044f 100644 (file)
@@ -213,6 +213,18 @@ METHOD(eap_method_t, is_mutual, bool,
 METHOD(eap_method_t, destroy, void,
        private_eap_tnc_t *this)
 {
+       chunk_t pdp_server;
+       u_int16_t pdp_port;
+       tls_t *tls;
+
+       pdp_server = this->tnccs->get_pdp_server(this->tnccs, &pdp_port);
+       if (pdp_server.len)
+       {
+               DBG2(DBG_TNC, "TODO: setup PT-TLS connection to %.*s:%u",
+                        pdp_server.len, pdp_server.ptr, pdp_port);
+       }
+       tls = &this->tnccs->tls;
+       tls->destroy(tls);
        this->tls_eap->destroy(this->tls_eap);
        free(this);
 }
@@ -238,6 +250,7 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
        private_eap_tnc_t *this;
        int max_msg_count;
        char* protocol;
+       tnccs_t *tnccs;
        tnccs_type_t type;
 
        INIT(this,
@@ -282,10 +295,11 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
                free(this);
                return NULL;
        }
-       this->tnccs = tnc->tnccs->create_instance(tnc->tnccs, type,
+       tnccs = tnc->tnccs->create_instance(tnc->tnccs, type,
                                                is_server, server, peer, TNC_IFT_EAP_1_1,
                                                is_server ? enforce_recommendation : NULL);
-       this->tls_eap = tls_eap_create(EAP_TNC, &this->tnccs->tls,
+       this->tnccs = tnccs->get_ref(tnccs);
+       this->tls_eap = tls_eap_create(EAP_TNC, &tnccs->tls,
                                                                   EAP_TNC_MAX_MESSAGE_LEN,
                                                                   max_msg_count, FALSE);
        if (!this->tls_eap)
index 7fc7e6d..91854b5 100644 (file)
@@ -126,6 +126,11 @@ struct private_tnccs_11_t {
         */
        tnccs_cb_t callback;
 
+       /**
+        * reference count
+        */
+       refcount_t ref;
+
 };
 
 METHOD(tnccs_t, send_msg, TNC_Result,
@@ -569,13 +574,16 @@ METHOD(tls_t, get_eap_msk, chunk_t,
 METHOD(tls_t, destroy, void,
        private_tnccs_11_t *this)
 {
-       tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id,
-                                                                                         this->is_server);
-       this->server->destroy(this->server);
-       this->peer->destroy(this->peer);
-       this->mutex->destroy(this->mutex);
-       DESTROY_IF(this->batch);
-       free(this);
+       if (ref_put(&this->ref))
+       {
+               tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id,
+                                                                                                 this->is_server);
+               this->server->destroy(this->server);
+               this->peer->destroy(this->peer);
+               this->mutex->destroy(this->mutex);
+               DESTROY_IF(this->batch);
+               free(this);
+       }
 }
 
 METHOD(tnccs_t, get_transport, tnc_ift_type_t,
@@ -602,6 +610,21 @@ METHOD(tnccs_t, set_auth_type, void,
        this->auth_type = auth_type;
 }
 
+METHOD(tnccs_t, get_pdp_server, chunk_t,
+       private_tnccs_11_t *this, u_int16_t *port)
+{
+       *port = 0;
+
+       return chunk_empty;
+}
+
+METHOD(tnccs_t, get_ref, tnccs_t*,
+       private_tnccs_11_t *this)
+{
+       ref_get(&this->ref);
+       return &this->public;
+}
+
 /**
  * See header
  */
@@ -629,6 +652,8 @@ tnccs_t* tnccs_11_create(bool is_server,
                        .set_transport = _set_transport,
                        .get_auth_type = _get_auth_type,
                        .set_auth_type = _set_auth_type,
+                       .get_pdp_server = _get_pdp_server,
+                       .get_ref = _get_ref,
                },
                .is_server = is_server,
                .server = server->clone(server),
@@ -638,6 +663,7 @@ tnccs_t* tnccs_11_create(bool is_server,
                .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
                .max_msg_len = lib->settings->get_int(lib->settings,
                                                        "libtnccs.plugins.tnccs-11.max_message_size", 45000),
+               .ref = 1,
        );
 
        return &this->public;
index b5b1ceb..b631ef5 100644 (file)
@@ -142,6 +142,21 @@ struct private_tnccs_20_t {
         */
        void *cb_data;
 
+       /**
+        * PDP server FQDN
+        */
+       chunk_t pdp_server;
+
+       /**
+        * PDP server port
+        */
+       u_int16_t pdp_port;
+
+       /**
+        * reference count
+        */
+       refcount_t ref;
+
 };
 
 /**
@@ -456,9 +471,7 @@ static void handle_tcg_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
                {
                        pb_pdp_referral_msg_t *pdp_msg;
                        pen_type_t pdp_id_type;
-                       chunk_t pdp_server;
                        u_int8_t pdp_protocol;
-                       u_int16_t pdp_port;
 
                        pdp_msg = (pb_pdp_referral_msg_t*)msg;
                        pdp_id_type = pdp_msg->get_identifier_type(pdp_msg);
@@ -466,15 +479,16 @@ static void handle_tcg_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
                        if (pdp_id_type.vendor_id == PEN_TCG &&
                                pdp_id_type.type == PB_PDP_ID_FQDN)
                        {
-                               pdp_server = pdp_msg->get_fqdn(pdp_msg, &pdp_protocol,
-                                                                                          &pdp_port);
+                               this->pdp_server = chunk_clone(pdp_msg->get_fqdn(pdp_msg,
+                                                                                &pdp_protocol, &this->pdp_port));
                                if (pdp_protocol != 0)
                                {
                                        DBG1(DBG_TNC, "unsupported PDP transport protocol");
                                        break;
                                }
                                DBG1(DBG_TNC, "PDP server '%.*s' is listening on port %u",
-                                                          pdp_server.len, pdp_server.ptr, pdp_port);
+                                                          this->pdp_server.len, this->pdp_server.ptr,
+                                                          this->pdp_port);
                        }
                        break;
                }
@@ -956,15 +970,19 @@ METHOD(tls_t, get_eap_msk, chunk_t,
 METHOD(tls_t, destroy, void,
        private_tnccs_20_t *this)
 {
-       tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id,
-                                                                                         this->is_server);
-       this->server->destroy(this->server);
-       this->peer->destroy(this->peer);
-       this->state_machine->destroy(this->state_machine);
-       this->mutex->destroy(this->mutex);
-       this->messages->destroy_offset(this->messages,
-                                                                  offsetof(pb_tnc_msg_t, destroy));
-       free(this);
+       if (ref_put(&this->ref))
+       {
+               tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id,
+                                                                                                 this->is_server);
+               this->server->destroy(this->server);
+               this->peer->destroy(this->peer);
+               this->state_machine->destroy(this->state_machine);
+               this->mutex->destroy(this->mutex);
+               this->messages->destroy_offset(this->messages,
+                                                                          offsetof(pb_tnc_msg_t, destroy));
+               free(this->pdp_server.ptr);
+               free(this);
+       }
 }
 
 METHOD(tnccs_t, get_transport, tnc_ift_type_t,
@@ -991,6 +1009,21 @@ METHOD(tnccs_t, set_auth_type, void,
        this->auth_type = auth_type;
 }
 
+METHOD(tnccs_t, get_pdp_server, chunk_t,
+       private_tnccs_20_t *this, u_int16_t *port)
+{
+       *port = this->pdp_port;
+
+       return this->pdp_server;
+}
+
+METHOD(tnccs_t, get_ref, tnccs_t*,
+       private_tnccs_20_t *this)
+{
+       ref_get(&this->ref);
+       return &this->public;
+}
+
 /**
  * See header
  */
@@ -1018,6 +1051,8 @@ tnccs_t* tnccs_20_create(bool is_server,
                        .set_transport = _set_transport,
                        .get_auth_type = _get_auth_type,
                        .set_auth_type = _set_auth_type,
+                       .get_pdp_server = _get_pdp_server,
+                       .get_ref = _get_ref,
                },
                .is_server = is_server,
                .server = server->clone(server),
@@ -1031,6 +1066,7 @@ tnccs_t* tnccs_20_create(bool is_server,
                                                        "libtnccs.plugins.tnccs-20.max_batch_size", 65522),
                .max_msg_len = lib->settings->get_int(lib->settings,
                                                        "libtnccs.plugins.tnccs-20.max_message_size", 65490),
+               .ref = 1,
        );
 
        return &this->public;
index a52ffed..e08236e 100644 (file)
@@ -61,6 +61,11 @@ struct private_tnccs_dynamic_t {
         */
        tnccs_cb_t callback;
 
+       /**
+        * reference count
+        */
+       refcount_t ref;
+
 };
 
 /**
@@ -173,10 +178,13 @@ METHOD(tls_t, get_eap_msk, chunk_t,
 METHOD(tls_t, destroy, void,
        private_tnccs_dynamic_t *this)
 {
-       DESTROY_IF(this->tls);
-       this->server->destroy(this->server);
-       this->peer->destroy(this->peer);
-       free(this);
+       if (ref_put(&this->ref))
+       {
+               DESTROY_IF(this->tls);
+               this->server->destroy(this->server);
+               this->peer->destroy(this->peer);
+               free(this);
+       }
 }
 
 METHOD(tnccs_t, get_transport, tnc_ift_type_t,
@@ -203,6 +211,21 @@ METHOD(tnccs_t, set_auth_type, void,
        this->auth_type = auth_type;
 }
 
+METHOD(tnccs_t, get_pdp_server, chunk_t,
+       private_tnccs_dynamic_t *this, u_int16_t *port)
+{
+       tnccs_t *tnccs = (tnccs_t*)this->tls;
+
+       return tnccs->get_pdp_server(tnccs, port);
+}
+
+METHOD(tnccs_t, get_ref, tnccs_t*,
+       private_tnccs_dynamic_t *this)
+{
+       ref_get(&this->ref);
+       return &this->public;
+}
+
 /**
  * See header
  */
@@ -230,11 +253,14 @@ tnccs_t* tnccs_dynamic_create(bool is_server,
                        .set_transport = _set_transport,
                        .get_auth_type = _get_auth_type,
                        .set_auth_type = _set_auth_type,
+                       .get_pdp_server = _get_pdp_server,
+                       .get_ref = _get_ref,
                },
                .server = server->clone(server),
                .peer = peer->clone(peer),
                .transport = transport,
                .callback = cb,
+               .ref = 1,
        );
 
        return &this->public;
index b1ac090..eefd556 100644 (file)
@@ -114,6 +114,21 @@ struct tnccs_t {
         */
        void (*set_auth_type)(tnccs_t *this, u_int32_t auth_type);
 
+       /**
+        * Get PDP server name and port number
+        *
+        * @param port          PDP port number
+        * @return                      PDP server name
+        */
+       chunk_t (*get_pdp_server)(tnccs_t *this, u_int16_t *port);
+
+       /**
+        * Get a new reference to the TNCCS object.
+        *
+        * @return                      this, with an increased refcount
+        */
+       tnccs_t* (*get_ref)(tnccs_t *this);
+
 };
 
 /**