diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c index 1ee2cf81b..478f531ea 100644 --- a/src/libcharon/encoding/message.c +++ b/src/libcharon/encoding/message.c @@ -2513,7 +2513,7 @@ static status_t decrypt_payloads(private_message_t *this, keymat_t *keymat) was_encrypted = "encrypted fragment payload"; } - if (payload_is_known(type, this->major_version) && !was_encrypted && + if (type != PL_UNKNOWN && !was_encrypted && !is_connectivity_check(this, payload) && this->exchange_type != AGGRESSIVE) { diff --git a/src/libcharon/encoding/payloads/payload.c b/src/libcharon/encoding/payloads/payload.c index a1cd2f945..f7c2754e0 100644 --- a/src/libcharon/encoding/payloads/payload.c +++ b/src/libcharon/encoding/payloads/payload.c @@ -97,6 +97,7 @@ ENUM_NEXT(payload_type_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_FRAGME #endif /* ME */ ENUM_NEXT(payload_type_names, PL_HEADER, PLV1_ENCRYPTED, PLV1_FRAGMENT, "HEADER", + "UNKNOWN", "PROPOSAL_SUBSTRUCTURE", "PROPOSAL_SUBSTRUCTURE_V1", "TRANSFORM_SUBSTRUCTURE", @@ -167,6 +168,7 @@ ENUM_NEXT(payload_type_short_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_ #endif /* ME */ ENUM_NEXT(payload_type_short_names, PL_HEADER, PLV1_ENCRYPTED, PLV1_FRAGMENT, "HDR", + "UNKN", "PROP", "PROP", "TRANS", diff --git a/src/libcharon/encoding/payloads/payload.h b/src/libcharon/encoding/payloads/payload.h index 920779bd1..72003894f 100644 --- a/src/libcharon/encoding/payloads/payload.h +++ b/src/libcharon/encoding/payloads/payload.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Tobias Brunner + * Copyright (C) 2007-2015 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -263,6 +263,11 @@ enum payload_type_t { */ PL_HEADER = 256, + /** + * Used to handle unknown or invalid payload types. + */ + PL_UNKNOWN, + /** * PLV2_PROPOSAL_SUBSTRUCTURE, IKEv2 proposals in a SA payload. */ diff --git a/src/libcharon/encoding/payloads/unknown_payload.c b/src/libcharon/encoding/payloads/unknown_payload.c index 45b91fd0b..c69254fc0 100644 --- a/src/libcharon/encoding/payloads/unknown_payload.c +++ b/src/libcharon/encoding/payloads/unknown_payload.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2015 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -120,6 +121,12 @@ METHOD(payload_t, get_header_length, int, METHOD(payload_t, get_payload_type, payload_type_t, private_unknown_payload_t *this) +{ + return PL_UNKNOWN; +} + +METHOD(unknown_payload_t, get_type, payload_type_t, + private_unknown_payload_t *this) { return this->type; } @@ -181,6 +188,7 @@ unknown_payload_t *unknown_payload_create(payload_type_t type) .destroy = _destroy, }, .is_critical = _is_critical, + .get_type = _get_type, .get_data = _get_data, .destroy = _destroy, }, diff --git a/src/libcharon/encoding/payloads/unknown_payload.h b/src/libcharon/encoding/payloads/unknown_payload.h index 326b550cd..09341bcc7 100644 --- a/src/libcharon/encoding/payloads/unknown_payload.h +++ b/src/libcharon/encoding/payloads/unknown_payload.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2015 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -41,6 +42,13 @@ struct unknown_payload_t { */ payload_t payload_interface; + /** + * Get the original payload type as sent by the peer. + * + * @return type of the original payload + */ + payload_type_t (*get_type) (unknown_payload_t *this); + /** * Get the raw data of this payload, without * the generic payload header. diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index 298167703..4676867df 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -1184,15 +1184,17 @@ static status_t parse_message(private_task_manager_t *this, message_t *msg) enumerator = msg->create_payload_enumerator(msg); while (enumerator->enumerate(enumerator, &payload)) { - unknown = (unknown_payload_t*)payload; - type = payload->get_type(payload); - if (!payload_is_known(type, msg->get_major_version(msg)) && - unknown->is_critical(unknown)) + if (payload->get_type(payload) == PL_UNKNOWN) { - DBG1(DBG_ENC, "payload type %N is not supported, " - "but its critical!", payload_type_names, type); - status = NOT_SUPPORTED; - break; + unknown = (unknown_payload_t*)payload; + if (unknown->is_critical(unknown)) + { + type = unknown->get_type(unknown); + DBG1(DBG_ENC, "payload type %N is not supported, " + "but its critical!", payload_type_names, type); + status = NOT_SUPPORTED; + break; + } } } enumerator->destroy(enumerator);