aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2010-08-24 08:40:28 +0200
committerMartin Willi <martin@revosec.ch>2010-08-24 08:45:49 +0200
commitc5142f110ec8376b8e5cef9bb92fe4a375e4622e (patch)
tree8c9ef7c4aaf632517d848584c78bc0966a093078
parent1475800080d605abb1995bfba1ce8ca98637917c (diff)
downloadstrongswan-c5142f110ec8376b8e5cef9bb92fe4a375e4622e.tar.bz2
strongswan-c5142f110ec8376b8e5cef9bb92fe4a375e4622e.tar.xz
Check if the application layer has completed successfully
-rw-r--r--src/libtls/tls.c10
-rw-r--r--src/libtls/tls_fragmentation.c61
-rw-r--r--src/libtls/tls_fragmentation.h7
3 files changed, 62 insertions, 16 deletions
diff --git a/src/libtls/tls.c b/src/libtls/tls.c
index 1f30f5a4e..142897e59 100644
--- a/src/libtls/tls.c
+++ b/src/libtls/tls.c
@@ -243,7 +243,15 @@ METHOD(tls_t, get_purpose, tls_purpose_t,
METHOD(tls_t, is_complete, bool,
private_tls_t *this)
{
- return this->crypto->get_eap_msk(this->crypto).len != 0;
+ if (this->handshake->finished(this->handshake))
+ {
+ if (!this->application)
+ {
+ return TRUE;
+ }
+ return this->fragmentation->application_finished(this->fragmentation);
+ }
+ return FALSE;
}
METHOD(tls_t, get_eap_msk, chunk_t,
diff --git a/src/libtls/tls_fragmentation.c b/src/libtls/tls_fragmentation.c
index d69ef3901..b941c97a5 100644
--- a/src/libtls/tls_fragmentation.c
+++ b/src/libtls/tls_fragmentation.c
@@ -59,6 +59,11 @@ struct private_tls_fragmentation_t {
alert_state_t state;
/**
+ * Did the application layer complete successfully?
+ */
+ bool application_finished;
+
+ /**
* Handshake input buffer
*/
chunk_t input;
@@ -200,10 +205,17 @@ static status_t process_application(private_tls_fragmentation_t *this,
return NEED_MORE;
}
status = this->application->process(this->application, reader);
- if (status != NEED_MORE)
+ switch (status)
{
- this->alert->add(this->alert, TLS_FATAL, TLS_CLOSE_NOTIFY);
- return NEED_MORE;
+ case NEED_MORE:
+ continue;
+ case SUCCESS:
+ this->application_finished = TRUE;
+ /* FALL */
+ case FAILED:
+ default:
+ this->alert->add(this->alert, TLS_FATAL, TLS_CLOSE_NOTIFY);
+ return NEED_MORE;
}
}
return NEED_MORE;
@@ -315,21 +327,33 @@ METHOD(tls_fragmentation_t, build, status_t,
{
if (this->application)
{
- status = this->application->build(this->application, msg);
- if (status == INVALID_STATE)
+ while (TRUE)
{
- *type = TLS_APPLICATION_DATA;
- this->output = chunk_clone(msg->get_buf(msg));
- }
- else if (status != NEED_MORE)
- {
- this->alert->add(this->alert, TLS_FATAL, TLS_CLOSE_NOTIFY);
- if (check_alerts(this, data))
+ status = this->application->build(this->application, msg);
+ switch (status)
{
- this->state = ALERT_SENDING;
- *type = TLS_ALERT;
- return NEED_MORE;
+ case NEED_MORE:
+ continue;
+ case INVALID_STATE:
+ *type = TLS_APPLICATION_DATA;
+ this->output = chunk_clone(msg->get_buf(msg));
+ break;
+ case SUCCESS:
+ this->application_finished = TRUE;
+ /* FALL */
+ case FAILED:
+ default:
+ this->alert->add(this->alert, TLS_FATAL,
+ TLS_CLOSE_NOTIFY);
+ if (check_alerts(this, data))
+ {
+ this->state = ALERT_SENDING;
+ *type = TLS_ALERT;
+ msg->destroy(msg);
+ return NEED_MORE;
+ }
}
+ break;
}
}
}
@@ -382,6 +406,12 @@ METHOD(tls_fragmentation_t, build, status_t,
return status;
}
+METHOD(tls_fragmentation_t, application_finished, bool,
+ private_tls_fragmentation_t *this)
+{
+ return this->application_finished;
+}
+
METHOD(tls_fragmentation_t, destroy, void,
private_tls_fragmentation_t *this)
{
@@ -402,6 +432,7 @@ tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake,
.public = {
.process = _process,
.build = _build,
+ .application_finished = _application_finished,
.destroy = _destroy,
},
.handshake = handshake,
diff --git a/src/libtls/tls_fragmentation.h b/src/libtls/tls_fragmentation.h
index 699244595..d80278916 100644
--- a/src/libtls/tls_fragmentation.h
+++ b/src/libtls/tls_fragmentation.h
@@ -62,6 +62,13 @@ struct tls_fragmentation_t {
tls_content_type_t *type, chunk_t *data);
/**
+ * Has the application layer finished (returned SUCCESS)?.
+ *
+ * @return TRUE if application layer finished
+ */
+ bool (*application_finished)(tls_fragmentation_t *this);
+
+ /**
* Destroy a tls_fragmentation_t.
*/
void (*destroy)(tls_fragmentation_t *this);