]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
implemented get|set_identifier() for tls_eap_t
authorAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 5 Apr 2011 16:14:58 +0000 (18:14 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 5 Apr 2011 16:14:58 +0000 (18:14 +0200)
src/libtls/tls_eap.c
src/libtls/tls_eap.h

index 8204a34414cee6b543f32f31e6584ef22a581a88..226422c35f9de590a65d8f7fe5cd5fe6e21a43d4 100644 (file)
@@ -40,6 +40,11 @@ struct private_tls_eap_t {
         */
        eap_type_t type;
 
+       /**
+        * Current value of EAP identifier
+        */
+       u_int8_t identifier;
+
        /**
         * TLS stack
         */
@@ -75,14 +80,15 @@ struct private_tls_eap_t {
  * Flags of an EAP-TLS/TTLS/TNC message
  */
 typedef enum {
-       EAP_TLS_LENGTH = (1<<7),                /* shared with EAP-TTLS/TNC */
-       EAP_TLS_MORE_FRAGS = (1<<6),    /* shared with EAP-TTLS/TNC */
-       EAP_TLS_START = (1<<5),                 /* shared with EAP-TTLS/TNC */
-       EAP_TTLS_VERSION = (0x07),              /* shared with EAP-TNC      */
+       EAP_TLS_LENGTH = (1<<7),                /* shared with EAP-TTLS/TNC/PEAP */
+       EAP_TLS_MORE_FRAGS = (1<<6),    /* shared with EAP-TTLS/TNC/PEAP */
+       EAP_TLS_START = (1<<5),                 /* shared with EAP-TTLS/TNC/PEAP */
+       EAP_TTLS_VERSION = (0x07),              /* shared with EAP-TNC/PEAP      */
 } eap_tls_flags_t;
 
 #define EAP_TTLS_SUPPORTED_VERSION     0
 #define EAP_TNC_SUPPORTED_VERSION      1
+#define EAP_PEAP_SUPPORTED_VERSION     0
 
 /**
  * EAP-TLS/TTLS packet format
@@ -113,15 +119,14 @@ METHOD(tls_eap_t, initiate, status_t,
                        case EAP_TNC:
                                pkt.flags |= EAP_TNC_SUPPORTED_VERSION;
                                break;
+                       case EAP_PEAP:
+                               pkt.flags |= EAP_PEAP_SUPPORTED_VERSION;
+                               break;
                        default:
                                break;
                }
                htoun16(&pkt.length, sizeof(eap_tls_packet_t));
-               do
-               {       /* start with non-zero random identifier */
-                       pkt.identifier = random();
-               }
-               while (!pkt.identifier);
+               pkt.identifier = this->identifier;
 
                DBG2(DBG_IKE, "sending %N start packet", eap_type_names, this->type);
                *out = chunk_clone(chunk_from_thing(pkt));
@@ -163,8 +168,7 @@ static status_t process_pkt(private_tls_eap_t *this, eap_tls_packet_t *pkt)
 /**
  * Build a packet to send
  */
-static status_t build_pkt(private_tls_eap_t *this,
-                                                 u_int8_t identifier, chunk_t *out)
+static status_t build_pkt(private_tls_eap_t *this, chunk_t *out)
 {
        char buf[this->frag_size];
        eap_tls_packet_t *pkt;
@@ -172,9 +176,13 @@ static status_t build_pkt(private_tls_eap_t *this,
        status_t status;
        char *kind;
 
+       if (this->is_server)
+       {
+               this->identifier++;
+       }
        pkt = (eap_tls_packet_t*)buf;
        pkt->code = this->is_server ? EAP_REQUEST : EAP_RESPONSE;
-       pkt->identifier = this->is_server ? identifier + 1 : identifier;
+       pkt->identifier = this->identifier;
        pkt->type = this->type;
        pkt->flags = 0;
 
@@ -186,6 +194,9 @@ static status_t build_pkt(private_tls_eap_t *this,
                case EAP_TNC:
                        pkt->flags |= EAP_TNC_SUPPORTED_VERSION;
                        break;
+               case EAP_PEAP:
+                       pkt->flags |= EAP_PEAP_SUPPORTED_VERSION;
+                       break;
                default:
                        break;
        }
@@ -242,22 +253,31 @@ static status_t build_pkt(private_tls_eap_t *this,
 /**
  * Send an ack to request next fragment
  */
-static chunk_t create_ack(private_tls_eap_t *this, u_int8_t identifier)
+static chunk_t create_ack(private_tls_eap_t *this)
 {
        eap_tls_packet_t pkt = {
                .code = this->is_server ? EAP_REQUEST : EAP_RESPONSE,
-               .identifier = this->is_server ? identifier + 1 : identifier,
                .type = this->type,
        };
+
+       if (this->is_server)
+       {
+               this->identifier++;
+       }
+       pkt.identifier = this->identifier;
        htoun16(&pkt.length, sizeof(pkt));
+
        switch (this->type)
        {
                case EAP_TTLS:
                        pkt.flags |= EAP_TTLS_SUPPORTED_VERSION;
-               break;
+                       break;
                case EAP_TNC:
                        pkt.flags |= EAP_TNC_SUPPORTED_VERSION;
                        break;
+               case EAP_PEAP:
+                       pkt.flags |= EAP_PEAP_SUPPORTED_VERSION;
+                       break;
                default:
                        break;
        }
@@ -281,16 +301,19 @@ METHOD(tls_eap_t, process, status_t,
        }
 
        pkt = (eap_tls_packet_t*)in.ptr;
-       if (in.len < sizeof(eap_tls_packet_t) ||
-               untoh16(&pkt->length) != in.len)
+       if (in.len < sizeof(eap_tls_packet_t) || untoh16(&pkt->length) != in.len)
        {
-               DBG1(DBG_IKE, "invalid %N packet length",
-                        eap_type_names, this->type);
+               DBG1(DBG_IKE, "invalid %N packet length", eap_type_names, this->type);
                return FAILED;
        }
+
+       /* update EAP identifier */
+       this->identifier = pkt->identifier;
+
        if (pkt->flags & EAP_TLS_START)
        {
-               if (this->type == EAP_TTLS || this->type == EAP_TNC)
+               if (this->type == EAP_TTLS || this->type == EAP_TNC ||
+                       this->type == EAP_PEAP)
                {
                        DBG1(DBG_TLS, "%N version is v%u", eap_type_names, this->type,
                                 pkt->flags & EAP_TTLS_VERSION);
@@ -302,7 +325,7 @@ METHOD(tls_eap_t, process, status_t,
                {
                        DBG2(DBG_TLS, "received %N acknowledgement packet",
                                 eap_type_names, this->type);
-                       status = build_pkt(this, pkt->identifier, out);
+                       status = build_pkt(this, out);
                        if (status == INVALID_STATE && this->tls->is_complete(this->tls))
                        {
                                return SUCCESS;
@@ -320,16 +343,16 @@ METHOD(tls_eap_t, process, status_t,
                                return status;
                }
        }
-       status = build_pkt(this, pkt->identifier, out);
+       status = build_pkt(this, out);
        switch (status)
        {
                case INVALID_STATE:
-                       *out = create_ack(this, pkt->identifier);
+                       *out = create_ack(this);
                        return NEED_MORE;
                case FAILED:
                        if (!this->is_server)
                        {
-                               *out = create_ack(this, pkt->identifier);
+                               *out = create_ack(this);
                                return NEED_MORE;
                        }
                        return FAILED;
@@ -344,6 +367,18 @@ METHOD(tls_eap_t, get_msk, chunk_t,
        return this->tls->get_eap_msk(this->tls);
 }
 
+METHOD(tls_eap_t, get_identifier, u_int8_t,
+       private_tls_eap_t *this)
+{
+       return this->identifier;
+}
+
+METHOD(tls_eap_t, set_identifier, void,
+       private_tls_eap_t *this, u_int8_t identifier)
+{
+       this->identifier = identifier;
+}
+
 METHOD(tls_eap_t, destroy, void,
        private_tls_eap_t *this)
 {
@@ -369,6 +404,8 @@ tls_eap_t *tls_eap_create(eap_type_t type, tls_t *tls, size_t frag_size,
                        .initiate = _initiate,
                        .process = _process,
                        .get_msk = _get_msk,
+                       .get_identifier = _get_identifier,
+                       .set_identifier = _set_identifier,
                        .destroy = _destroy,
                },
                .type = type,
@@ -379,5 +416,14 @@ tls_eap_t *tls_eap_create(eap_type_t type, tls_t *tls, size_t frag_size,
                .tls = tls,
        );
 
+       if (this->is_server)
+       {
+               do
+               {       /* start with non-zero random identifier */
+                       this->identifier = random();
+               }
+               while (!this->identifier);
+       }
+
        return &this->public;
 }
index ebda2636d87c05aa66ac709e591f6f3e14801661..186703f97f4501f6ca110cff5f272d699203f035 100644 (file)
@@ -61,6 +61,21 @@ struct tls_eap_t {
         */
        chunk_t (*get_msk)(tls_eap_t *this);
 
+       /**
+        * Get the current EAP identifier.
+        *
+        * @return                              identifier
+        */
+       u_int8_t (*get_identifier)(tls_eap_t *this);
+
+       /**
+        * Set the EAP identifier to a deterministic value, overwriting
+        * the randomly initialized default value.
+        *
+        * @param identifier    EAP identifier
+        */
+       void (*set_identifier) (tls_eap_t *this, u_int8_t identifier);
+
        /**
         * Destroy a tls_eap_t.
         */