Corrected use of PB-TNC CRETRY and SRETRY batches
authorAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 29 Mar 2019 14:33:24 +0000 (15:33 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 29 Mar 2019 16:04:43 +0000 (17:04 +0100)
The PB-TNC finite state machine according to section 3.2 of RFC 5793
was not correctly implemented when sending either a CRETRY or SRETRY
batch. These batches can only be sent in the "Decided" state and a
CRETRY batch can immediately carry all messages usually transported
by a CDATA batch. strongSwan currently is not able to send a SRETRY
batch since full-duplex mode for PT-TLS isn't supported yet.

NEWS
src/libtnccs/plugins/tnccs_20/state_machine/pb_tnc_state_machine.c
src/libtnccs/plugins/tnccs_20/tnccs_20_client.c
src/libtnccs/plugins/tnccs_20/tnccs_20_server.c

diff --git a/NEWS b/NEWS
index 384f2dc..a9dec6a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,13 @@ strongswan-5.8.0
 
 - The openssl plugin supports ChaCha20-Poly1305 when built with OpenSSL 1.1.0.
 
+- The PB-TNC finite state machine according to section 3.2 of RFC 5793 was not
+  correctly implemented when sending either a CRETRY or SRETRY batch. These
+  batches can only be sent in the "Decided" state and a CRETRY batch can
+  immediately carry all messages usually transported by a CDATA batch. It is
+  currently not possible to send a SRETRY batch since full-duplex mode for
+  PT-TLS transport is not supported.
+
 
 strongswan-5.7.2
 ----------------
index 43f1854..51ce384 100644 (file)
@@ -134,15 +134,12 @@ METHOD(pb_tnc_state_machine_t, receive_batch, bool,
                        }
                        return FALSE;
                case PB_STATE_CLIENT_WORKING:
-                       if (this->is_server && type == PB_BATCH_CDATA)
+                       if (this->is_server &&
+                                       (type == PB_BATCH_CDATA || type == PB_BATCH_CRETRY))
                        {
                                this->state = PB_STATE_SERVER_WORKING;
                                break;
                        }
-                       if (this->is_server && type == PB_BATCH_CRETRY)
-                       {
-                               break;
-                       }
                        if (type == PB_BATCH_CLOSE)
                        {
                                this->state = PB_STATE_END;
index 04e4042..c8fdf0d 100644 (file)
@@ -538,9 +538,19 @@ METHOD(tnccs_20_handler_t, build, status_t,
 
        if (this->request_handshake_retry)
        {
-               if (state != PB_STATE_INIT)
+               if (state == PB_STATE_DECIDED)
                {
+
                        build_retry_batch(this);
+
+                       /* Restart the measurements */
+                       tnc->imcs->notify_connection_change(tnc->imcs,
+                                               this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
+                       this->send_msg = TRUE;
+                       this->mutex->unlock(this->mutex);
+                       tnc->imcs->begin_handshake(tnc->imcs, this->connection_id);
+                       this->mutex->lock(this->mutex);
+                       this->send_msg = FALSE;
                }
 
                /* Reset the flag for the next handshake retry request */
@@ -714,7 +724,7 @@ METHOD(tnccs_20_handler_t, add_msg, void,
        {
                this->batch_type = PB_BATCH_CDATA;
        }
-       if (this->batch_type == PB_BATCH_CDATA)
+       if (this->batch_type == PB_BATCH_CDATA || this->batch_type == PB_BATCH_CRETRY)
        {
                this->messages->insert_last(this->messages, msg);
        }
index 32d9502..44889d7 100644 (file)
@@ -282,11 +282,6 @@ static void build_retry_batch(private_tnccs_20_server_t *this)
                return;
        }
        change_batch_type(this, PB_BATCH_SRETRY);
-
-       this->recs->clear_recommendation(this->recs);
-
-       /* Handshake will be retried with next incoming CDATA batch */
-       this->retry_handshake = TRUE;
 }
 
 METHOD(tnccs_20_handler_t, process, status_t,
@@ -307,22 +302,13 @@ METHOD(tnccs_20_handler_t, process, status_t,
                pb_tnc_msg_t *msg;
                bool empty = TRUE;
 
-               if (batch_type == PB_BATCH_CDATA)
-               {
-                       /* retry handshake after a previous SRETRY batch */
-                       if (this->retry_handshake)
-                       {
-                               tnc->imvs->notify_connection_change(tnc->imvs,
-                                               this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
-                               this->retry_handshake = FALSE;
-                       }
-               }
-               else if (batch_type == PB_BATCH_CRETRY)
+               if (batch_type == PB_BATCH_CRETRY ||
+                  (batch_type == PB_BATCH_CDATA && this->retry_handshake))
                {
-                       /* Send an SRETRY batch in response */
-                       this->mutex->lock(this->mutex);
-                       build_retry_batch(this);
-                       this->mutex->unlock(this->mutex);
+                       this->recs->clear_recommendation(this->recs);
+                       tnc->imvs->notify_connection_change(tnc->imvs,
+                                       this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
+                       this->retry_handshake = FALSE;
                }
 
                enumerator = batch->create_msg_enumerator(batch);
@@ -441,9 +427,12 @@ METHOD(tnccs_20_handler_t, build, status_t,
 
        if (this->request_handshake_retry)
        {
-               if (state != PB_STATE_INIT)
+               if (state == PB_STATE_DECIDED)
                {
                        build_retry_batch(this);
+
+                       /* Handshake will be retried with next incoming CDATA batch */
+                       this->retry_handshake = TRUE;
                }
 
                /* Reset the flag for the next handshake retry request */