From: Tobias Brunner Date: Tue, 21 Oct 2014 12:03:25 +0000 (+0200) Subject: ike: Only parse payloads valid for the current IKE version X-Git-Tag: 5.2.2rc1~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=42e0a317c64b;p=thirdparty%2Fstrongswan.git ike: Only parse payloads valid for the current IKE version --- diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c index ba71238c82..0a596ffb04 100644 --- a/src/libcharon/encoding/message.c +++ b/src/libcharon/encoding/message.c @@ -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")); diff --git a/src/libcharon/encoding/parser.c b/src/libcharon/encoding/parser.c index d6240fde27..f8340367eb 100644 --- a/src/libcharon/encoding/parser.c +++ b/src/libcharon/encoding/parser.c @@ -58,6 +58,11 @@ struct private_parser_t { */ parser_t public; + /** + * major IKE version + */ + u_int8_t major_version; + /** * Current bit for reading in input data. */ @@ -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, }, diff --git a/src/libcharon/encoding/parser.h b/src/libcharon/encoding/parser.h index 27c5f03fed..5fd3e86ee6 100644 --- a/src/libcharon/encoding/parser.h +++ b/src/libcharon/encoding/parser.h @@ -29,7 +29,7 @@ typedef struct parser_t parser_t; #include /** - * 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. @@ -62,6 +63,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. */ diff --git a/src/libcharon/encoding/payloads/encrypted_payload.c b/src/libcharon/encoding/payloads/encrypted_payload.c index 5c574c34de..04372fdf06 100644 --- a/src/libcharon/encoding/payloads/encrypted_payload.c +++ b/src/libcharon/encoding/payloads/encrypted_payload.c @@ -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) {