aboutsummaryrefslogtreecommitdiffstats
path: root/src/libtnccs/plugins
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2015-03-22 01:07:31 +0100
committerAndreas Steffen <andreas.steffen@strongswan.org>2015-03-23 22:25:43 +0100
commit7b4a96b2f7df63bddf179378c32a7b1c1998333b (patch)
treed09f05c17f8e79b44e93a15fade0832b0d637ac4 /src/libtnccs/plugins
parentc6aed8aa21e639ea54eb0605bc2639815757ea82 (diff)
downloadstrongswan-7b4a96b2f7df63bddf179378c32a7b1c1998333b.tar.bz2
strongswan-7b4a96b2f7df63bddf179378c32a7b1c1998333b.tar.xz
Implemented PB-TNC mutual half-duplex protocol
Diffstat (limited to 'src/libtnccs/plugins')
-rw-r--r--src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c1
-rw-r--r--src/libtnccs/plugins/tnccs_20/tnccs_20.c99
-rw-r--r--src/libtnccs/plugins/tnccs_20/tnccs_20_client.c34
-rw-r--r--src/libtnccs/plugins/tnccs_20/tnccs_20_handler.h11
-rw-r--r--src/libtnccs/plugins/tnccs_20/tnccs_20_server.c29
5 files changed, 139 insertions, 35 deletions
diff --git a/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c b/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c
index 859dded79..ce5b48133 100644
--- a/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c
+++ b/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c
@@ -44,6 +44,7 @@ METHOD(plugin_t, get_features, int,
PLUGIN_CALLBACK(tnc_manager_register, tnc_imc_manager_create),
PLUGIN_PROVIDE(CUSTOM, "imc-manager"),
PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
+ PLUGIN_SDEPEND(CUSTOM, "imv-manager"),
PLUGIN_SDEPEND(CERT_DECODE, CERT_X509),
PLUGIN_SDEPEND(CERT_DECODE, CERT_TRUSTED_PUBKEY),
};
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20.c b/src/libtnccs/plugins/tnccs_20/tnccs_20.c
index 33b012880..3d8615ce0 100644
--- a/src/libtnccs/plugins/tnccs_20/tnccs_20.c
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20.c
@@ -80,7 +80,7 @@ struct private_tnccs_20_t {
u_int32_t auth_type;
/**
- * Mutual TNC measurements
+ * Mutual PB-TNC protocol enabled
*/
bool mutual;
@@ -171,12 +171,12 @@ METHOD(tnccs_t, send_msg, TNC_Result,
METHOD(tls_t, process, status_t,
private_tnccs_20_t *this, void *buf, size_t buflen)
{
- chunk_t data;
pb_tnc_batch_t *batch;
- bool from_server, mutual;
+ bool from_server;
status_t status;
+ chunk_t data;
- /* On arrival of first PB-TNC batch create TNC server */
+ /* On arrival of first batch from TNC client create TNC server */
if (this->is_server && !this->tnc_server)
{
this->tnc_server = tnccs_20_server_create(&this->public, _send_msg,
@@ -187,25 +187,40 @@ METHOD(tls_t, process, status_t,
return FAILED;
}
this->tnccs_handler = this->tnc_server;
- this->tnccs_handler->begin_handshake(this->tnccs_handler);
+ this->tnccs_handler->begin_handshake(this->tnccs_handler, FALSE);
}
data = chunk_create(buf, buflen);
DBG1(DBG_TNC, "received TNCCS batch (%u bytes)", data.len);
DBG3(DBG_TNC, "%B", &data);
- /* Has a mutual connection been established? */
- mutual = this->tnc_client && this->tnc_server;
-
/* Parse the header of the received PB-TNC batch */
batch = pb_tnc_batch_create_from_data(data);
- status = batch->process_header(batch, !mutual, this->is_server,
+ status = batch->process_header(batch, !this->mutual, this->is_server,
&from_server);
- this->to_server = mutual ? from_server : !this->is_server;
- /* Set active TNCCS handler */
- this->tnccs_handler = this->to_server ? this->tnc_client : this->tnc_server;
- DBG2(DBG_TNC, "TNC %s is handling the connection",
+ this->to_server = this->mutual ? from_server : !this->is_server;
+
+ /* In the mutual case, first batch from TNC server requires a TNC client */
+ if (this->to_server && !this->tnc_client)
+ {
+ this->tnc_client = tnccs_20_client_create(&this->public, _send_msg,
+ this->max_batch_len, this->max_msg_len);
+ if (!this->tnc_client)
+ {
+ batch->destroy(batch);
+ return FAILED;
+ }
+ this->tnccs_handler = this->tnc_client;
+ this->tnccs_handler->begin_handshake(this->tnccs_handler, this->mutual);
+ }
+ else
+ {
+ /* Set active TNCCS handler for processing */
+ this->tnccs_handler = this->to_server ? this->tnc_client :
+ this->tnc_server;
+ }
+ DBG2(DBG_TNC, "TNC %s is handling inbound connection",
this->to_server ? "client" : "server");
if (status == SUCCESS)
@@ -219,6 +234,40 @@ METHOD(tls_t, process, status_t,
}
batch->destroy(batch);
+ /* Has a mutual connection been established? */
+ this->mutual = this->is_server ?
+ this->tnc_server->get_mutual(this->tnc_server) :
+ this->tnc_client->get_mutual(this->tnc_client);
+
+ if (this->mutual && !this->is_server)
+ {
+ pb_tnc_state_t client_state, server_state;
+
+ client_state = !this->tnc_client ? PB_STATE_INIT :
+ this->tnc_client->get_state(this->tnc_client);
+ server_state = !this->tnc_server ? PB_STATE_INIT :
+ this->tnc_server->get_state(this->tnc_server);
+
+ /* In half-duplex mutual mode toggle the direction on the client side */
+ if ((!this->to_server && client_state != PB_STATE_DECIDED) ||
+ ( this->to_server && server_state != PB_STATE_END))
+ {
+ this->to_server = !this->to_server;
+ }
+ else if (client_state == PB_STATE_DECIDED &&
+ server_state == PB_STATE_END)
+ {
+ /* Cause the final CLOSE batch to be sent to the TNC server */
+ this->to_server = TRUE;
+ }
+
+ /* Suppress a successful CLOSE batch coming from the TNC server */
+ if (status == SUCCESS)
+ {
+ status = NEED_MORE;
+ }
+ }
+
return status;
}
@@ -229,10 +278,15 @@ METHOD(tls_t, build, status_t,
if (this->to_server)
{
+ DBG2(DBG_TNC, "TNC client is handling outbound connection");
+
/* Before sending the first PB-TNC batch create TNC client */
- if (!this->tnc_client)
+ if (this->tnc_client)
+ {
+ this->tnccs_handler = this->tnc_client;
+ }
+ else
{
- DBG2(DBG_TNC, "TNC client is handling the connection");
this->tnc_client = tnccs_20_client_create(&this->public, _send_msg,
this->max_batch_len,
this->max_msg_len);
@@ -241,15 +295,21 @@ METHOD(tls_t, build, status_t,
status = FAILED;
}
this->tnccs_handler = this->tnc_client;
- this->tnccs_handler->begin_handshake(this->tnccs_handler);
+ this->tnccs_handler->begin_handshake(this->tnccs_handler,
+ this->mutual);
}
}
else
{
+ DBG2(DBG_TNC, "TNC server is handling outbound connection");
+
/* Before sending the first PB-TNC batch create TNC server */
- if (!this->tnc_server)
+ if (this->tnc_server)
+ {
+ this->tnccs_handler = this->tnc_server;
+ }
+ else
{
- DBG2(DBG_TNC, "TNC server is handling the connection");
this->tnc_server = tnccs_20_server_create(&this->public, _send_msg,
this->max_batch_len, this->max_msg_len,
this->eap_transport);
@@ -258,7 +318,8 @@ METHOD(tls_t, build, status_t,
status = FAILED;
}
this->tnccs_handler = this->tnc_server;
- this->tnccs_handler->begin_handshake(this->tnccs_handler);
+ this->tnccs_handler->begin_handshake(this->tnccs_handler,
+ this->mutual);
}
}
status = this->tnccs_handler->build(this->tnccs_handler, buf, buflen, msglen);
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_client.c b/src/libtnccs/plugins/tnccs_20/tnccs_20_client.c
index 4fd27a729..9bfadcb66 100644
--- a/src/libtnccs/plugins/tnccs_20/tnccs_20_client.c
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_client.c
@@ -110,6 +110,11 @@ struct private_tnccs_20_client_t {
*/
bool mutual;
+ /**
+ * Mutual Capability message sent
+ */
+ bool sent_mutual_capability;
+
};
/**
@@ -166,20 +171,29 @@ void tnccs_20_handle_ietf_error_msg(pb_tnc_msg_t *msg, bool *fatal_error)
}
}
-void tnccs_20_handle_ita_mutual_capability_msg(pb_tnc_msg_t *msg, bool *mutual)
+bool tnccs_20_handle_ita_mutual_capability_msg(pb_tnc_msg_t *msg)
{
pb_mutual_capability_msg_t *mutual_msg;
uint32_t protocols;
+ if (!lib->settings->get_bool(lib->settings,
+ "%s.plugins.tnccs-20.mutual", FALSE, lib->ns))
+ {
+ /* PB-TNC mutual capability disabled, ignore message */
+ return FALSE;
+ }
+
mutual_msg = (pb_mutual_capability_msg_t*)msg;
protocols = mutual_msg->get_protocols(mutual_msg);
if (protocols & PB_MUTUAL_HALF_DUPLEX)
{
- *mutual = TRUE;
DBG1(DBG_TNC, "activating mutual PB-TNC %N protocol",
pb_tnc_mutual_protocol_type_names, PB_MUTUAL_HALF_DUPLEX);
+ return TRUE;
}
+
+ return FALSE;
}
/**
@@ -396,7 +410,7 @@ static void handle_ita_message(private_tnccs_20_client_t *this, pb_tnc_msg_t *ms
switch (msg_type.type)
{
case PB_ITA_MSG_MUTUAL_CAPABILITY:
- tnccs_20_handle_ita_mutual_capability_msg(msg, &this->mutual);
+ this->mutual = tnccs_20_handle_ita_mutual_capability_msg(msg);
break;
default:
break;
@@ -636,7 +650,7 @@ METHOD(tnccs_20_handler_t, build, status_t,
}
METHOD(tnccs_20_handler_t, begin_handshake, void,
- private_tnccs_20_client_t *this)
+ private_tnccs_20_client_t *this, bool mutual)
{
pb_tnc_msg_t *msg;
char *pref_lang;
@@ -645,7 +659,9 @@ METHOD(tnccs_20_handler_t, begin_handshake, void,
TNC_CONNECTION_STATE_HANDSHAKE);
/* Announce PB-TNC Mutual Capability if activated */
- if (lib->settings->get_bool(lib->settings,
+ this->sent_mutual_capability = mutual;
+
+ if (!mutual && lib->settings->get_bool(lib->settings,
"%s.plugins.tnccs-20.mutual", FALSE, lib->ns))
{
pb_tnc_mutual_protocol_type_t protocols;
@@ -657,6 +673,7 @@ METHOD(tnccs_20_handler_t, begin_handshake, void,
this->mutex->lock(this->mutex);
this->messages->insert_last(this->messages, msg);
this->mutex->unlock(this->mutex);
+ this->sent_mutual_capability = TRUE;
}
/* Create PB-TNC Language Preference message */
@@ -684,6 +701,12 @@ METHOD(tnccs_20_handler_t, get_mutual, bool,
return this->mutual;
}
+METHOD(tnccs_20_handler_t, get_state, pb_tnc_state_t,
+ private_tnccs_20_client_t *this)
+{
+ return this->state_machine->get_state(this->state_machine);
+}
+
METHOD(tnccs_20_handler_t, add_msg, void,
private_tnccs_20_client_t *this, pb_tnc_msg_t *msg)
{
@@ -761,6 +784,7 @@ tnccs_20_handler_t* tnccs_20_client_create(tnccs_t *tnccs,
.begin_handshake = _begin_handshake,
.get_send_flag = _get_send_flag,
.get_mutual = _get_mutual,
+ .get_state = _get_state,
.add_msg = _add_msg,
.handle_errors = _handle_errors,
.destroy = _destroy,
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_handler.h b/src/libtnccs/plugins/tnccs_20/tnccs_20_handler.h
index 1e6da8798..45df32fc7 100644
--- a/src/libtnccs/plugins/tnccs_20/tnccs_20_handler.h
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_handler.h
@@ -54,8 +54,10 @@ struct tnccs_20_handler_t {
/**
* Put the IMCs or IMVs into the handshake state
+ *
+ * @param mutual TRUE if PB-TNC mutual mode is already established
*/
- void (*begin_handshake)(tnccs_20_handler_t *this);
+ void (*begin_handshake)(tnccs_20_handler_t *this, bool mutual);
/**
* Indicates if IMCs or IMVs are allowed to send PA-TNC messages
@@ -72,6 +74,13 @@ struct tnccs_20_handler_t {
bool (*get_mutual)(tnccs_20_handler_t *this);
/**
+ * Get state of the PB-TNC protocol
+ *
+ * @return PB-TNC state
+ */
+ pb_tnc_state_t (*get_state)(tnccs_20_handler_t *this);
+
+ /**
* Add a PB-PA message to the handler's message queue
*
* @param msg PB-PA message to be added
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_server.c b/src/libtnccs/plugins/tnccs_20/tnccs_20_server.c
index aacb5aa5f..c75ecdc39 100644
--- a/src/libtnccs/plugins/tnccs_20/tnccs_20_server.c
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_server.c
@@ -110,6 +110,11 @@ struct private_tnccs_20_server_t {
*/
bool mutual;
+ /**
+ * Mutual Capability message sent
+ */
+ bool sent_mutual_capability;
+
};
/**
@@ -117,8 +122,7 @@ struct private_tnccs_20_server_t {
*/
extern void tnccs_20_handle_ietf_error_msg(pb_tnc_msg_t *msg,
bool *fatal_error);
-extern void tnccs_20_handle_ita_mutual_capability_msg(pb_tnc_msg_t *msg,
- bool *mutual);
+extern bool tnccs_20_handle_ita_mutual_capability_msg(pb_tnc_msg_t *msg);
/**
* If the batch type changes then delete all accumulated PB-TNC messages
@@ -224,18 +228,16 @@ static void handle_ita_message(private_tnccs_20_server_t *this, pb_tnc_msg_t *ms
switch (msg_type.type)
{
case PB_ITA_MSG_MUTUAL_CAPABILITY:
- tnccs_20_handle_ita_mutual_capability_msg(msg, &this->mutual);
+ this->mutual = tnccs_20_handle_ita_mutual_capability_msg(msg);
- /* Respond with PB-TNC Mutual Capability message if activated */
- if (this->mutual && lib->settings->get_bool(lib->settings,
- "%s.plugins.tnccs-20.mutual", FALSE, lib->ns))
+ /* Respond with PB-TNC Mutual Capability message if necessary */
+ if (this->mutual && !this->sent_mutual_capability)
{
- pb_tnc_mutual_protocol_type_t protocols = PB_MUTUAL_HALF_DUPLEX;
-
- msg = pb_mutual_capability_msg_create(protocols);
+ msg = pb_mutual_capability_msg_create(PB_MUTUAL_HALF_DUPLEX);
this->mutex->lock(this->mutex);
this->messages->insert_last(this->messages, msg);
this->mutex->unlock(this->mutex);
+ this->sent_mutual_capability = TRUE;
}
break;
default:
@@ -537,7 +539,7 @@ METHOD(tnccs_20_handler_t, build, status_t,
}
METHOD(tnccs_20_handler_t, begin_handshake, void,
- private_tnccs_20_server_t *this)
+ private_tnccs_20_server_t *this, bool mutual)
{
pb_tnc_msg_t *msg;
identification_t *pdp_server;
@@ -572,6 +574,12 @@ METHOD(tnccs_20_handler_t, get_mutual, bool,
return this->mutual;
}
+METHOD(tnccs_20_handler_t, get_state, pb_tnc_state_t,
+ private_tnccs_20_server_t *this)
+{
+ return this->state_machine->get_state(this->state_machine);
+}
+
METHOD(tnccs_20_handler_t, add_msg, void,
private_tnccs_20_server_t *this, pb_tnc_msg_t *msg)
{
@@ -648,6 +656,7 @@ tnccs_20_handler_t* tnccs_20_server_create(tnccs_t *tnccs,
.begin_handshake = _begin_handshake,
.get_send_flag = _get_send_flag,
.get_mutual = _get_mutual,
+ .get_state = _get_state,
.add_msg = _add_msg,
.handle_errors = _handle_errors,
.destroy = _destroy,