ike: Only parse payloads valid for the current IKE version
authorTobias Brunner <tobias@strongswan.org>
Tue, 21 Oct 2014 12:03:25 +0000 (14:03 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 5 Dec 2014 14:41:47 +0000 (15:41 +0100)
src/libcharon/encoding/message.c
src/libcharon/encoding/parser.c
src/libcharon/encoding/parser.h
src/libcharon/encoding/payloads/encrypted_payload.c

index ba71238..0a596ff 100644 (file)
@@ -2155,6 +2155,8 @@ METHOD(message_t, parse_header, status_t,
        }
        ike_header->destroy(ike_header);
 
+       this->parser->set_major_version(this->parser, this->major_version);
+
        DBG2(DBG_ENC, "parsed a %N %s header", exchange_type_names,
                 this->exchange_type, this->major_version == IKEV1_MAJOR_VERSION ?
                 "message" : (this->is_request ? "request" : "response"));
index d6240fd..f834036 100644 (file)
@@ -59,6 +59,11 @@ struct private_parser_t {
        parser_t public;
 
        /**
+        * major IKE version
+        */
+       u_int8_t major_version;
+
+       /**
         * Current bit for reading in input data.
         */
        u_int8_t bit_pos;
@@ -369,7 +374,14 @@ METHOD(parser_t, parse_payload, status_t,
        encoding_rule_t *rule;
 
        /* create instance of the payload to parse */
-       pld = payload_create(payload_type);
+       if (payload_is_known(payload_type, this->major_version))
+       {
+               pld = payload_create(payload_type);
+       }
+       else
+       {
+               pld = (payload_t*)unknown_payload_create(payload_type);
+       }
 
        DBG2(DBG_ENC, "parsing %N payload, %d bytes left",
                 payload_type_names, payload_type, this->input_roof - this->byte_pos);
@@ -629,6 +641,12 @@ METHOD(parser_t, reset_context, void,
        this->bit_pos = 0;
 }
 
+METHOD(parser_t, set_major_version, void,
+       private_parser_t *this, u_int8_t major_version)
+{
+       this->major_version = major_version;
+}
+
 METHOD(parser_t, destroy, void,
        private_parser_t *this)
 {
@@ -646,6 +664,7 @@ parser_t *parser_create(chunk_t data)
                .public = {
                        .parse_payload = _parse_payload,
                        .reset_context = _reset_context,
+                       .set_major_version = _set_major_version,
                        .get_remaining_byte_count = _get_remaining_byte_count,
                        .destroy = _destroy,
                },
index 27c5f03..5fd3e86 100644 (file)
@@ -29,7 +29,7 @@ typedef struct parser_t parser_t;
 #include <encoding/payloads/payload.h>
 
 /**
- * A parser_t class to parse IKEv2 payloads.
+ * A parser_t class to parse IKE payloads.
  *
  * A parser is used for parsing one chunk of data. Multiple
  * payloads can be parsed out of the chunk using parse_payload.
@@ -50,7 +50,8 @@ struct parser_t {
         *                                              - SUCCESSFUL if succeeded,
         *                                              - PARSE_ERROR if corrupted/invalid data found
         */
-       status_t (*parse_payload) (parser_t *this, payload_type_t payload_type, payload_t **payload);
+       status_t (*parse_payload) (parser_t *this, payload_type_t payload_type,
+                                                          payload_t **payload);
 
        /**
         * Gets the remaining byte count which is not currently parsed.
@@ -63,6 +64,13 @@ struct parser_t {
        void (*reset_context) (parser_t *this);
 
        /**
+        * Set the major IKE version.
+        *
+        * @param major_version the major IKE version
+        */
+       void (*set_major_version) (parser_t *this, u_int8_t major_version);
+
+       /**
         * Destroys a parser_t object.
         */
        void (*destroy) (parser_t *this);
index 5c574c3..04372fd 100644 (file)
@@ -561,6 +561,7 @@ static status_t parse(private_encrypted_payload_t *this, chunk_t plain)
        payload_type_t type;
 
        parser = parser_create(plain);
+       parser->set_major_version(parser, this->type == PLV1_ENCRYPTED ? 1 : 2);
        type = this->next_payload;
        while (type != PL_NONE)
        {