diff options
Diffstat (limited to 'src/charon/encoding')
-rw-r--r-- | src/charon/encoding/message.c | 38 | ||||
-rw-r--r-- | src/charon/encoding/payloads/notify_payload.c | 117 | ||||
-rw-r--r-- | src/charon/encoding/payloads/notify_payload.h | 9 |
3 files changed, 118 insertions, 46 deletions
diff --git a/src/charon/encoding/message.c b/src/charon/encoding/message.c index b31b21afa..980ff12b5 100644 --- a/src/charon/encoding/message.c +++ b/src/charon/encoding/message.c @@ -611,9 +611,13 @@ static char* get_string(private_message_t *this, char *buf, int len) int written; char *pos = buf; - written = snprintf(pos, len, "%N %s [", - exchange_type_names, this->exchange_type, - this->is_request ? "request" : "response"); + memset(buf, 0, len); + len--; + + written = snprintf(pos, len, "%N %s %d [", + exchange_type_names, this->exchange_type, + this->is_request ? "request" : "response", + this->message_id); if (written >= len || written < 0) { return ""; @@ -621,16 +625,10 @@ static char* get_string(private_message_t *this, char *buf, int len) pos += written; len -= written; - if (this->payloads->get_count(this->payloads) == 0) - { - snprintf(pos, len, "]"); - return buf; - } - iterator = this->payloads->create_iterator(this->payloads, TRUE); while (iterator->iterate(iterator, (void**)&payload)) { - written = snprintf(pos, len, "%N ", payload_type_short_names, + written = snprintf(pos, len, " %N", payload_type_short_names, payload->get_type(payload)); if (written >= len || written < 0) { @@ -638,13 +636,23 @@ static char* get_string(private_message_t *this, char *buf, int len) } pos += written; len -= written; + if (payload->get_type(payload) == NOTIFY) + { + notify_payload_t *notify = (notify_payload_t*)payload; + written = snprintf(pos, len, "(%N)", notify_type_short_names, + notify->get_notify_type(notify)); + if (written >= len || written < 0) + { + return buf; + } + pos += written; + len -= written; + } } iterator->destroy(iterator); /* remove last space */ - pos--; - len++; - snprintf(pos, len, "]"); + snprintf(pos, len, " ]"); return buf; } @@ -734,7 +742,7 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t* iterator_t *iterator; status_t status; chunk_t packet_data; - char str[128]; + char str[256]; if (is_encoded(this)) { @@ -1140,7 +1148,7 @@ static status_t parse_body(private_message_t *this, crypter_t *crypter, signer_t { status_t status = SUCCESS; payload_type_t current_payload_type; - char str[128]; + char str[256]; current_payload_type = this->first_payload; diff --git a/src/charon/encoding/payloads/notify_payload.c b/src/charon/encoding/payloads/notify_payload.c index a04901a90..e27d3c68f 100644 --- a/src/charon/encoding/payloads/notify_payload.c +++ b/src/charon/encoding/payloads/notify_payload.c @@ -47,14 +47,16 @@ ENUM_NEXT(notify_type_names, INVALID_KE_PAYLOAD, INVALID_KE_PAYLOAD, NO_PROPOSAL "INVALID_KE_PAYLOAD"); ENUM_NEXT(notify_type_names, AUTHENTICATION_FAILED, AUTHENTICATION_FAILED, INVALID_KE_PAYLOAD, "AUTHENTICATION_FAILED"); -ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, INVALID_SELECTORS, AUTHENTICATION_FAILED, +ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, UNEXPECTED_NAT_DETECTED, AUTHENTICATION_FAILED, "SINGLE_PAIR_REQUIRED", "NO_ADDITIONAL_SAS", "INTERNAL_ADDRESS_FAILURE", "FAILED_CP_REQUIRED", "TS_UNACCEPTABLE", - "INVALID_SELECTORS"); -ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, INVALID_SELECTORS, + "INVALID_SELECTORS", + "UNACCEPTABLE_ADDRESSES", + "UNEXPECTED_NAT_DETECTED"); +ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NAT_DETECTED, "INITIAL_CONTACT", "SET_WINDOW_SIZE", "ADDITIONAL_TS_POSSIBLE", @@ -79,6 +81,59 @@ ENUM_NEXT(notify_type_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, A "EAP_ONLY_AUTHENTICATION"); ENUM_END(notify_type_names, EAP_ONLY_AUTHENTICATION); + +ENUM_BEGIN(notify_type_short_names, UNSUPPORTED_CRITICAL_PAYLOAD, UNSUPPORTED_CRITICAL_PAYLOAD, + "CRIT"); +ENUM_NEXT(notify_type_short_names, INVALID_IKE_SPI, INVALID_MAJOR_VERSION, UNSUPPORTED_CRITICAL_PAYLOAD, + "INVAL_IKE_SPI", + "INVAL_MAJOR"); +ENUM_NEXT(notify_type_short_names, INVALID_SYNTAX, INVALID_SYNTAX, INVALID_MAJOR_VERSION, + "INVAL_SYN"); +ENUM_NEXT(notify_type_short_names, INVALID_MESSAGE_ID, INVALID_MESSAGE_ID, INVALID_SYNTAX, + "INVAL_MID"); +ENUM_NEXT(notify_type_short_names, INVALID_SPI, INVALID_SPI, INVALID_MESSAGE_ID, + "INVAL_SPI"); +ENUM_NEXT(notify_type_short_names, NO_PROPOSAL_CHOSEN, NO_PROPOSAL_CHOSEN, INVALID_SPI, + "NO_PROP"); +ENUM_NEXT(notify_type_short_names, INVALID_KE_PAYLOAD, INVALID_KE_PAYLOAD, NO_PROPOSAL_CHOSEN, + "INVAL_KE"); +ENUM_NEXT(notify_type_short_names, AUTHENTICATION_FAILED, AUTHENTICATION_FAILED, INVALID_KE_PAYLOAD, + "AUTH_FAILED"); +ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, UNEXPECTED_NAT_DETECTED, AUTHENTICATION_FAILED, + "SINGLE_PAIR", + "NO_ADD_SAS", + "INT_ADDR_FAIL", + "FAIL_CP_REQ", + "TS_UNACCEPT", + "INVAL_SEL", + "UNACCEPT_ADDR", + "UNEXPECT_NAT"); +ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NAT_DETECTED, + "INIT_CONTACT", + "SET_WINSIZE", + "ADD_TS_POSS", + "IPCOMP_SUPP", + "NATD_S_IP", + "NATD_D_IP", + "COOKIE", + "USE_TRANSP", + "HTTP_CERT_LOOK", + "REKEY_SA", + "ESP_TFC_PAD_N", + "NON_FIRST_FRAG", + "MOBIKE_SUP", + "ADD_4_ADDR", + "ADD_6_ADDR", + "NO_ADD_ADDR", + "UPD_SA_ADDR", + "COOKIE2", + "NO_NATS", + "AUTH_LFT"); +ENUM_NEXT(notify_type_short_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, AUTH_LIFETIME, + "EAP_ONLY"); +ENUM_END(notify_type_short_names, EAP_ONLY_AUTHENTICATION); + + typedef struct private_notify_payload_t private_notify_payload_t; /** @@ -189,6 +244,8 @@ encoding_rule_t notify_payload_encodings[] = { */ static status_t verify(private_notify_payload_t *this) { + bool bad_length = FALSE; + switch (this->protocol_id) { case PROTO_NONE: @@ -205,30 +262,9 @@ static status_t verify(private_notify_payload_t *this) { case INVALID_KE_PAYLOAD: { - /* check notification data */ - diffie_hellman_group_t dh_group; if (this->notification_data.len != 2) { - DBG1(DBG_ENC, "invalid notify data length for %N (%d)", - notify_type_names, this->notify_type, - this->notification_data.len); - return FAILED; - } - dh_group = ntohs(*((u_int16_t*)this->notification_data.ptr)); - switch (dh_group) - { - case MODP_768_BIT: - case MODP_1024_BIT: - case MODP_1536_BIT: - case MODP_2048_BIT: - case MODP_3072_BIT: - case MODP_4096_BIT: - case MODP_6144_BIT: - case MODP_8192_BIT: - break; - default: - DBG1(DBG_ENC, "Bad DH group (%d)", dh_group); - return FAILED; + bad_length = TRUE; } break; } @@ -237,9 +273,7 @@ static status_t verify(private_notify_payload_t *this) { if (this->notification_data.len != HASH_SIZE_SHA1) { - DBG1(DBG_ENC, "invalid %N notify length", - notify_type_names, this->notify_type); - return FAILED; + bad_length = TRUE; } break; } @@ -249,9 +283,23 @@ static status_t verify(private_notify_payload_t *this) { if (this->notification_data.len != 0) { - DBG1(DBG_ENC, "invalid %N notify", - notify_type_names, this->notify_type); - return FAILED; + bad_length = TRUE; + } + break; + } + case ADDITIONAL_IP4_ADDRESS: + { + if (this->notification_data.len != 4) + { + bad_length = TRUE; + } + break; + } + case ADDITIONAL_IP6_ADDRESS: + { + if (this->notification_data.len != 16) + { + bad_length = TRUE; } break; } @@ -259,6 +307,13 @@ static status_t verify(private_notify_payload_t *this) /* TODO: verify */ break; } + if (bad_length) + { + DBG1(DBG_ENC, "invalid notify data length for %N (%d)", + notify_type_names, this->notify_type, + this->notification_data.len); + return FAILED; + } return SUCCESS; } diff --git a/src/charon/encoding/payloads/notify_payload.h b/src/charon/encoding/payloads/notify_payload.h index 431932631..231d0408d 100644 --- a/src/charon/encoding/payloads/notify_payload.h +++ b/src/charon/encoding/payloads/notify_payload.h @@ -65,6 +65,8 @@ enum notify_type_t { FAILED_CP_REQUIRED = 37, TS_UNACCEPTABLE = 38, INVALID_SELECTORS = 39, + UNACCEPTABLE_ADDRESSES = 40, + UNEXPECTED_NAT_DETECTED = 41, /* notify status messages */ INITIAL_CONTACT = 16384, SET_WINDOW_SIZE = 16385, @@ -102,6 +104,13 @@ enum notify_type_t { extern enum_name_t *notify_type_names; /** + * enum name for notify_type_t (shorter strings). + * + * @ingroup payloads + */ +extern enum_name_t *notify_type_short_names; + +/** * @brief Class representing an IKEv2-Notify Payload. * * The Notify Payload format is described in Draft section 3.10. |