do not include length field in non-fragmented EAP-PEAP packets
authorAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 21 Apr 2011 17:50:36 +0000 (19:50 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 21 Apr 2011 17:52:49 +0000 (19:52 +0200)
NEWS
man/strongswan.conf.5.in
src/libcharon/plugins/eap_peap/eap_peap.c
src/libcharon/plugins/eap_tls/eap_tls.c
src/libcharon/plugins/eap_tnc/eap_tnc.c
src/libcharon/plugins/eap_ttls/eap_ttls.c
src/libtls/tls_eap.c
src/libtls/tls_eap.h

diff --git a/NEWS b/NEWS
index af7ccf0..a11739a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -17,8 +17,7 @@ strongswan-4.5.2
   pcsc-lite based SIM card backend.
 
 - The eap-peap plugin implements the EAP PEAP protocol. Interoperates
-  successfully with a FreeRADIUS server but not yet with a Windows 7
-  Agile VPN client.
+  successfully with a FreeRADIUS server and Windows 7 Agile VPN clients.
 
 - The IKEv2 daemon charon rereads strongswan.conf on SIGHUP and instructs
   all plugins to reload. Currently only the eap-radius and the attr plugins
index bfd28ea..2d74752 100644 (file)
@@ -279,6 +279,9 @@ Maximum size of an EAP-PEAP packet
 .BR charon.plugins.eap-peap.max_message_count " [32]"
 Maximum number of processed EAP-PEAP packets
 .TP
+.BR charon.plugins.eap-peap.include_length " [no]"
+Include length in non-fragmented EAP-PEAP packets
+.TP
 .BR charon.plugins.eap-peap.phase2_method " [mschapv2]"
 Phase2 EAP client authentication method
 .TP
@@ -365,18 +368,27 @@ Maximum size of an EAP-TLS packet
 .BR charon.plugins.eap-tls.max_message_count " [32]"
 Maximum number of processed EAP-TLS packets
 .TP
+.BR charon.plugins.eap-tls.include_length " [yes]"
+Include length in non-fragmented EAP-TLS packets
+.TP
 .BR charon.plugins.eap-tnc.fragment_size " [50000]"
 Maximum size of an EAP-TNC packet
 .TP
 .BR charon.plugins.eap-tnc.max_message_count " [10]"
 Maximum number of processed EAP-TNC packets
 .TP
+.BR charon.plugins.eap-tnc.include_length " [yes]"
+Include length in non-fragmented EAP-TNC packets
+.TP
 .BR charon.plugins.eap-ttls.fragment_size " [1024]"
 Maximum size of an EAP-TTLS packet
 .TP
 .BR charon.plugins.eap-ttls.max_message_count " [32]"
 Maximum number of processed EAP-TTLS packets
 .TP
+.BR charon.plugins.eap-ttls.include_length " [yes]"
+Include length in non-fragmented EAP-TTLS packets
+.TP
 .BR charon.plugins.eap-ttls.phase2_method " [md5]"
 Phase2 EAP client authentication method
 .TP
index 54c2ea0..5bae0fa 100644 (file)
@@ -152,6 +152,7 @@ static eap_peap_t *eap_peap_create(private_eap_peap_t * this,
 {
        size_t frag_size;
        int max_msg_count;
+       bool include_length;
        tls_t *tls;
 
        if (is_server && !lib->settings->get_bool(lib->settings,
@@ -163,8 +164,11 @@ static eap_peap_t *eap_peap_create(private_eap_peap_t * this,
                                        "charon.plugins.eap-peap.fragment_size", MAX_FRAGMENT_LEN);
        max_msg_count = lib->settings->get_int(lib->settings,
                                        "charon.plugins.eap-peap.max_message_count", MAX_MESSAGE_COUNT);
-       tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_PEAP, application);
-       this->tls_eap = tls_eap_create(EAP_PEAP, tls, frag_size, max_msg_count);
+       include_length = lib->settings->get_bool(lib->settings,
+                                       "charon.plugins.eap-peap.include_length", FALSE);
+       tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_PEAP, application);
+       this->tls_eap = tls_eap_create(EAP_PEAP, tls, frag_size, max_msg_count,
+                                                                                                 include_length);
        if (!this->tls_eap)
        {
                application->destroy(application);
index f6e8aba..39e1a60 100644 (file)
@@ -125,6 +125,7 @@ static eap_tls_t *eap_tls_create(identification_t *server,
        private_eap_tls_t *this;
        size_t frag_size;
        int max_msg_count;
+       bool include_length;
        tls_t *tls;
 
        INIT(this,
@@ -146,8 +147,11 @@ static eap_tls_t *eap_tls_create(identification_t *server,
                                        "charon.plugins.eap-tls.fragment_size", MAX_FRAGMENT_LEN);
        max_msg_count = lib->settings->get_int(lib->settings,
                                        "charon.plugins.eap-tls.max_message_count", MAX_MESSAGE_COUNT);
+       include_length = lib->settings->get_bool(lib->settings,
+                    "charon.plugins.eap-tls.include_length", TRUE);
        tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TLS, NULL);
-       this->tls_eap = tls_eap_create(EAP_TLS, tls, frag_size, max_msg_count);
+       this->tls_eap = tls_eap_create(EAP_TLS, tls, frag_size, max_msg_count,
+                                                                                                include_length);
        if (!this->tls_eap)
        {
                free(this);
index d47fd37..ab3f876 100644 (file)
@@ -126,6 +126,7 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
        private_eap_tnc_t *this;
        size_t frag_size;
        int max_msg_count;
+       bool include_length;
        char* protocol;
        tnccs_type_t type;
        tnccs_t *tnccs;
@@ -149,7 +150,9 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
                                        "charon.plugins.eap-tnc.fragment_size", MAX_FRAGMENT_LEN);
        max_msg_count = lib->settings->get_int(lib->settings,
                                        "charon.plugins.eap-tnc.max_message_count", MAX_MESSAGE_COUNT);
-       protocol = lib->settings->get_str(lib->settings,
+       include_length = lib->settings->get_bool(lib->settings,
+                                       "charon.plugins.eap-tnc.include_length", TRUE);
+       protocol = lib->settings->get_str(lib->settings,
                                        "charon.plugins.eap-tnc.protocol", "tnccs-1.1");
        if (strcaseeq(protocol, "tnccs-2.0"))
        {
@@ -170,7 +173,8 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
                return NULL;
        }
        tnccs = charon->tnccs->create_instance(charon->tnccs, type, is_server);
-       this->tls_eap = tls_eap_create(EAP_TNC, (tls_t*)tnccs, frag_size, max_msg_count);
+       this->tls_eap = tls_eap_create(EAP_TNC, (tls_t*)tnccs, frag_size,
+                                                                                        max_msg_count, include_length);
        if (!this->tls_eap)
        {
                free(this);
index 176b0c4..7193bc9 100644 (file)
@@ -128,6 +128,7 @@ static eap_ttls_t *eap_ttls_create(identification_t *server,
        private_eap_ttls_t *this;
        size_t frag_size;
        int max_msg_count;
+       bool include_length;
        tls_t *tls;
 
        INIT(this,
@@ -153,8 +154,11 @@ static eap_ttls_t *eap_ttls_create(identification_t *server,
                                        "charon.plugins.eap-ttls.fragment_size", MAX_FRAGMENT_LEN);
        max_msg_count = lib->settings->get_int(lib->settings,
                                        "charon.plugins.eap-ttls.max_message_count", MAX_MESSAGE_COUNT);
-       tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TTLS, application);
-       this->tls_eap = tls_eap_create(EAP_TTLS, tls, frag_size, max_msg_count);
+       include_length = lib->settings->get_bool(lib->settings,
+                                       "charon.plugins.eap-ttls.include_length", TRUE);
+       tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TTLS, application);
+       this->tls_eap = tls_eap_create(EAP_TTLS, tls, frag_size, max_msg_count,
+                                                                                                 include_length);
        if (!this->tls_eap)
        {
                application->destroy(application);
index 226422c..bb3cd49 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * Copyright (C) 2010 Martin Willi
  * Copyright (C) 2010 revosec AG
@@ -56,6 +57,13 @@ struct private_tls_eap_t {
        bool is_server;
 
        /**
+        * If FALSE include the total length of an EAP message
+        * in the first fragment of fragmented messages only.
+        * If TRUE also include the length in non-fragmented messages.
+        */
+       bool include_length;
+
+       /**
         * First fragment of a multi-fragment record?
         */
        bool first_fragment;
@@ -128,8 +136,10 @@ METHOD(tls_eap_t, initiate, status_t,
                htoun16(&pkt.length, sizeof(eap_tls_packet_t));
                pkt.identifier = this->identifier;
 
-               DBG2(DBG_IKE, "sending %N start packet", eap_type_names, this->type);
                *out = chunk_clone(chunk_from_thing(pkt));
+               DBG2(DBG_IKE, "sending %N start packet (%u bytes)",
+                                          eap_type_names, this->type, sizeof(eap_tls_packet_t));
+               DBG3(DBG_IKE, "%B", out);
                return NEED_MORE;
        }
        return FAILED;
@@ -203,7 +213,6 @@ static status_t build_pkt(private_tls_eap_t *this, chunk_t *out)
 
        if (this->first_fragment)
        {
-               pkt->flags |= EAP_TLS_LENGTH;
                len = sizeof(buf) - sizeof(eap_tls_packet_t) - sizeof(u_int32_t);
                status = this->tls->build(this->tls, buf + sizeof(eap_tls_packet_t) +
                                                                  sizeof(u_int32_t), &len, &reclen);
@@ -221,13 +230,21 @@ static status_t build_pkt(private_tls_eap_t *this, chunk_t *out)
                        kind = "further fragment";
                        if (this->first_fragment)
                        {
+                       pkt->flags |= EAP_TLS_LENGTH;
                                this->first_fragment = FALSE;
                                kind = "first fragment";
                        }
                        break;
                case ALREADY_DONE:
-                       kind = "packet";
-                       if (!this->first_fragment)
+                       if (this->first_fragment)
+                       {
+                               if (this->include_length)
+                               {
+                                       pkt->flags |= EAP_TLS_LENGTH;
+                               }
+                               kind = "packet";
+                       }
+                       else
                        {
                                this->first_fragment = TRUE;
                                kind = "final fragment";
@@ -236,17 +253,27 @@ static status_t build_pkt(private_tls_eap_t *this, chunk_t *out)
                default:
                        return status;
        }
-       DBG2(DBG_TLS, "sending %N %s (%u bytes)",
-                eap_type_names, this->type, kind, len);
        if (reclen)
        {
-               htoun32(pkt + 1, reclen);
-               len += sizeof(u_int32_t);
-               pkt->flags |= EAP_TLS_LENGTH;
+               if (pkt->flags & EAP_TLS_LENGTH)
+               { 
+                       htoun32(pkt + 1, reclen);
+                       len += sizeof(u_int32_t);
+                       pkt->flags |= EAP_TLS_LENGTH;
+               }
+               else
+               {
+                       /* get rid of the reserved length field */
+                       memcpy(buf+sizeof(eap_packet_t),
+                                  buf+sizeof(eap_packet_t)+sizeof(u_int32_t), len);    
+               }
        }
        len += sizeof(eap_tls_packet_t);
        htoun16(&pkt->length, len);
        *out = chunk_clone(chunk_create(buf, len));
+       DBG2(DBG_TLS, "sending %N %s (%u bytes)",
+                                  eap_type_names, this->type, kind, len);
+       DBG3(DBG_TLS, "%B", out);
        return NEED_MORE;
 }
 
@@ -308,7 +335,11 @@ METHOD(tls_eap_t, process, status_t,
        }
 
        /* update EAP identifier */
-       this->identifier = pkt->identifier;
+       if (!this->is_server)
+       {
+               this->identifier = pkt->identifier;
+       }
+       DBG3(DBG_TLS, "%N payload %B", eap_type_names, this->type, &in);
 
        if (pkt->flags & EAP_TLS_START)
        {
@@ -390,7 +421,7 @@ METHOD(tls_eap_t, destroy, void,
  * See header
  */
 tls_eap_t *tls_eap_create(eap_type_t type, tls_t *tls, size_t frag_size,
-                                                 int max_msg_count)
+                                                 int max_msg_count, bool include_length)
 {
        private_tls_eap_t *this;
 
@@ -413,6 +444,7 @@ tls_eap_t *tls_eap_create(eap_type_t type, tls_t *tls, size_t frag_size,
                .first_fragment = TRUE,
                .frag_size = frag_size,
                .max_msg_count = max_msg_count,
+               .include_length = include_length,
                .tls = tls,
        );
 
index 186703f..c7da832 100644 (file)
@@ -89,8 +89,9 @@ struct tls_eap_t {
  * @param tls                          TLS implementation
  * @param frag_size                    maximum size of a TLS fragment we send
  * @param max_msg_count                maximum number of processed messages
+ * @param include_length       if TRUE include length in non-fragmented packets
  */
 tls_eap_t *tls_eap_create(eap_type_t type, tls_t *tls, size_t frag_size,
-                                                 int max_msg_count);
+                                                 int max_msg_count, bool include_length);
 
 #endif /** TLS_EAP_H_ @}*/