Corrected use of PB-TNC CRETRY and SRETRY batches

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.
This commit is contained in:
Andreas Steffen 2019-03-29 15:33:24 +01:00
parent 35b82000f1
commit 6fcb3baae8
4 changed files with 31 additions and 28 deletions

7
NEWS
View File

@ -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
----------------

View 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;

View 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);
}

View 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)
if (batch_type == PB_BATCH_CRETRY ||
(batch_type == PB_BATCH_CDATA && this->retry_handshake))
{
/* 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)
{
/* 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 */