diff options
author | Volker Rümelin <vr_strongswan@t-online.de> | 2012-12-15 14:11:26 +0100 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2012-12-19 11:03:42 +0100 |
commit | 0ff8d20a89e50a386584a79424a4c04c5a6c1e95 (patch) | |
tree | 8a8320e41c8e93cc5230de5784822dc3e29073c4 /src | |
parent | ecdd5aedac519eb3065bf2017a70b595ac9d75a3 (diff) | |
download | strongswan-0ff8d20a89e50a386584a79424a4c04c5a6c1e95.tar.bz2 strongswan-0ff8d20a89e50a386584a79424a4c04c5a6c1e95.tar.xz |
Add support for draft-ietf-ipsec-nat-t-ike-03 and earlier
This adds support for early versions of the draft that eventually
resulted in RFC 3947.
Diffstat (limited to 'src')
-rw-r--r-- | src/libcharon/encoding/message.c | 12 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/id_payload.c | 5 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/payload.c | 53 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/payload.h | 12 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/proposal_substructure.c | 34 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/proposal_substructure.h | 22 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/sa_payload.c | 8 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/sa_payload.h | 8 | ||||
-rw-r--r-- | src/libcharon/sa/ike_sa.h | 7 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/aggressive_mode.c | 6 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/isakmp_natd.c | 39 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/isakmp_vendor.c | 124 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/main_mode.c | 6 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/quick_mode.c | 65 |
14 files changed, 311 insertions, 90 deletions
diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c index 5a59b6c09..55e9f33fc 100644 --- a/src/libcharon/encoding/message.c +++ b/src/libcharon/encoding/message.c @@ -437,6 +437,7 @@ static payload_rule_t id_prot_i_rules[] = { {VENDOR_ID_V1, 0, MAX_VID_PAYLOADS, FALSE, FALSE}, {CERTIFICATE_REQUEST_V1, 0, MAX_CERTREQ_PAYLOADS, FALSE, FALSE}, {NAT_D_V1, 0, MAX_NAT_D_PAYLOADS, FALSE, FALSE}, + {NAT_D_DRAFT_00_03_V1, 0, MAX_NAT_D_PAYLOADS, FALSE, FALSE}, {ID_V1, 0, 1, TRUE, FALSE}, {CERTIFICATE_V1, 0, 2, TRUE, FALSE}, {SIGNATURE_V1, 0, 1, TRUE, FALSE}, @@ -459,6 +460,7 @@ static payload_order_t id_prot_i_order[] = { {NOTIFY_V1, 0}, {VENDOR_ID_V1, 0}, {NAT_D_V1, 0}, + {NAT_D_DRAFT_00_03_V1, 0}, }; /** @@ -473,6 +475,7 @@ static payload_rule_t id_prot_r_rules[] = { {VENDOR_ID_V1, 0, MAX_VID_PAYLOADS, FALSE, FALSE}, {CERTIFICATE_REQUEST_V1, 0, MAX_CERTREQ_PAYLOADS, FALSE, FALSE}, {NAT_D_V1, 0, MAX_NAT_D_PAYLOADS, FALSE, FALSE}, + {NAT_D_DRAFT_00_03_V1, 0, MAX_NAT_D_PAYLOADS, FALSE, FALSE}, {ID_V1, 0, 1, TRUE, FALSE}, {CERTIFICATE_V1, 0, 2, TRUE, FALSE}, {SIGNATURE_V1, 0, 1, TRUE, FALSE}, @@ -495,6 +498,7 @@ static payload_order_t id_prot_r_order[] = { {NOTIFY_V1, 0}, {VENDOR_ID_V1, 0}, {NAT_D_V1, 0}, + {NAT_D_DRAFT_00_03_V1, 0}, }; /** @@ -509,6 +513,7 @@ static payload_rule_t aggressive_i_rules[] = { {VENDOR_ID_V1, 0, MAX_VID_PAYLOADS, FALSE, FALSE}, {CERTIFICATE_REQUEST_V1, 0, MAX_CERTREQ_PAYLOADS, FALSE, FALSE}, {NAT_D_V1, 0, MAX_NAT_D_PAYLOADS, FALSE, FALSE}, + {NAT_D_DRAFT_00_03_V1, 0, MAX_NAT_D_PAYLOADS, FALSE, FALSE}, {ID_V1, 0, 1, FALSE, FALSE}, {CERTIFICATE_V1, 0, 1, TRUE, FALSE}, {SIGNATURE_V1, 0, 1, TRUE, FALSE}, @@ -526,6 +531,7 @@ static payload_order_t aggressive_i_order[] = { {ID_V1, 0}, {CERTIFICATE_V1, 0}, {NAT_D_V1, 0}, + {NAT_D_DRAFT_00_03_V1, 0}, {SIGNATURE_V1, 0}, {HASH_V1, 0}, {CERTIFICATE_REQUEST_V1, 0}, @@ -545,6 +551,7 @@ static payload_rule_t aggressive_r_rules[] = { {VENDOR_ID_V1, 0, MAX_VID_PAYLOADS, FALSE, FALSE}, {CERTIFICATE_REQUEST_V1, 0, MAX_CERTREQ_PAYLOADS, FALSE, FALSE}, {NAT_D_V1, 0, MAX_NAT_D_PAYLOADS, FALSE, FALSE}, + {NAT_D_DRAFT_00_03_V1, 0, MAX_NAT_D_PAYLOADS, FALSE, FALSE}, {ID_V1, 0, 1, FALSE, FALSE}, {CERTIFICATE_V1, 0, 1, FALSE, FALSE}, {SIGNATURE_V1, 0, 1, FALSE, FALSE}, @@ -562,6 +569,7 @@ static payload_order_t aggressive_r_order[] = { {ID_V1, 0}, {CERTIFICATE_V1, 0}, {NAT_D_V1, 0}, + {NAT_D_DRAFT_00_03_V1, 0}, {SIGNATURE_V1, 0}, {HASH_V1, 0}, {CERTIFICATE_REQUEST_V1, 0}, @@ -624,6 +632,7 @@ static payload_rule_t quick_mode_i_rules[] = { {KEY_EXCHANGE_V1, 0, 1, TRUE, FALSE}, {ID_V1, 0, 2, TRUE, FALSE}, {NAT_OA_V1, 0, 2, TRUE, FALSE}, + {NAT_OA_DRAFT_00_03_V1, 0, 2, TRUE, FALSE}, }; /** @@ -639,6 +648,7 @@ static payload_order_t quick_mode_i_order[] = { {KEY_EXCHANGE_V1, 0}, {ID_V1, 0}, {NAT_OA_V1, 0}, + {NAT_OA_DRAFT_00_03_V1, 0}, }; /** @@ -654,6 +664,7 @@ static payload_rule_t quick_mode_r_rules[] = { {KEY_EXCHANGE_V1, 0, 1, TRUE, FALSE}, {ID_V1, 0, 2, TRUE, FALSE}, {NAT_OA_V1, 0, 2, TRUE, FALSE}, + {NAT_OA_DRAFT_00_03_V1, 0, 2, TRUE, FALSE}, }; /** @@ -669,6 +680,7 @@ static payload_order_t quick_mode_r_order[] = { {KEY_EXCHANGE_V1, 0}, {ID_V1, 0}, {NAT_OA_V1, 0}, + {NAT_OA_DRAFT_00_03_V1, 0}, }; /** diff --git a/src/libcharon/encoding/payloads/id_payload.c b/src/libcharon/encoding/payloads/id_payload.c index 02b07d691..7470bb3b4 100644 --- a/src/libcharon/encoding/payloads/id_payload.c +++ b/src/libcharon/encoding/payloads/id_payload.c @@ -165,7 +165,7 @@ METHOD(payload_t, verify, status_t, { bool bad_length = FALSE; - if (this->type == NAT_OA_V1 && + if ((this->type == NAT_OA_V1 || this->type == NAT_OA_DRAFT_00_03_V1) && this->id_type != ID_IPV4_ADDR && this->id_type != ID_IPV6_ADDR) { DBG1(DBG_ENC, "invalid ID type %N for %N payload", id_type_names, @@ -195,7 +195,8 @@ METHOD(payload_t, verify, status_t, METHOD(payload_t, get_encoding_rules, int, private_id_payload_t *this, encoding_rule_t **rules) { - if (this->type == ID_V1 || this->type == NAT_OA_V1) + if (this->type == ID_V1 || + this->type == NAT_OA_V1 || this->type == NAT_OA_DRAFT_00_03_V1) { *rules = encodings_v1; return countof(encodings_v1); diff --git a/src/libcharon/encoding/payloads/payload.c b/src/libcharon/encoding/payloads/payload.c index dc158476b..7ddd8e72d 100644 --- a/src/libcharon/encoding/payloads/payload.c +++ b/src/libcharon/encoding/payloads/payload.c @@ -79,20 +79,15 @@ ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION, GENERIC_SECURE_PASSWORD_METH #ifdef ME ENUM_NEXT(payload_type_names, ID_PEER, ID_PEER, GENERIC_SECURE_PASSWORD_METHOD, "ID_PEER"); -ENUM_NEXT(payload_type_names, HEADER, ENCRYPTED_V1, ID_PEER, - "HEADER", - "PROPOSAL_SUBSTRUCTURE", - "PROPOSAL_SUBSTRUCTURE_V1", - "TRANSFORM_SUBSTRUCTURE", - "TRANSFORM_SUBSTRUCTURE_V1", - "TRANSFORM_ATTRIBUTE", - "TRANSFORM_ATTRIBUTE_V1", - "TRAFFIC_SELECTOR_SUBSTRUCTURE", - "CONFIGURATION_ATTRIBUTE", - "CONFIGURATION_ATTRIBUTE_V1", - "ENCRYPTED_V1"); +ENUM_NEXT(payload_type_names, NAT_D_DRAFT_00_03_V1, NAT_OA_DRAFT_00_03_V1, ID_PEER, + "NAT_D_DRAFT_V1", + "NAT_OA_DRAFT_V1"); #else -ENUM_NEXT(payload_type_names, HEADER, ENCRYPTED_V1, GENERIC_SECURE_PASSWORD_METHOD, +ENUM_NEXT(payload_type_names, NAT_D_DRAFT_00_03_V1, NAT_OA_DRAFT_00_03_V1, GENERIC_SECURE_PASSWORD_METHOD, + "NAT_D_DRAFT_V1", + "NAT_OA_DRAFT_V1"); +#endif /* ME */ +ENUM_NEXT(payload_type_names, HEADER, ENCRYPTED_V1, NAT_OA_DRAFT_00_03_V1, "HEADER", "PROPOSAL_SUBSTRUCTURE", "PROPOSAL_SUBSTRUCTURE_V1", @@ -104,7 +99,6 @@ ENUM_NEXT(payload_type_names, HEADER, ENCRYPTED_V1, GENERIC_SECURE_PASSWORD_METH "CONFIGURATION_ATTRIBUTE", "CONFIGURATION_ATTRIBUTE_V1", "ENCRYPTED_V1"); -#endif /* ME */ ENUM_END(payload_type_names, ENCRYPTED_V1); /* short forms of payload names */ @@ -147,23 +141,17 @@ ENUM_NEXT(payload_type_short_names, SECURITY_ASSOCIATION, GENERIC_SECURE_PASSWOR "EAP", "GSPM"); #ifdef ME -ENUM_NEXT(payload_type_short_names, ID_PEER, ID_PEER, - GENERIC_SECURE_PASSWORD_METHOD, +ENUM_NEXT(payload_type_short_names, ID_PEER, ID_PEER, GENERIC_SECURE_PASSWORD_METHOD, "IDp"); -ENUM_NEXT(payload_type_short_names, HEADER, ENCRYPTED_V1, ID_PEER, - "HDR", - "PROP", - "PROP", - "TRANS", - "TRANS", - "TRANSATTR", - "TRANSATTR", - "TSSUB", - "CATTR", - "CATTR", - "E"); +ENUM_NEXT(payload_type_short_names, NAT_D_DRAFT_00_03_V1, NAT_OA_DRAFT_00_03_V1, ID_PEER, + "NAT-D", + "NAT-OA"); #else -ENUM_NEXT(payload_type_short_names, HEADER, ENCRYPTED_V1, GENERIC_SECURE_PASSWORD_METHOD, +ENUM_NEXT(payload_type_short_names, NAT_D_DRAFT_00_03_V1, NAT_OA_DRAFT_00_03_V1, GENERIC_SECURE_PASSWORD_METHOD, + "NAT-D", + "NAT-OA"); +#endif /* ME */ +ENUM_NEXT(payload_type_short_names, HEADER, ENCRYPTED_V1, NAT_OA_DRAFT_00_03_V1, "HDR", "PROP", "PROP", @@ -175,7 +163,6 @@ ENUM_NEXT(payload_type_short_names, HEADER, ENCRYPTED_V1, GENERIC_SECURE_PASSWOR "CATTR", "CATTR", "E"); -#endif /* ME */ ENUM_END(payload_type_short_names, ENCRYPTED_V1); /* @@ -206,6 +193,7 @@ payload_t *payload_create(payload_type_t type) case ID_RESPONDER: case ID_V1: case NAT_OA_V1: + case NAT_OA_DRAFT_00_03_V1: #ifdef ME case ID_PEER: #endif /* ME */ @@ -239,6 +227,7 @@ payload_t *payload_create(payload_type_t type) case HASH_V1: case SIGNATURE_V1: case NAT_D_V1: + case NAT_D_DRAFT_00_03_V1: return (payload_t*)hash_payload_create(type); case CONFIGURATION: case CONFIGURATION_V1: @@ -283,6 +272,10 @@ bool payload_is_known(payload_type_t type) return TRUE; } #endif + if (type >= NAT_D_DRAFT_00_03_V1 && type <= NAT_OA_DRAFT_00_03_V1) + { + return TRUE; + } return FALSE; } diff --git a/src/libcharon/encoding/payloads/payload.h b/src/libcharon/encoding/payloads/payload.h index d5e862601..d18bbea2d 100644 --- a/src/libcharon/encoding/payloads/payload.h +++ b/src/libcharon/encoding/payloads/payload.h @@ -123,7 +123,7 @@ enum payload_type_t { NAT_D_V1 = 20, /** - * NAT original address payload (NAT-OA) + * NAT original address payload (NAT-OA). */ NAT_OA_V1 = 21, @@ -221,6 +221,16 @@ enum payload_type_t { #endif /* ME */ /** + * NAT discovery payload (NAT-D) (drafts). + */ + NAT_D_DRAFT_00_03_V1 = 130, + + /** + * NAT original address payload (NAT-OA) (drafts). + */ + NAT_OA_DRAFT_00_03_V1 = 131, + + /** * Header has a value of PRIVATE USE space. * * This type and all the following are never sent over wire and are diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c index 1616e8283..ae0fce991 100644 --- a/src/libcharon/encoding/payloads/proposal_substructure.c +++ b/src/libcharon/encoding/payloads/proposal_substructure.c @@ -253,6 +253,8 @@ typedef enum { IKEV1_ENCAP_TRANSPORT = 2, IKEV1_ENCAP_UDP_TUNNEL = 3, IKEV1_ENCAP_UDP_TRANSPORT = 4, + IKEV1_ENCAP_UDP_TUNNEL_DRAFT_00_03 = 61443, + IKEV1_ENCAP_UDP_TRANSPORT_DRAFT_00_03 = 61444, } ikev1_esp_encap_t; /** @@ -810,14 +812,30 @@ static u_int16_t get_ikev1_auth(auth_method_t method) /** * Get IKEv1 encapsulation mode */ -static u_int16_t get_ikev1_mode(ipsec_mode_t mode, bool udp) +static u_int16_t get_ikev1_mode(ipsec_mode_t mode, encap_t udp) { switch (mode) { case MODE_TUNNEL: - return udp ? IKEV1_ENCAP_UDP_TUNNEL : IKEV1_ENCAP_TUNNEL; + switch (udp) + { + case ENCAP_UDP: + return IKEV1_ENCAP_UDP_TUNNEL; + case ENCAP_UDP_DRAFT_00_03: + return IKEV1_ENCAP_UDP_TUNNEL_DRAFT_00_03; + default: + return IKEV1_ENCAP_TUNNEL; + } case MODE_TRANSPORT: - return udp ? IKEV1_ENCAP_UDP_TRANSPORT : IKEV1_ENCAP_TRANSPORT; + switch (udp) + { + case ENCAP_UDP: + return IKEV1_ENCAP_UDP_TRANSPORT; + case ENCAP_UDP_DRAFT_00_03: + return IKEV1_ENCAP_UDP_TRANSPORT_DRAFT_00_03; + default: + return IKEV1_ENCAP_TRANSPORT; + } default: return IKEV1_ENCAP_TUNNEL; } @@ -1125,9 +1143,11 @@ METHOD(proposal_substructure_t, get_encap_mode, ipsec_mode_t, case IKEV1_ENCAP_TUNNEL: return MODE_TUNNEL; case IKEV1_ENCAP_UDP_TRANSPORT: + case IKEV1_ENCAP_UDP_TRANSPORT_DRAFT_00_03: *udp = TRUE; return MODE_TRANSPORT; case IKEV1_ENCAP_UDP_TUNNEL: + case IKEV1_ENCAP_UDP_TUNNEL_DRAFT_00_03: *udp = TRUE; return MODE_TUNNEL; default: @@ -1263,7 +1283,7 @@ static void set_from_proposal_v1_ike(private_proposal_substructure_t *this, */ static void set_from_proposal_v1_esp(private_proposal_substructure_t *this, proposal_t *proposal, u_int32_t lifetime, u_int64_t lifebytes, - ipsec_mode_t mode, bool udp, int number) + ipsec_mode_t mode, encap_t udp, int number) { transform_substructure_t *transform = NULL; u_int16_t alg, key_size; @@ -1459,7 +1479,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal_v2( */ proposal_substructure_t *proposal_substructure_create_from_proposal_v1( proposal_t *proposal, u_int32_t lifetime, u_int64_t lifebytes, - auth_method_t auth, ipsec_mode_t mode, bool udp) + auth_method_t auth, ipsec_mode_t mode, encap_t udp) { private_proposal_substructure_t *this; @@ -1487,7 +1507,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal_v1( */ proposal_substructure_t *proposal_substructure_create_from_proposals_v1( linked_list_t *proposals, u_int32_t lifetime, u_int64_t lifebytes, - auth_method_t auth, ipsec_mode_t mode, bool udp) + auth_method_t auth, ipsec_mode_t mode, encap_t udp) { private_proposal_substructure_t *this = NULL; enumerator_t *enumerator; @@ -1531,7 +1551,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposals_v1( */ proposal_substructure_t *proposal_substructure_create_for_ipcomp_v1( u_int32_t lifetime, u_int64_t lifebytes, u_int16_t cpi, - ipsec_mode_t mode, bool udp, u_int8_t proposal_number) + ipsec_mode_t mode, encap_t udp, u_int8_t proposal_number) { private_proposal_substructure_t *this; transform_substructure_t *transform; diff --git a/src/libcharon/encoding/payloads/proposal_substructure.h b/src/libcharon/encoding/payloads/proposal_substructure.h index bfa8b9daa..c8e7adfd8 100644 --- a/src/libcharon/encoding/payloads/proposal_substructure.h +++ b/src/libcharon/encoding/payloads/proposal_substructure.h @@ -23,6 +23,7 @@ #ifndef PROPOSAL_SUBSTRUCTURE_H_ #define PROPOSAL_SUBSTRUCTURE_H_ +typedef enum encap_t encap_t; typedef struct proposal_substructure_t proposal_substructure_t; #include <library.h> @@ -34,6 +35,15 @@ typedef struct proposal_substructure_t proposal_substructure_t; #include <sa/authenticator.h> /** + * Encap type for proposal substructure + */ +enum encap_t { + ENCAP_NONE = 0, + ENCAP_UDP, + ENCAP_UDP_DRAFT_00_03, +}; + +/** * Class representing an IKEv1/IKEv2 proposal substructure. */ struct proposal_substructure_t { @@ -179,12 +189,12 @@ proposal_substructure_t *proposal_substructure_create_from_proposal_v2( * @param lifebytes lifebytes, in bytes * @param auth authentication method to use, or AUTH_NONE * @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL - * @param udp TRUE to use UDP encapsulation + * @param udp ENCAP_UDP to use UDP encapsulation * @return proposal_substructure_t object PROPOSAL_SUBSTRUCTURE_V1 */ proposal_substructure_t *proposal_substructure_create_from_proposal_v1( proposal_t *proposal, u_int32_t lifetime, u_int64_t lifebytes, - auth_method_t auth, ipsec_mode_t mode, bool udp); + auth_method_t auth, ipsec_mode_t mode, encap_t udp); /** * Creates an IKEv1 proposal_substructure_t from a list of proposal_t. @@ -194,12 +204,12 @@ proposal_substructure_t *proposal_substructure_create_from_proposal_v1( * @param lifebytes lifebytes, in bytes * @param auth authentication method to use, or AUTH_NONE * @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL - * @param udp TRUE to use UDP encapsulation + * @param udp ENCAP_UDP to use UDP encapsulation * @return IKEv1 proposal_substructure_t PROPOSAL_SUBSTRUCTURE_V1 */ proposal_substructure_t *proposal_substructure_create_from_proposals_v1( linked_list_t *proposals, u_int32_t lifetime, u_int64_t lifebytes, - auth_method_t auth, ipsec_mode_t mode, bool udp); + auth_method_t auth, ipsec_mode_t mode, encap_t udp); /** * Creates an IKEv1 proposal_substructure_t for IPComp with the given @@ -209,12 +219,12 @@ proposal_substructure_t *proposal_substructure_create_from_proposals_v1( * @param lifebytes lifebytes, in bytes * @param cpi the CPI to be used * @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL - * @param udp TRUE to use UDP encapsulation + * @param udp ENCAP_UDP to use UDP encapsulation * @param proposal_number the proposal number of the proposal to be linked * @return IKEv1 proposal_substructure_t PROPOSAL_SUBSTRUCTURE_V1 */ proposal_substructure_t *proposal_substructure_create_for_ipcomp_v1( u_int32_t lifetime, u_int64_t lifebytes, u_int16_t cpi, - ipsec_mode_t mode, bool udp, u_int8_t proposal_number); + ipsec_mode_t mode, encap_t udp, u_int8_t proposal_number); #endif /** PROPOSAL_SUBSTRUCTURE_H_ @}*/ diff --git a/src/libcharon/encoding/payloads/sa_payload.c b/src/libcharon/encoding/payloads/sa_payload.c index 3a8d3a760..a588d4e97 100644 --- a/src/libcharon/encoding/payloads/sa_payload.c +++ b/src/libcharon/encoding/payloads/sa_payload.c @@ -552,8 +552,8 @@ sa_payload_t *sa_payload_create_from_proposal_v2(proposal_t *proposal) */ sa_payload_t *sa_payload_create_from_proposals_v1(linked_list_t *proposals, u_int32_t lifetime, u_int64_t lifebytes, - auth_method_t auth, ipsec_mode_t mode, bool udp, - u_int16_t cpi) + auth_method_t auth, ipsec_mode_t mode, + encap_t udp, u_int16_t cpi) { proposal_substructure_t *substruct; private_sa_payload_t *this; @@ -591,8 +591,8 @@ sa_payload_t *sa_payload_create_from_proposals_v1(linked_list_t *proposals, */ sa_payload_t *sa_payload_create_from_proposal_v1(proposal_t *proposal, u_int32_t lifetime, u_int64_t lifebytes, - auth_method_t auth, ipsec_mode_t mode, bool udp, - u_int16_t cpi) + auth_method_t auth, ipsec_mode_t mode, + encap_t udp, u_int16_t cpi) { private_sa_payload_t *this; linked_list_t *proposals; diff --git a/src/libcharon/encoding/payloads/sa_payload.h b/src/libcharon/encoding/payloads/sa_payload.h index dac3043bf..b62a341d8 100644 --- a/src/libcharon/encoding/payloads/sa_payload.h +++ b/src/libcharon/encoding/payloads/sa_payload.h @@ -133,13 +133,13 @@ sa_payload_t *sa_payload_create_from_proposal_v2(proposal_t *proposal); * @param lifebytes lifebytes, in bytes * @param auth authentication method to use, or AUTH_NONE * @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL - * @param udp TRUE to use UDP encapsulation + * @param udp ENCAP_UDP to use UDP encapsulation * @param cpi CPI in case IPComp should be used * @return sa_payload_t object */ sa_payload_t *sa_payload_create_from_proposals_v1(linked_list_t *proposals, u_int32_t lifetime, u_int64_t lifebytes, - auth_method_t auth, ipsec_mode_t mode, bool udp, + auth_method_t auth, ipsec_mode_t mode, encap_t udp, u_int16_t cpi); /** @@ -150,13 +150,13 @@ sa_payload_t *sa_payload_create_from_proposals_v1(linked_list_t *proposals, * @param lifebytes lifebytes, in bytes * @param auth authentication method to use, or AUTH_NONE * @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL - * @param udp TRUE to use UDP encapsulation + * @param udp ENCAP_UDP to use UDP encapsulation * @param cpi CPI in case IPComp should be used * @return sa_payload_t object */ sa_payload_t *sa_payload_create_from_proposal_v1(proposal_t *proposal, u_int32_t lifetime, u_int64_t lifebytes, - auth_method_t auth, ipsec_mode_t mode, bool udp, + auth_method_t auth, ipsec_mode_t mode, encap_t udp, u_int16_t cpi); #endif /** SA_PAYLOAD_H_ @}*/ diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index b610055d6..7c6a9a5d9 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -72,6 +72,7 @@ enum ike_extension_t { /** * peer supports NAT traversal as specified in RFC4306 or RFC3947 + * including some RFC3947 drafts */ EXT_NATT = (1<<0), @@ -119,6 +120,12 @@ enum ike_extension_t { * peer supports Cisco Unity configuration attributes */ EXT_CISCO_UNITY = (1<<9), + + /** + * peer supports NAT traversal as specified in + * draft-ietf-ipsec-nat-t-ike-02 .. -03 + */ + EXT_NATT_DRAFT_02_03 = (1<<10), }; /** diff --git a/src/libcharon/sa/ikev1/tasks/aggressive_mode.c b/src/libcharon/sa/ikev1/tasks/aggressive_mode.c index 954dea880..7336d5d64 100644 --- a/src/libcharon/sa/ikev1/tasks/aggressive_mode.c +++ b/src/libcharon/sa/ikev1/tasks/aggressive_mode.c @@ -235,7 +235,8 @@ METHOD(task_t, build_i, status_t, this->lifetime += this->peer_cfg->get_over_time(this->peer_cfg); proposals = this->ike_cfg->get_proposals(this->ike_cfg); sa_payload = sa_payload_create_from_proposals_v1(proposals, - this->lifetime, 0, this->method, MODE_NONE, FALSE, 0); + this->lifetime, 0, this->method, MODE_NONE, + ENCAP_NONE, 0); proposals->destroy_offset(proposals, offsetof(proposal_t, destroy)); message->add_payload(message, &sa_payload->payload_interface); @@ -520,7 +521,8 @@ METHOD(task_t, build_r, status_t, identification_t *id; sa_payload = sa_payload_create_from_proposal_v1(this->proposal, - this->lifetime, 0, this->method, MODE_NONE, FALSE, 0); + this->lifetime, 0, this->method, MODE_NONE, + ENCAP_NONE, 0); message->add_payload(message, &sa_payload->payload_interface); if (!this->ph1->add_nonce_ke(this->ph1, message)) diff --git a/src/libcharon/sa/ikev1/tasks/isakmp_natd.c b/src/libcharon/sa/ikev1/tasks/isakmp_natd.c index 50bf1612d..5a71c34d8 100644 --- a/src/libcharon/sa/ikev1/tasks/isakmp_natd.c +++ b/src/libcharon/sa/ikev1/tasks/isakmp_natd.c @@ -15,6 +15,28 @@ * for more details. */ +/* + * Copyright (C) 2012 Volker Rümelin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "isakmp_natd.h" #include <string.h> @@ -75,6 +97,18 @@ struct private_isakmp_natd_t { }; /** + * Get NAT-D payload type (RFC 3947 or RFC 3947 drafts). + */ +static payload_type_t get_nat_d_payload_type(ike_sa_t *ike_sa) +{ + if (ike_sa->supports_extension(ike_sa, EXT_NATT_DRAFT_02_03)) + { + return NAT_D_DRAFT_00_03_V1; + } + return NAT_D_V1; +} + +/** * Build NAT detection hash for a host. */ static chunk_t generate_natd_hash(private_isakmp_natd_t *this, @@ -162,7 +196,7 @@ static hash_payload_t *build_natd_payload(private_isakmp_natd_t *this, bool src, { return NULL; } - payload = hash_payload_create(NAT_D_V1); + payload = hash_payload_create(get_nat_d_payload_type(this->ike_sa)); payload->set_hash(payload, hash); chunk_free(&hash); return payload; @@ -221,7 +255,8 @@ static void process_payloads(private_isakmp_natd_t *this, message_t *message) enumerator = message->create_payload_enumerator(message); while (enumerator->enumerate(enumerator, &payload)) { - if (payload->get_type(payload) != NAT_D_V1) + if (payload->get_type(payload) != NAT_D_V1 && + payload->get_type(payload) != NAT_D_DRAFT_00_03_V1) { continue; } diff --git a/src/libcharon/sa/ikev1/tasks/isakmp_vendor.c b/src/libcharon/sa/ikev1/tasks/isakmp_vendor.c index 4c6f823f4..506d05b87 100644 --- a/src/libcharon/sa/ikev1/tasks/isakmp_vendor.c +++ b/src/libcharon/sa/ikev1/tasks/isakmp_vendor.c @@ -13,6 +13,28 @@ * for more details. */ +/* + * Copyright (C) 2012 Volker Rümelin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "isakmp_vendor.h" #include <daemon.h> @@ -39,6 +61,11 @@ struct private_isakmp_vendor_t { * Are we the inititator of this task */ bool initiator; + + /** + * Index of best nat traversal VID found + */ + int best_natt_ext; }; /** @@ -65,52 +92,59 @@ static struct { { "XAuth", EXT_XAUTH, TRUE, 8, "\x09\x00\x26\x89\xdf\xd6\xb7\x12"}, - /* NAT-Traversal, MD5("RFC 3947") */ - { "NAT-T (RFC 3947)", EXT_NATT, TRUE, 16, - "\x4a\x13\x1c\x81\x07\x03\x58\x45\x5c\x57\x28\xf2\x0e\x95\x45\x2f"}, - /* Dead peer detection, RFC 3706 */ { "DPD", EXT_DPD, TRUE, 16, "\xaf\xca\xd7\x13\x68\xa1\xf1\xc9\x6b\x86\x96\xfc\x77\x57\x01\x00"}, - { "draft-stenberg-ipsec-nat-traversal-01", 0, FALSE, 16, - "\x27\xba\xb5\xdc\x01\xea\x07\x60\xea\x4e\x31\x90\xac\x27\xc0\xd0"}, + { "Cisco Unity", EXT_CISCO_UNITY, FALSE, 16, + "\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00"}, - { "draft-stenberg-ipsec-nat-traversal-02", 0, FALSE, 16, - "\x61\x05\xc4\x22\xe7\x68\x47\xe4\x3f\x96\x84\x80\x12\x92\xae\xcd"}, +}, vendor_natt_ids[] = { - { "draft-ietf-ipsec-nat-t-ike", 0, FALSE, 16, - "\x4d\xf3\x79\x28\xe9\xfc\x4f\xd1\xb3\x26\x21\x70\xd5\x15\xc6\x62"}, + /* NAT-Traversal VIDs ordered by preference */ - { "draft-ietf-ipsec-nat-t-ike-00", 0, FALSE, 16, - "\x44\x85\x15\x2d\x18\xb6\xbb\xcd\x0b\xe8\xa8\x46\x95\x79\xdd\xcc"}, + /* NAT-Traversal, MD5("RFC 3947") */ + { "NAT-T (RFC 3947)", EXT_NATT, TRUE, 16, + "\x4a\x13\x1c\x81\x07\x03\x58\x45\x5c\x57\x28\xf2\x0e\x95\x45\x2f"}, + + { "draft-ietf-ipsec-nat-t-ike-03", EXT_NATT | EXT_NATT_DRAFT_02_03, + FALSE, 16, + "\x7d\x94\x19\xa6\x53\x10\xca\x6f\x2c\x17\x9d\x92\x15\x52\x9d\x56"}, - { "draft-ietf-ipsec-nat-t-ike-02", 0, FALSE, 16, + { "draft-ietf-ipsec-nat-t-ike-02", EXT_NATT | EXT_NATT_DRAFT_02_03, + FALSE, 16, "\xcd\x60\x46\x43\x35\xdf\x21\xf8\x7c\xfd\xb2\xfc\x68\xb6\xa4\x48"}, - { "draft-ietf-ipsec-nat-t-ike-02\\n", 0, FALSE, 16, + { "draft-ietf-ipsec-nat-t-ike-02\\n", EXT_NATT | EXT_NATT_DRAFT_02_03, + TRUE, 16, "\x90\xcb\x80\x91\x3e\xbb\x69\x6e\x08\x63\x81\xb5\xec\x42\x7b\x1f"}, - { "draft-ietf-ipsec-nat-t-ike-03", 0, FALSE, 16, - "\x7d\x94\x19\xa6\x53\x10\xca\x6f\x2c\x17\x9d\x92\x15\x52\x9d\x56"}, + { "draft-ietf-ipsec-nat-t-ike-08", 0, FALSE, 16, + "\x8f\x8d\x83\x82\x6d\x24\x6b\x6f\xc7\xa8\xa6\xa4\x28\xc1\x1d\xe8"}, - { "draft-ietf-ipsec-nat-t-ike-04", 0, FALSE, 16, - "\x99\x09\xb6\x4e\xed\x93\x7c\x65\x73\xde\x52\xac\xe9\x52\xfa\x6b"}, + { "draft-ietf-ipsec-nat-t-ike-07", 0, FALSE, 16, + "\x43\x9b\x59\xf8\xba\x67\x6c\x4c\x77\x37\xae\x22\xea\xb8\xf5\x82"}, + + { "draft-ietf-ipsec-nat-t-ike-06", 0, FALSE, 16, + "\x4d\x1e\x0e\x13\x6d\xea\xfa\x34\xc4\xf3\xea\x9f\x02\xec\x72\x85"}, { "draft-ietf-ipsec-nat-t-ike-05", 0, FALSE, 16, "\x80\xd0\xbb\x3d\xef\x54\x56\x5e\xe8\x46\x45\xd4\xc8\x5c\xe3\xee"}, - { "draft-ietf-ipsec-nat-t-ike-06", 0, FALSE, 16, - "\x4d\x1e\x0e\x13\x6d\xea\xfa\x34\xc4\xf3\xea\x9f\x02\xec\x72\x85"}, + { "draft-ietf-ipsec-nat-t-ike-04", 0, FALSE, 16, + "\x99\x09\xb6\x4e\xed\x93\x7c\x65\x73\xde\x52\xac\xe9\x52\xfa\x6b"}, - { "draft-ietf-ipsec-nat-t-ike-07", 0, FALSE, 16, - "\x43\x9b\x59\xf8\xba\x67\x6c\x4c\x77\x37\xae\x22\xea\xb8\xf5\x82"}, + { "draft-ietf-ipsec-nat-t-ike-00", 0, FALSE, 16, + "\x44\x85\x15\x2d\x18\xb6\xbb\xcd\x0b\xe8\xa8\x46\x95\x79\xdd\xcc"}, - { "draft-ietf-ipsec-nat-t-ike-08", 0, FALSE, 16, - "\x8f\x8d\x83\x82\x6d\x24\x6b\x6f\xc7\xa8\xa6\xa4\x28\xc1\x1d\xe8"}, + { "draft-ietf-ipsec-nat-t-ike", 0, FALSE, 16, + "\x4d\xf3\x79\x28\xe9\xfc\x4f\xd1\xb3\x26\x21\x70\xd5\x15\xc6\x62"}, - { "Cisco Unity", EXT_CISCO_UNITY, FALSE, 16, - "\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00"}, + { "draft-stenberg-ipsec-nat-traversal-02", 0, FALSE, 16, + "\x61\x05\xc4\x22\xe7\x68\x47\xe4\x3f\x96\x84\x80\x12\x92\xae\xcd"}, + + { "draft-stenberg-ipsec-nat-traversal-01", 0, FALSE, 16, + "\x27\xba\xb5\xdc\x01\xea\x07\x60\xea\x4e\x31\x90\xac\x27\xc0\xd0"}, }; METHOD(task_t, build, status_t, @@ -136,6 +170,17 @@ METHOD(task_t, build, status_t, message->add_payload(message, &vid_payload->payload_interface); } } + for (i = 0; i < countof(vendor_natt_ids); i++) + { + if (this->initiator && vendor_natt_ids[i].send || + this->best_natt_ext == i) + { + vid_payload = vendor_id_payload_create_data(VENDOR_ID_V1, + chunk_clone(chunk_create(vendor_natt_ids[i].id, + vendor_natt_ids[i].len))); + message->add_payload(message, &vid_payload->payload_interface); + } + } return this->initiator ? NEED_MORE : SUCCESS; } @@ -170,6 +215,26 @@ METHOD(task_t, process, status_t, vendor_ids[i].extension); } found = TRUE; + break; + } + } + if (!found) + { + for (i = 0; i < countof(vendor_natt_ids); i++) + { + if (chunk_equals(data, chunk_create(vendor_natt_ids[i].id, + vendor_natt_ids[i].len))) + { + DBG1(DBG_IKE, "received %s vendor ID", + vendor_natt_ids[i].desc); + if (vendor_natt_ids[i].extension && + (i < this->best_natt_ext || this->best_natt_ext < 0)) + { + this->best_natt_ext = i; + } + found = TRUE; + break; + } } } if (!found) @@ -180,6 +245,12 @@ METHOD(task_t, process, status_t, } enumerator->destroy(enumerator); + if (this->best_natt_ext >= 0) + { + this->ike_sa->enable_extension(this->ike_sa, + vendor_natt_ids[this->best_natt_ext].extension); + } + return this->initiator ? SUCCESS : NEED_MORE; } @@ -220,6 +291,7 @@ isakmp_vendor_t *isakmp_vendor_create(ike_sa_t *ike_sa, bool initiator) }, .initiator = initiator, .ike_sa = ike_sa, + .best_natt_ext = -1, ); return &this->public; diff --git a/src/libcharon/sa/ikev1/tasks/main_mode.c b/src/libcharon/sa/ikev1/tasks/main_mode.c index 9ccf9abf5..bc9d4bbc3 100644 --- a/src/libcharon/sa/ikev1/tasks/main_mode.c +++ b/src/libcharon/sa/ikev1/tasks/main_mode.c @@ -241,7 +241,8 @@ METHOD(task_t, build_i, status_t, this->lifetime += this->peer_cfg->get_over_time(this->peer_cfg); proposals = this->ike_cfg->get_proposals(this->ike_cfg); sa_payload = sa_payload_create_from_proposals_v1(proposals, - this->lifetime, 0, this->method, MODE_NONE, FALSE, 0); + this->lifetime, 0, this->method, MODE_NONE, + ENCAP_NONE, 0); proposals->destroy_offset(proposals, offsetof(proposal_t, destroy)); message->add_payload(message, &sa_payload->payload_interface); @@ -455,7 +456,8 @@ METHOD(task_t, build_r, status_t, sa_payload_t *sa_payload; sa_payload = sa_payload_create_from_proposal_v1(this->proposal, - this->lifetime, 0, this->method, MODE_NONE, FALSE, 0); + this->lifetime, 0, this->method, MODE_NONE, + ENCAP_NONE, 0); message->add_payload(message, &sa_payload->payload_interface); return NEED_MORE; diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index 86ddcc9d9..1eae6aa93 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -16,6 +16,28 @@ * for more details. */ +/* + * Copyright (C) 2012 Volker Rümelin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "quick_mode.h" #include <string.h> @@ -596,6 +618,34 @@ static bool get_ts(private_quick_mode_t *this, message_t *message) } /** + * Get encap + */ +static encap_t get_encap(ike_sa_t* ike_sa, bool udp) +{ + if (!udp) + { + return ENCAP_NONE; + } + if (ike_sa->supports_extension(ike_sa, EXT_NATT_DRAFT_02_03)) + { + return ENCAP_UDP_DRAFT_00_03; + } + return ENCAP_UDP; +} + +/** + * Get NAT-OA payload type (RFC 3947 or RFC 3947 drafts). + */ +static payload_type_t get_nat_oa_payload_type(ike_sa_t *ike_sa) +{ + if (ike_sa->supports_extension(ike_sa, EXT_NATT_DRAFT_02_03)) + { + return NAT_OA_DRAFT_00_03_V1; + } + return NAT_OA_V1; +} + +/** * Add NAT-OA payloads */ static void add_nat_oa_payloads(private_quick_mode_t *this, message_t *message) @@ -603,6 +653,7 @@ static void add_nat_oa_payloads(private_quick_mode_t *this, message_t *message) identification_t *id; id_payload_t *nat_oa; host_t *src, *dst; + payload_type_t nat_oa_payload_type; src = message->get_source(message); dst = message->get_destination(message); @@ -610,15 +661,17 @@ static void add_nat_oa_payloads(private_quick_mode_t *this, message_t *message) src = this->initiator ? src : dst; dst = this->initiator ? dst : src; + nat_oa_payload_type = get_nat_oa_payload_type(this->ike_sa); + /* first NAT-OA is the initiator's address */ id = identification_create_from_sockaddr(src->get_sockaddr(src)); - nat_oa = id_payload_create_from_identification(NAT_OA_V1, id); + nat_oa = id_payload_create_from_identification(nat_oa_payload_type, id); message->add_payload(message, (payload_t*)nat_oa); id->destroy(id); /* second NAT-OA is that of the responder */ id = identification_create_from_sockaddr(dst->get_sockaddr(dst)); - nat_oa = id_payload_create_from_identification(NAT_OA_V1, id); + nat_oa = id_payload_create_from_identification(nat_oa_payload_type, id); message->add_payload(message, (payload_t*)nat_oa); id->destroy(id); } @@ -697,6 +750,7 @@ METHOD(task_t, build_i, status_t, linked_list_t *list, *tsi, *tsr; proposal_t *proposal; diffie_hellman_group_t group; + encap_t encap; this->udp = this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY); this->mode = this->config->get_mode(this->config); @@ -767,9 +821,10 @@ METHOD(task_t, build_i, status_t, enumerator->destroy(enumerator); get_lifetimes(this); + encap = get_encap(this->ike_sa, this->udp); sa_payload = sa_payload_create_from_proposals_v1(list, this->lifetime, this->lifebytes, AUTH_NONE, - this->mode, this->udp, this->cpi_i); + this->mode, encap, this->cpi_i); list->destroy_offset(list, offsetof(proposal_t, destroy)); message->add_payload(message, &sa_payload->payload_interface); @@ -1060,6 +1115,7 @@ METHOD(task_t, build_r, status_t, case QM_INIT: { sa_payload_t *sa_payload; + encap_t encap; this->spi_r = this->child_sa->alloc_spi(this->child_sa, PROTO_ESP); if (!this->spi_r) @@ -1086,9 +1142,10 @@ METHOD(task_t, build_r, status_t, add_nat_oa_payloads(this, message); } + encap = get_encap(this->ike_sa, this->udp); sa_payload = sa_payload_create_from_proposal_v1(this->proposal, this->lifetime, this->lifebytes, AUTH_NONE, - this->mode, this->udp, this->cpi_r); + this->mode, encap, this->cpi_r); message->add_payload(message, &sa_payload->payload_interface); if (!add_nonce(this, &this->nonce_r, message)) |