diff options
Diffstat (limited to 'src/libcharon/encoding')
-rw-r--r-- | src/libcharon/encoding/message.c | 66 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/encrypted_payload.c | 5 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/payload.c | 2 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/payload.h | 7 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/unknown_payload.c | 8 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/unknown_payload.h | 8 |
6 files changed, 90 insertions, 6 deletions
diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c index 0a596ffb0..3303024cd 100644 --- a/src/libcharon/encoding/message.c +++ b/src/libcharon/encoding/message.c @@ -1411,6 +1411,55 @@ static char* get_string(private_message_t *this, char *buf, int len) len -= written; } } + if (payload->get_type(payload) == PLV1_FRAGMENT) + { + fragment_payload_t *frag; + + frag = (fragment_payload_t*)payload; + if (frag->is_last(frag)) + { + written = snprintf(pos, len, "(%u/%u)", + frag->get_number(frag), frag->get_number(frag)); + } + else + { + written = snprintf(pos, len, "(%u)", frag->get_number(frag)); + } + if (written >= len || written < 0) + { + return buf; + } + pos += written; + len -= written; + } + if (payload->get_type(payload) == PLV2_FRAGMENT) + { + encrypted_fragment_payload_t *frag; + + frag = (encrypted_fragment_payload_t*)payload; + written = snprintf(pos, len, "(%u/%u)", + frag->get_fragment_number(frag), + frag->get_total_fragments(frag)); + if (written >= len || written < 0) + { + return buf; + } + pos += written; + len -= written; + } + if (payload->get_type(payload) == PL_UNKNOWN) + { + unknown_payload_t *unknown; + + unknown = (unknown_payload_t*)payload; + written = snprintf(pos, len, "(%d)", unknown->get_type(unknown)); + if (written >= len || written < 0) + { + return buf; + } + pos += written; + len -= written; + } } enumerator->destroy(enumerator); @@ -2237,9 +2286,16 @@ static status_t parse_payloads(private_message_t *this) payload->destroy(payload); return VERIFY_ERROR; } - - DBG2(DBG_ENC, "%N payload verified, adding to payload list", - payload_type_names, type); + if (payload->get_type(payload) == PL_UNKNOWN) + { + DBG2(DBG_ENC, "%N payload unknown or not allowed", + payload_type_names, type); + } + else + { + DBG2(DBG_ENC, "%N payload verified, adding to payload list", + payload_type_names, type); + } this->payloads->insert_last(this->payloads, payload); /* an encrypted (fragment) payload MUST be the last one, so STOP here. @@ -2477,7 +2533,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) { @@ -2625,7 +2681,7 @@ METHOD(message_t, parse_body, status_t, other_hash = hash_payload->get_hash(hash_payload); DBG3(DBG_ENC, "HASH received %B\nHASH expected %B", &other_hash, &hash); - if (!chunk_equals(hash, other_hash)) + if (!chunk_equals_const(hash, other_hash)) { DBG1(DBG_ENC, "received HASH payload does not match"); chunk_free(&hash); diff --git a/src/libcharon/encoding/payloads/encrypted_payload.c b/src/libcharon/encoding/payloads/encrypted_payload.c index 04372fdf0..d1a267836 100644 --- a/src/libcharon/encoding/payloads/encrypted_payload.c +++ b/src/libcharon/encoding/payloads/encrypted_payload.c @@ -502,6 +502,8 @@ METHOD(encrypted_payload_t, encrypt, status_t, generator = generator_create(); plain = generate(this, generator); assoc = append_header(this, assoc); + /* lower 32-bits are for fragment number, if used */ + mid <<= 32; status = encrypt_content("encrypted payload", this->aead, mid, plain, assoc, &this->encrypted); generator->destroy(generator); @@ -932,6 +934,9 @@ METHOD(encrypted_payload_t, frag_encrypt, status_t, } free(this->encrypted.ptr); assoc = append_header_frag(this, assoc); + /* IKEv2 message IDs are not unique if fragmentation is used, hence include + * the fragment number to make it unique */ + mid = mid << 32 | this->fragment_number; status = encrypt_content("encrypted fragment payload", this->aead, mid, this->plain, assoc, &this->encrypted); free(assoc.ptr); 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 @@ -264,6 +264,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. */ PLV2_PROPOSAL_SUBSTRUCTURE, 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 @@ -121,6 +122,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 @@ -42,6 +43,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. * |