diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2008-07-09 21:02:41 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2008-07-09 21:02:41 +0000 |
commit | db67c87db3c9089ea8d2e14f617bf3d9e2af261f (patch) | |
tree | 665c0caea83d34c11c1517c4c57137bb58cba6fb /src/charon/encoding/message.c | |
parent | 1c088a8b6237ec67f63c23f97a0f2dc4e99af869 (diff) | |
download | vyos-strongswan-db67c87db3c9089ea8d2e14f617bf3d9e2af261f.tar.gz vyos-strongswan-db67c87db3c9089ea8d2e14f617bf3d9e2af261f.zip |
[svn-upgrade] Integrating new upstream version, strongswan (4.2.4)
Diffstat (limited to 'src/charon/encoding/message.c')
-rw-r--r-- | src/charon/encoding/message.c | 545 |
1 files changed, 418 insertions, 127 deletions
diff --git a/src/charon/encoding/message.c b/src/charon/encoding/message.c index 3dfa64fb9..af9483192 100644 --- a/src/charon/encoding/message.c +++ b/src/charon/encoding/message.c @@ -1,10 +1,3 @@ -/** - * @file message.c - * - * @brief Implementation of message_t. - * - */ - /* * Copyright (C) 2006-2007 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger @@ -21,6 +14,8 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. + * + * $Id: message.c 3991 2008-05-21 17:56:21Z martin $ */ #include <stdlib.h> @@ -82,13 +77,31 @@ struct payload_rule_t { bool sufficient; }; +typedef struct payload_order_t payload_order_t; + +/** + * payload ordering structure allows us to reorder payloads according to RFC. + */ +struct payload_order_t { + + /** + * payload type + */ + payload_type_t type; + + /** + * notify type, if payload == NOTIFY + */ + notify_type_t notify; +}; + + typedef struct message_rule_t message_rule_t; /** * A message rule defines the kind of a message, * if it has encrypted contents and a list - * of payload rules. - * + * of payload ordering rules and payload parsing rules. */ struct message_rule_t { /** @@ -109,161 +122,398 @@ struct message_rule_t { /** * Number of payload rules which will follow */ - size_t payload_rule_count; + int payload_rule_count; /** * Pointer to first payload rule */ payload_rule_t *payload_rules; + + /** + * Number of payload order rules + */ + int payload_order_count; + + /** + * payload ordering rules + */ + payload_order_t *payload_order; }; /** * Message rule for IKE_SA_INIT from initiator. */ static payload_rule_t ike_sa_init_i_payload_rules[] = { - {NOTIFY,0,MAX_NOTIFY_PAYLOADS,FALSE,FALSE}, - {SECURITY_ASSOCIATION,1,1,FALSE,FALSE}, - {KEY_EXCHANGE,1,1,FALSE,FALSE}, - {NONCE,1,1,FALSE,FALSE}, - {VENDOR_ID,0,10,FALSE,FALSE}, +/* payload type min max encr suff */ + {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, FALSE, FALSE}, + {SECURITY_ASSOCIATION, 1, 1, FALSE, FALSE}, + {KEY_EXCHANGE, 1, 1, FALSE, FALSE}, + {NONCE, 1, 1, FALSE, FALSE}, + {VENDOR_ID, 0, 10, FALSE, FALSE}, +}; + +/** + * payload order for IKE_SA_INIT initiator + */ +static payload_order_t ike_sa_init_i_payload_order[] = { +/* payload type notify type */ + {NOTIFY, COOKIE}, + {SECURITY_ASSOCIATION, 0}, + {KEY_EXCHANGE, 0}, + {NONCE, 0}, + {NOTIFY, NAT_DETECTION_SOURCE_IP}, + {NOTIFY, NAT_DETECTION_DESTINATION_IP}, + {NOTIFY, 0}, + {VENDOR_ID, 0}, }; /** * Message rule for IKE_SA_INIT from responder. */ static payload_rule_t ike_sa_init_r_payload_rules[] = { - {NOTIFY,0,MAX_NOTIFY_PAYLOADS,FALSE,TRUE}, - {SECURITY_ASSOCIATION,1,1,FALSE,FALSE}, - {KEY_EXCHANGE,1,1,FALSE,FALSE}, - {NONCE,1,1,FALSE,FALSE}, - {VENDOR_ID,0,10,FALSE,FALSE}, +/* payload type min max encr suff */ + {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, FALSE, TRUE}, + {SECURITY_ASSOCIATION, 1, 1, FALSE, FALSE}, + {KEY_EXCHANGE, 1, 1, FALSE, FALSE}, + {NONCE, 1, 1, FALSE, FALSE}, + {VENDOR_ID, 0, 10, FALSE, FALSE}, +}; + +/** + * payload order for IKE_SA_INIT responder + */ +static payload_order_t ike_sa_init_r_payload_order[] = { +/* payload type notify type */ + {SECURITY_ASSOCIATION, 0}, + {KEY_EXCHANGE, 0}, + {NONCE, 0}, + {NOTIFY, NAT_DETECTION_SOURCE_IP}, + {NOTIFY, NAT_DETECTION_DESTINATION_IP}, + {NOTIFY, HTTP_CERT_LOOKUP_SUPPORTED}, + {CERTIFICATE_REQUEST, 0}, + {NOTIFY, 0}, + {VENDOR_ID, 0}, }; /** * Message rule for IKE_AUTH from initiator. */ static payload_rule_t ike_auth_i_payload_rules[] = { - {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE}, - {EXTENSIBLE_AUTHENTICATION,0,1,TRUE,TRUE}, - {AUTHENTICATION,0,1,TRUE,TRUE}, - {ID_INITIATOR,1,1,TRUE,FALSE}, - {CERTIFICATE,0,1,TRUE,FALSE}, - {CERTIFICATE_REQUEST,0,1,TRUE,FALSE}, - {ID_RESPONDER,0,1,TRUE,FALSE}, -#ifdef P2P - {SECURITY_ASSOCIATION,0,1,TRUE,FALSE}, - {TRAFFIC_SELECTOR_INITIATOR,0,1,TRUE,FALSE}, - {TRAFFIC_SELECTOR_RESPONDER,0,1,TRUE,FALSE}, +/* payload type min max encr suff */ + {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE}, + {EXTENSIBLE_AUTHENTICATION, 0, 1, TRUE, TRUE}, + {AUTHENTICATION, 0, 1, TRUE, TRUE}, + {ID_INITIATOR, 1, 1, TRUE, FALSE}, + {CERTIFICATE, 0, 4, TRUE, FALSE}, + {CERTIFICATE_REQUEST, 0, 1, TRUE, FALSE}, + {ID_RESPONDER, 0, 1, TRUE, FALSE}, +#ifdef ME + {SECURITY_ASSOCIATION, 0, 1, TRUE, FALSE}, + {TRAFFIC_SELECTOR_INITIATOR, 0, 1, TRUE, FALSE}, + {TRAFFIC_SELECTOR_RESPONDER, 0, 1, TRUE, FALSE}, #else - {SECURITY_ASSOCIATION,1,1,TRUE,FALSE}, - {TRAFFIC_SELECTOR_INITIATOR,1,1,TRUE,FALSE}, - {TRAFFIC_SELECTOR_RESPONDER,1,1,TRUE,FALSE}, -#endif /* P2P */ - {CONFIGURATION,0,1,TRUE,FALSE}, - {VENDOR_ID,0,10,TRUE,FALSE}, + {SECURITY_ASSOCIATION, 1, 1, TRUE, FALSE}, + {TRAFFIC_SELECTOR_INITIATOR, 1, 1, TRUE, FALSE}, + {TRAFFIC_SELECTOR_RESPONDER, 1, 1, TRUE, FALSE}, +#endif /* ME */ + {CONFIGURATION, 0, 1, TRUE, FALSE}, + {VENDOR_ID, 0, 10, TRUE, FALSE}, +}; + +/** + * payload order for IKE_AUTH initiator + */ +static payload_order_t ike_auth_i_payload_order[] = { +/* payload type notify type */ + {ID_INITIATOR, 0}, + {CERTIFICATE, 0}, + {NOTIFY, INITIAL_CONTACT}, + {NOTIFY, HTTP_CERT_LOOKUP_SUPPORTED}, + {CERTIFICATE_REQUEST, 0}, + {ID_RESPONDER, 0}, + {AUTHENTICATION, 0}, + {EXTENSIBLE_AUTHENTICATION, 0}, + {CONFIGURATION, 0}, + {NOTIFY, IPCOMP_SUPPORTED}, + {NOTIFY, USE_TRANSPORT_MODE}, + {NOTIFY, ESP_TFC_PADDING_NOT_SUPPORTED}, + {NOTIFY, NON_FIRST_FRAGMENTS_ALSO}, + {SECURITY_ASSOCIATION, 0}, + {TRAFFIC_SELECTOR_INITIATOR, 0}, + {TRAFFIC_SELECTOR_RESPONDER, 0}, + {NOTIFY, MOBIKE_SUPPORTED}, + {NOTIFY, ADDITIONAL_IP4_ADDRESS}, + {NOTIFY, ADDITIONAL_IP6_ADDRESS}, + {NOTIFY, NO_ADDITIONAL_ADDRESSES}, + {NOTIFY, 0}, + {VENDOR_ID, 0}, }; /** * Message rule for IKE_AUTH from responder. */ static payload_rule_t ike_auth_r_payload_rules[] = { - {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE}, - {EXTENSIBLE_AUTHENTICATION,0,1,TRUE,TRUE}, - {CERTIFICATE,0,1,TRUE,FALSE}, - {ID_RESPONDER,0,1,TRUE,FALSE}, - {AUTHENTICATION,0,1,TRUE,FALSE}, - {SECURITY_ASSOCIATION,0,1,TRUE,FALSE}, - {TRAFFIC_SELECTOR_INITIATOR,0,1,TRUE,FALSE}, - {TRAFFIC_SELECTOR_RESPONDER,0,1,TRUE,FALSE}, - {CONFIGURATION,0,1,TRUE,FALSE}, - {VENDOR_ID,0,10,TRUE,FALSE}, +/* payload type min max encr suff */ + {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE}, + {EXTENSIBLE_AUTHENTICATION, 0, 1, TRUE, TRUE}, + {CERTIFICATE, 0, 4, TRUE, FALSE}, + {ID_RESPONDER, 0, 1, TRUE, FALSE}, + {AUTHENTICATION, 0, 1, TRUE, FALSE}, + {SECURITY_ASSOCIATION, 0, 1, TRUE, FALSE}, + {TRAFFIC_SELECTOR_INITIATOR, 0, 1, TRUE, FALSE}, + {TRAFFIC_SELECTOR_RESPONDER, 0, 1, TRUE, FALSE}, + {CONFIGURATION, 0, 1, TRUE, FALSE}, + {VENDOR_ID, 0, 10, TRUE, FALSE}, }; +/** + * payload order for IKE_AUTH responder + */ +static payload_order_t ike_auth_r_payload_order[] = { +/* payload type notify type */ + {ID_RESPONDER, 0}, + {CERTIFICATE, 0}, + {AUTHENTICATION, 0}, + {EXTENSIBLE_AUTHENTICATION, 0}, + {CONFIGURATION, 0}, + {NOTIFY, IPCOMP_SUPPORTED}, + {NOTIFY, USE_TRANSPORT_MODE}, + {NOTIFY, ESP_TFC_PADDING_NOT_SUPPORTED}, + {NOTIFY, NON_FIRST_FRAGMENTS_ALSO}, + {SECURITY_ASSOCIATION, 0}, + {TRAFFIC_SELECTOR_INITIATOR, 0}, + {TRAFFIC_SELECTOR_RESPONDER, 0}, + {NOTIFY, AUTH_LIFETIME}, + {NOTIFY, MOBIKE_SUPPORTED}, + {NOTIFY, ADDITIONAL_IP4_ADDRESS}, + {NOTIFY, ADDITIONAL_IP6_ADDRESS}, + {NOTIFY, NO_ADDITIONAL_ADDRESSES}, + {NOTIFY, 0}, + {VENDOR_ID, 0}, +}; /** * Message rule for INFORMATIONAL from initiator. */ static payload_rule_t informational_i_payload_rules[] = { - {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE}, - {CONFIGURATION,0,1,TRUE,FALSE}, - {DELETE,0,1,TRUE,FALSE}, - {VENDOR_ID,0,10,TRUE,FALSE}, - +/* payload type min max encr suff */ + {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE}, + {CONFIGURATION, 0, 1, TRUE, FALSE}, + {DELETE, 0, 1, TRUE, FALSE}, + {VENDOR_ID, 0, 10, TRUE, FALSE}, +}; + +/** + * payload order for INFORMATIONAL initiator + */ +static payload_order_t informational_i_payload_order[] = { +/* payload type notify type */ + {NOTIFY, UPDATE_SA_ADDRESSES}, + {NOTIFY, NAT_DETECTION_SOURCE_IP}, + {NOTIFY, NAT_DETECTION_DESTINATION_IP}, + {NOTIFY, COOKIE2}, + {NOTIFY, 0}, + {DELETE, 0}, + {CONFIGURATION, 0}, }; /** * Message rule for INFORMATIONAL from responder. */ static payload_rule_t informational_r_payload_rules[] = { - {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE}, - {CONFIGURATION,0,1,TRUE,FALSE}, - {DELETE,0,1,TRUE,FALSE}, - {VENDOR_ID,0,10,TRUE,FALSE}, +/* payload type min max encr suff */ + {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE}, + {CONFIGURATION, 0, 1, TRUE, FALSE}, + {DELETE, 0, 1, TRUE, FALSE}, + {VENDOR_ID, 0, 10, TRUE, FALSE}, +}; + +/** + * payload order for INFORMATIONAL responder + */ +static payload_order_t informational_r_payload_order[] = { +/* payload type notify type */ + {NOTIFY, UPDATE_SA_ADDRESSES}, + {NOTIFY, NAT_DETECTION_SOURCE_IP}, + {NOTIFY, NAT_DETECTION_DESTINATION_IP}, + {NOTIFY, COOKIE2}, + {NOTIFY, 0}, + {DELETE, 0}, + {CONFIGURATION, 0}, }; /** * Message rule for CREATE_CHILD_SA from initiator. */ static payload_rule_t create_child_sa_i_payload_rules[] = { - {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE}, - {SECURITY_ASSOCIATION,1,1,TRUE,FALSE}, - {NONCE,1,1,TRUE,FALSE}, - {KEY_EXCHANGE,0,1,TRUE,FALSE}, - {TRAFFIC_SELECTOR_INITIATOR,0,1,TRUE,FALSE}, - {TRAFFIC_SELECTOR_RESPONDER,0,1,TRUE,FALSE}, - {CONFIGURATION,0,1,TRUE,FALSE}, - {VENDOR_ID,0,10,TRUE,FALSE}, +/* payload type min max encr suff */ + {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE}, + {SECURITY_ASSOCIATION, 1, 1, TRUE, FALSE}, + {NONCE, 1, 1, TRUE, FALSE}, + {KEY_EXCHANGE, 0, 1, TRUE, FALSE}, + {TRAFFIC_SELECTOR_INITIATOR, 0, 1, TRUE, FALSE}, + {TRAFFIC_SELECTOR_RESPONDER, 0, 1, TRUE, FALSE}, + {CONFIGURATION, 0, 1, TRUE, FALSE}, + {VENDOR_ID, 0, 10, TRUE, FALSE}, +}; + +/** + * payload order for CREATE_CHILD_SA from initiator. + */ +static payload_order_t create_child_sa_i_payload_order[] = { +/* payload type notify type */ + {NOTIFY, REKEY_SA}, + {NOTIFY, IPCOMP_SUPPORTED}, + {NOTIFY, USE_TRANSPORT_MODE}, + {NOTIFY, ESP_TFC_PADDING_NOT_SUPPORTED}, + {NOTIFY, NON_FIRST_FRAGMENTS_ALSO}, + {SECURITY_ASSOCIATION, 0}, + {NONCE, 0}, + {KEY_EXCHANGE, 0}, + {TRAFFIC_SELECTOR_INITIATOR, 0}, + {TRAFFIC_SELECTOR_RESPONDER, 0}, + {NOTIFY, 0}, }; /** * Message rule for CREATE_CHILD_SA from responder. */ static payload_rule_t create_child_sa_r_payload_rules[] = { - {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE}, - {SECURITY_ASSOCIATION,1,1,TRUE,FALSE}, - {NONCE,1,1,TRUE,FALSE}, - {KEY_EXCHANGE,0,1,TRUE,FALSE}, - {TRAFFIC_SELECTOR_INITIATOR,0,1,TRUE,FALSE}, - {TRAFFIC_SELECTOR_RESPONDER,0,1,TRUE,FALSE}, - {CONFIGURATION,0,1,TRUE,FALSE}, - {VENDOR_ID,0,10,TRUE,FALSE}, +/* payload type min max encr suff */ + {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE}, + {SECURITY_ASSOCIATION, 1, 1, TRUE, FALSE}, + {NONCE, 1, 1, TRUE, FALSE}, + {KEY_EXCHANGE, 0, 1, TRUE, FALSE}, + {TRAFFIC_SELECTOR_INITIATOR, 0, 1, TRUE, FALSE}, + {TRAFFIC_SELECTOR_RESPONDER, 0, 1, TRUE, FALSE}, + {CONFIGURATION, 0, 1, TRUE, FALSE}, + {VENDOR_ID, 0, 10, TRUE, FALSE}, }; -#ifdef P2P /** - * Message rule for P2P_CONNECT from initiator. + * payload order for CREATE_CHILD_SA from responder. */ -static payload_rule_t p2p_connect_i_payload_rules[] = { - {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE}, - {ID_PEER,1,1,TRUE,FALSE}, - {VENDOR_ID,0,10,TRUE,FALSE} +static payload_order_t create_child_sa_r_payload_order[] = { +/* payload type notify type */ + {NOTIFY, IPCOMP_SUPPORTED}, + {NOTIFY, USE_TRANSPORT_MODE}, + {NOTIFY, ESP_TFC_PADDING_NOT_SUPPORTED}, + {NOTIFY, NON_FIRST_FRAGMENTS_ALSO}, + {SECURITY_ASSOCIATION, 0}, + {NONCE, 0}, + {KEY_EXCHANGE, 0}, + {TRAFFIC_SELECTOR_INITIATOR, 0}, + {TRAFFIC_SELECTOR_RESPONDER, 0}, + {NOTIFY, ADDITIONAL_TS_POSSIBLE}, + {NOTIFY, 0}, }; +#ifdef ME /** - * Message rule for P2P_CONNECT from responder. + * Message rule for ME_CONNECT from initiator. */ -static payload_rule_t p2p_connect_r_payload_rules[] = { - {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE}, - {VENDOR_ID,0,10,TRUE,FALSE} +static payload_rule_t me_connect_i_payload_rules[] = { +/* payload type min max encr suff */ + {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE}, + {ID_PEER, 1, 1, TRUE, FALSE}, + {VENDOR_ID, 0, 10, TRUE, FALSE} }; -#endif /* P2P */ + +/** + * payload order for ME_CONNECT from initiator. + */ +static payload_order_t me_connect_i_payload_order[] = { +/* payload type notify type */ + {NOTIFY, 0}, + {ID_PEER, 0}, + {VENDOR_ID, 0}, +}; + +/** + * Message rule for ME_CONNECT from responder. + */ +static payload_rule_t me_connect_r_payload_rules[] = { +/* payload type min max encr suff */ + {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE}, + {VENDOR_ID, 0, 10, TRUE, FALSE} +}; + +/** + * payload order for ME_CONNECT from responder. + */ +static payload_order_t me_connect_r_payload_order[] = { +/* payload type notify type */ + {NOTIFY, 0}, + {VENDOR_ID, 0}, +}; +#endif /* ME */ /** * Message rules, defines allowed payloads. */ static message_rule_t message_rules[] = { - {IKE_SA_INIT,TRUE,FALSE,(sizeof(ike_sa_init_i_payload_rules)/sizeof(payload_rule_t)),ike_sa_init_i_payload_rules}, - {IKE_SA_INIT,FALSE,FALSE,(sizeof(ike_sa_init_r_payload_rules)/sizeof(payload_rule_t)),ike_sa_init_r_payload_rules}, - {IKE_AUTH,TRUE,TRUE,(sizeof(ike_auth_i_payload_rules)/sizeof(payload_rule_t)),ike_auth_i_payload_rules}, - {IKE_AUTH,FALSE,TRUE,(sizeof(ike_auth_r_payload_rules)/sizeof(payload_rule_t)),ike_auth_r_payload_rules}, - {INFORMATIONAL,TRUE,TRUE,(sizeof(informational_i_payload_rules)/sizeof(payload_rule_t)),informational_i_payload_rules}, - {INFORMATIONAL,FALSE,TRUE,(sizeof(informational_r_payload_rules)/sizeof(payload_rule_t)),informational_r_payload_rules}, - {CREATE_CHILD_SA,TRUE,TRUE,(sizeof(create_child_sa_i_payload_rules)/sizeof(payload_rule_t)),create_child_sa_i_payload_rules}, - {CREATE_CHILD_SA,FALSE,TRUE,(sizeof(create_child_sa_r_payload_rules)/sizeof(payload_rule_t)),create_child_sa_r_payload_rules}, -#ifdef P2P - {P2P_CONNECT,TRUE,TRUE,(sizeof(p2p_connect_i_payload_rules)/sizeof(payload_rule_t)),p2p_connect_i_payload_rules}, - {P2P_CONNECT,FALSE,TRUE,(sizeof(p2p_connect_r_payload_rules)/sizeof(payload_rule_t)),p2p_connect_r_payload_rules}, -#endif /* P2P */ + {IKE_SA_INIT, TRUE, FALSE, + (sizeof(ike_sa_init_i_payload_rules)/sizeof(payload_rule_t)), + ike_sa_init_i_payload_rules, + (sizeof(ike_sa_init_i_payload_order)/sizeof(payload_order_t)), + ike_sa_init_i_payload_order, + }, + {IKE_SA_INIT, FALSE, FALSE, + (sizeof(ike_sa_init_r_payload_rules)/sizeof(payload_rule_t)), + ike_sa_init_r_payload_rules, + (sizeof(ike_sa_init_r_payload_order)/sizeof(payload_order_t)), + ike_sa_init_r_payload_order, + }, + {IKE_AUTH, TRUE, TRUE, + (sizeof(ike_auth_i_payload_rules)/sizeof(payload_rule_t)), + ike_auth_i_payload_rules, + (sizeof(ike_auth_i_payload_order)/sizeof(payload_order_t)), + ike_auth_i_payload_order, + }, + {IKE_AUTH, FALSE, TRUE, + (sizeof(ike_auth_r_payload_rules)/sizeof(payload_rule_t)), + ike_auth_r_payload_rules, + (sizeof(ike_auth_r_payload_order)/sizeof(payload_order_t)), + ike_auth_r_payload_order, + }, + {INFORMATIONAL, TRUE, TRUE, + (sizeof(informational_i_payload_rules)/sizeof(payload_rule_t)), + informational_i_payload_rules, + (sizeof(informational_i_payload_order)/sizeof(payload_order_t)), + informational_i_payload_order, + }, + {INFORMATIONAL, FALSE, TRUE, + (sizeof(informational_r_payload_rules)/sizeof(payload_rule_t)), + informational_r_payload_rules, + (sizeof(informational_r_payload_order)/sizeof(payload_order_t)), + informational_r_payload_order, + }, + {CREATE_CHILD_SA, TRUE, TRUE, + (sizeof(create_child_sa_i_payload_rules)/sizeof(payload_rule_t)), + create_child_sa_i_payload_rules, + (sizeof(create_child_sa_i_payload_order)/sizeof(payload_order_t)), + create_child_sa_i_payload_order, + }, + {CREATE_CHILD_SA, FALSE, TRUE, + (sizeof(create_child_sa_r_payload_rules)/sizeof(payload_rule_t)), + create_child_sa_r_payload_rules, + (sizeof(create_child_sa_r_payload_order)/sizeof(payload_order_t)), + create_child_sa_r_payload_order, + }, +#ifdef ME + {ME_CONNECT, TRUE, TRUE, + (sizeof(me_connect_i_payload_rules)/sizeof(payload_rule_t)), + me_connect_i_payload_rules, + (sizeof(me_connect_i_payload_order)/sizeof(payload_order_t)), + me_connect_i_payload_order, + }, + {ME_CONNECT, FALSE, TRUE, + (sizeof(me_connect_r_payload_rules)/sizeof(payload_rule_t)), + me_connect_r_payload_rules, + (sizeof(me_connect_r_payload_order)/sizeof(payload_order_t)), + me_connect_r_payload_order, + }, +#endif /* ME */ }; @@ -517,38 +767,19 @@ static bool is_encoded(private_message_t *this) */ static void add_payload(private_message_t *this, payload_t *payload) { - payload_t *last_payload, *first_payload; - - if ((this->is_request && payload->get_type(payload) == ID_INITIATOR) || - (!this->is_request && payload->get_type(payload) == ID_RESPONDER)) + payload_t *last_payload; + + if (this->payloads->get_count(this->payloads) > 0) { - /* HOTD: insert ID payload in the beginning to respect RFC */ - if (this->payloads->get_first(this->payloads, - (void **)&first_payload) == SUCCESS) - { - payload->set_next_type(payload, first_payload->get_type(first_payload)); - } - else - { - payload->set_next_type(payload, NO_PAYLOAD); - } - this->first_payload = payload->get_type(payload); - this->payloads->insert_first(this->payloads, payload); + this->payloads->get_last(this->payloads, (void **)&last_payload); + last_payload->set_next_type(last_payload, payload->get_type(payload)); } else { - if (this->payloads->get_count(this->payloads) > 0) - { - this->payloads->get_last(this->payloads,(void **) &last_payload); - last_payload->set_next_type(last_payload, payload->get_type(payload)); - } - else - { - this->first_payload = payload->get_type(payload); - } - payload->set_next_type(payload, NO_PAYLOAD); - this->payloads->insert_last(this->payloads, payload); + this->first_payload = payload->get_type(payload); } + payload->set_next_type(payload, NO_PAYLOAD); + this->payloads->insert_last(this->payloads, payload); DBG2(DBG_ENC ,"added payload of type %N to message", payload_type_names, payload->get_type(payload)); @@ -694,9 +925,65 @@ static char* get_string(private_message_t *this, char *buf, int len) } /** + * reorder payloads depending on reordering rules + */ +static void order_payloads(private_message_t *this) +{ + linked_list_t *list; + payload_t *payload; + int i; + + /* move to temp list */ + list = linked_list_create(); + while (this->payloads->remove_last(this->payloads, + (void**)&payload) == SUCCESS) + { + list->insert_first(list, payload); + } + /* for each rule, ... */ + for (i = 0; i < this->message_rule->payload_order_count; i++) + { + enumerator_t *enumerator; + notify_payload_t *notify; + payload_order_t order = this->message_rule->payload_order[i]; + + /* ... find all payload ... */ + enumerator = list->create_enumerator(list); + while (enumerator->enumerate(enumerator, &payload)) + { + /* ... with that type ... */ + if (payload->get_type(payload) == order.type) + { + notify = (notify_payload_t*)payload; + + /**... and check notify for type. */ + if (order.type != NOTIFY || order.notify == 0 || + order.notify == notify->get_notify_type(notify)) + { + list->remove_at(list, enumerator); + add_payload(this, payload); + } + } + } + enumerator->destroy(enumerator); + } + /* append all payloads without a rule to the end */ + while (list->remove_last(list, (void**)&payload) == SUCCESS) + { + DBG1(DBG_ENC, "payload %N has no ordering rule in %N %s", + payload_type_names, payload->get_type(payload), + exchange_type_names, this->message_rule->exchange_type, + this->message_rule->is_request ? "request" : "response"); + add_payload(this, payload); + } + list->destroy(list); +} + +/** * Implementation of private_message_t.encrypt_payloads. */ -static status_t encrypt_payloads (private_message_t *this,crypter_t *crypter, signer_t* signer) +static status_t encrypt_payloads(private_message_t *this, + crypter_t *crypter, signer_t* signer) { encryption_payload_t *encryption_payload = NULL; status_t status; @@ -778,7 +1065,8 @@ static status_t encrypt_payloads (private_message_t *this,crypter_t *crypter, si /** * Implementation of message_t.generate. */ -static status_t generate(private_message_t *this, crypter_t *crypter, signer_t* signer, packet_t **packet) +static status_t generate(private_message_t *this, crypter_t *crypter, + signer_t* signer, packet_t **packet) { generator_t *generator; ike_header_t *ike_header; @@ -795,8 +1083,6 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t* return SUCCESS; } - DBG1(DBG_ENC, "generating %s", get_string(this, str, sizeof(str))); - if (this->exchange_type == EXCHANGE_TYPE_UNDEFINED) { DBG1(DBG_ENC, "exchange type is not defined"); @@ -819,6 +1105,10 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t* return NOT_SUPPORTED; } + order_payloads(this); + + DBG1(DBG_ENC, "generating %s", get_string(this, str, sizeof(str))); + /* going to encrypt all content which have to be encrypted */ status = encrypt_payloads(this, crypter, signer); if (status != SUCCESS) @@ -842,7 +1132,7 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t* payload = (payload_t*)ike_header; - /* generate every payload expect last one, this is doen later*/ + /* generate every payload expect last one, this is done later*/ iterator = this->payloads->create_iterator(this->payloads, TRUE); while(iterator->iterate(iterator, (void**)&next_payload)) { @@ -1346,3 +1636,4 @@ message_t *message_create() { return message_create_from_packet(NULL); } + |