summaryrefslogtreecommitdiff
path: root/src/charon/encoding/message.c
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2008-07-09 21:02:41 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2008-07-09 21:02:41 +0000
commitdb67c87db3c9089ea8d2e14f617bf3d9e2af261f (patch)
tree665c0caea83d34c11c1517c4c57137bb58cba6fb /src/charon/encoding/message.c
parent1c088a8b6237ec67f63c23f97a0f2dc4e99af869 (diff)
downloadvyos-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.c545
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);
}
+