diff options
Diffstat (limited to 'src/libtls')
-rw-r--r-- | src/libtls/tls.c | 2 | ||||
-rw-r--r-- | src/libtls/tls_fragmentation.c | 35 | ||||
-rw-r--r-- | src/libtls/tls_fragmentation.h | 4 |
3 files changed, 38 insertions, 3 deletions
diff --git a/src/libtls/tls.c b/src/libtls/tls.c index 6a8d5030c..201612470 100644 --- a/src/libtls/tls.c +++ b/src/libtls/tls.c @@ -487,7 +487,7 @@ tls_t *tls_create(bool is_server, identification_t *server, this->alert, peer, server)->handshake; } this->fragmentation = tls_fragmentation_create(this->handshake, this->alert, - this->application); + this->application, purpose); this->compression = tls_compression_create(this->fragmentation, this->alert); this->protection = tls_protection_create(this->compression, this->alert); this->crypto->set_protection(this->crypto, this->protection); diff --git a/src/libtls/tls_fragmentation.c b/src/libtls/tls_fragmentation.c index 6e4347e3c..a97ca1eaa 100644 --- a/src/libtls/tls_fragmentation.c +++ b/src/libtls/tls_fragmentation.c @@ -96,9 +96,32 @@ struct private_tls_fragmentation_t { * Upper layer application data protocol */ tls_application_t *application; + + /** + * Type of context this TLS instance runs in + */ + tls_purpose_t purpose; }; /** + * Check if we should send a close notify once the application finishes + */ +static bool send_close_notify(private_tls_fragmentation_t *this) +{ + switch (this->purpose) + { + case TLS_PURPOSE_EAP_TLS: + case TLS_PURPOSE_EAP_TTLS: + case TLS_PURPOSE_EAP_PEAP: + /* not for TLS-in-EAP, as we indicate completion with EAP-SUCCCESS. + * Windows does not like close notifies, and hangs/disconnects. */ + return FALSE; + default: + return TRUE; + } +} + +/** * Process a TLS alert */ static status_t process_alert(private_tls_fragmentation_t *this, @@ -223,6 +246,10 @@ static status_t process_application(private_tls_fragmentation_t *this, continue; case SUCCESS: this->application_finished = TRUE; + if (!send_close_notify(this)) + { + return SUCCESS; + } /* FALL */ case FAILED: default: @@ -368,6 +395,10 @@ static status_t build_application(private_tls_fragmentation_t *this) break; case SUCCESS: this->application_finished = TRUE; + if (!send_close_notify(this)) + { + break; + } /* FALL */ case FAILED: default: @@ -463,7 +494,8 @@ METHOD(tls_fragmentation_t, destroy, void, * See header */ tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake, - tls_alert_t *alert, tls_application_t *application) + tls_alert_t *alert, tls_application_t *application, + tls_purpose_t purpose) { private_tls_fragmentation_t *this; @@ -478,6 +510,7 @@ tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake, .alert = alert, .state = ALERT_NONE, .application = application, + .purpose = purpose, ); return &this->public; diff --git a/src/libtls/tls_fragmentation.h b/src/libtls/tls_fragmentation.h index f650e7be8..a49f27b20 100644 --- a/src/libtls/tls_fragmentation.h +++ b/src/libtls/tls_fragmentation.h @@ -80,9 +80,11 @@ struct tls_fragmentation_t { * @param handshake upper layer handshake protocol * @param alert TLS alert handler * @param application upper layer application data or NULL + * @param purpose type of context this TLS stack is running in * @return TLS fragmentation layer */ tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake, - tls_alert_t *alert, tls_application_t *application); + tls_alert_t *alert, tls_application_t *application, + tls_purpose_t purpose); #endif /** TLS_FRAGMENTATION_H_ @}*/ |