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.
This commit is contained in:
Volker Rümelin 2012-12-15 14:11:26 +01:00 committed by Tobias Brunner
parent ecdd5aedac
commit 0ff8d20a89
14 changed files with 316 additions and 95 deletions

View File

@ -437,6 +437,7 @@ static payload_rule_t id_prot_i_rules[] = {
{VENDOR_ID_V1, 0, MAX_VID_PAYLOADS, FALSE, FALSE}, {VENDOR_ID_V1, 0, MAX_VID_PAYLOADS, FALSE, FALSE},
{CERTIFICATE_REQUEST_V1, 0, MAX_CERTREQ_PAYLOADS, FALSE, FALSE}, {CERTIFICATE_REQUEST_V1, 0, MAX_CERTREQ_PAYLOADS, FALSE, FALSE},
{NAT_D_V1, 0, MAX_NAT_D_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}, {ID_V1, 0, 1, TRUE, FALSE},
{CERTIFICATE_V1, 0, 2, TRUE, FALSE}, {CERTIFICATE_V1, 0, 2, TRUE, FALSE},
{SIGNATURE_V1, 0, 1, TRUE, FALSE}, {SIGNATURE_V1, 0, 1, TRUE, FALSE},
@ -459,6 +460,7 @@ static payload_order_t id_prot_i_order[] = {
{NOTIFY_V1, 0}, {NOTIFY_V1, 0},
{VENDOR_ID_V1, 0}, {VENDOR_ID_V1, 0},
{NAT_D_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}, {VENDOR_ID_V1, 0, MAX_VID_PAYLOADS, FALSE, FALSE},
{CERTIFICATE_REQUEST_V1, 0, MAX_CERTREQ_PAYLOADS, FALSE, FALSE}, {CERTIFICATE_REQUEST_V1, 0, MAX_CERTREQ_PAYLOADS, FALSE, FALSE},
{NAT_D_V1, 0, MAX_NAT_D_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}, {ID_V1, 0, 1, TRUE, FALSE},
{CERTIFICATE_V1, 0, 2, TRUE, FALSE}, {CERTIFICATE_V1, 0, 2, TRUE, FALSE},
{SIGNATURE_V1, 0, 1, TRUE, FALSE}, {SIGNATURE_V1, 0, 1, TRUE, FALSE},
@ -495,6 +498,7 @@ static payload_order_t id_prot_r_order[] = {
{NOTIFY_V1, 0}, {NOTIFY_V1, 0},
{VENDOR_ID_V1, 0}, {VENDOR_ID_V1, 0},
{NAT_D_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}, {VENDOR_ID_V1, 0, MAX_VID_PAYLOADS, FALSE, FALSE},
{CERTIFICATE_REQUEST_V1, 0, MAX_CERTREQ_PAYLOADS, FALSE, FALSE}, {CERTIFICATE_REQUEST_V1, 0, MAX_CERTREQ_PAYLOADS, FALSE, FALSE},
{NAT_D_V1, 0, MAX_NAT_D_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}, {ID_V1, 0, 1, FALSE, FALSE},
{CERTIFICATE_V1, 0, 1, TRUE, FALSE}, {CERTIFICATE_V1, 0, 1, TRUE, FALSE},
{SIGNATURE_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}, {ID_V1, 0},
{CERTIFICATE_V1, 0}, {CERTIFICATE_V1, 0},
{NAT_D_V1, 0}, {NAT_D_V1, 0},
{NAT_D_DRAFT_00_03_V1, 0},
{SIGNATURE_V1, 0}, {SIGNATURE_V1, 0},
{HASH_V1, 0}, {HASH_V1, 0},
{CERTIFICATE_REQUEST_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}, {VENDOR_ID_V1, 0, MAX_VID_PAYLOADS, FALSE, FALSE},
{CERTIFICATE_REQUEST_V1, 0, MAX_CERTREQ_PAYLOADS, FALSE, FALSE}, {CERTIFICATE_REQUEST_V1, 0, MAX_CERTREQ_PAYLOADS, FALSE, FALSE},
{NAT_D_V1, 0, MAX_NAT_D_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}, {ID_V1, 0, 1, FALSE, FALSE},
{CERTIFICATE_V1, 0, 1, FALSE, FALSE}, {CERTIFICATE_V1, 0, 1, FALSE, FALSE},
{SIGNATURE_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}, {ID_V1, 0},
{CERTIFICATE_V1, 0}, {CERTIFICATE_V1, 0},
{NAT_D_V1, 0}, {NAT_D_V1, 0},
{NAT_D_DRAFT_00_03_V1, 0},
{SIGNATURE_V1, 0}, {SIGNATURE_V1, 0},
{HASH_V1, 0}, {HASH_V1, 0},
{CERTIFICATE_REQUEST_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}, {KEY_EXCHANGE_V1, 0, 1, TRUE, FALSE},
{ID_V1, 0, 2, TRUE, FALSE}, {ID_V1, 0, 2, TRUE, FALSE},
{NAT_OA_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}, {KEY_EXCHANGE_V1, 0},
{ID_V1, 0}, {ID_V1, 0},
{NAT_OA_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}, {KEY_EXCHANGE_V1, 0, 1, TRUE, FALSE},
{ID_V1, 0, 2, TRUE, FALSE}, {ID_V1, 0, 2, TRUE, FALSE},
{NAT_OA_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}, {KEY_EXCHANGE_V1, 0},
{ID_V1, 0}, {ID_V1, 0},
{NAT_OA_V1, 0}, {NAT_OA_V1, 0},
{NAT_OA_DRAFT_00_03_V1, 0},
}; };
/** /**

View File

@ -165,7 +165,7 @@ METHOD(payload_t, verify, status_t,
{ {
bool bad_length = FALSE; 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) 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, 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, METHOD(payload_t, get_encoding_rules, int,
private_id_payload_t *this, encoding_rule_t **rules) 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; *rules = encodings_v1;
return countof(encodings_v1); return countof(encodings_v1);

View File

@ -79,20 +79,15 @@ ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION, GENERIC_SECURE_PASSWORD_METH
#ifdef ME #ifdef ME
ENUM_NEXT(payload_type_names, ID_PEER, ID_PEER, GENERIC_SECURE_PASSWORD_METHOD, ENUM_NEXT(payload_type_names, ID_PEER, ID_PEER, GENERIC_SECURE_PASSWORD_METHOD,
"ID_PEER"); "ID_PEER");
ENUM_NEXT(payload_type_names, HEADER, ENCRYPTED_V1, ID_PEER, ENUM_NEXT(payload_type_names, NAT_D_DRAFT_00_03_V1, NAT_OA_DRAFT_00_03_V1, ID_PEER,
"HEADER", "NAT_D_DRAFT_V1",
"PROPOSAL_SUBSTRUCTURE", "NAT_OA_DRAFT_V1");
"PROPOSAL_SUBSTRUCTURE_V1",
"TRANSFORM_SUBSTRUCTURE",
"TRANSFORM_SUBSTRUCTURE_V1",
"TRANSFORM_ATTRIBUTE",
"TRANSFORM_ATTRIBUTE_V1",
"TRAFFIC_SELECTOR_SUBSTRUCTURE",
"CONFIGURATION_ATTRIBUTE",
"CONFIGURATION_ATTRIBUTE_V1",
"ENCRYPTED_V1");
#else #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", "HEADER",
"PROPOSAL_SUBSTRUCTURE", "PROPOSAL_SUBSTRUCTURE",
"PROPOSAL_SUBSTRUCTURE_V1", "PROPOSAL_SUBSTRUCTURE_V1",
@ -104,7 +99,6 @@ ENUM_NEXT(payload_type_names, HEADER, ENCRYPTED_V1, GENERIC_SECURE_PASSWORD_METH
"CONFIGURATION_ATTRIBUTE", "CONFIGURATION_ATTRIBUTE",
"CONFIGURATION_ATTRIBUTE_V1", "CONFIGURATION_ATTRIBUTE_V1",
"ENCRYPTED_V1"); "ENCRYPTED_V1");
#endif /* ME */
ENUM_END(payload_type_names, ENCRYPTED_V1); ENUM_END(payload_type_names, ENCRYPTED_V1);
/* short forms of payload names */ /* short forms of payload names */
@ -147,23 +141,17 @@ ENUM_NEXT(payload_type_short_names, SECURITY_ASSOCIATION, GENERIC_SECURE_PASSWOR
"EAP", "EAP",
"GSPM"); "GSPM");
#ifdef ME #ifdef ME
ENUM_NEXT(payload_type_short_names, ID_PEER, ID_PEER, ENUM_NEXT(payload_type_short_names, ID_PEER, ID_PEER, GENERIC_SECURE_PASSWORD_METHOD,
GENERIC_SECURE_PASSWORD_METHOD,
"IDp"); "IDp");
ENUM_NEXT(payload_type_short_names, HEADER, ENCRYPTED_V1, ID_PEER, ENUM_NEXT(payload_type_short_names, NAT_D_DRAFT_00_03_V1, NAT_OA_DRAFT_00_03_V1, ID_PEER,
"HDR", "NAT-D",
"PROP", "NAT-OA");
"PROP",
"TRANS",
"TRANS",
"TRANSATTR",
"TRANSATTR",
"TSSUB",
"CATTR",
"CATTR",
"E");
#else #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", "HDR",
"PROP", "PROP",
"PROP", "PROP",
@ -175,7 +163,6 @@ ENUM_NEXT(payload_type_short_names, HEADER, ENCRYPTED_V1, GENERIC_SECURE_PASSWOR
"CATTR", "CATTR",
"CATTR", "CATTR",
"E"); "E");
#endif /* ME */
ENUM_END(payload_type_short_names, ENCRYPTED_V1); 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_RESPONDER:
case ID_V1: case ID_V1:
case NAT_OA_V1: case NAT_OA_V1:
case NAT_OA_DRAFT_00_03_V1:
#ifdef ME #ifdef ME
case ID_PEER: case ID_PEER:
#endif /* ME */ #endif /* ME */
@ -239,6 +227,7 @@ payload_t *payload_create(payload_type_t type)
case HASH_V1: case HASH_V1:
case SIGNATURE_V1: case SIGNATURE_V1:
case NAT_D_V1: case NAT_D_V1:
case NAT_D_DRAFT_00_03_V1:
return (payload_t*)hash_payload_create(type); return (payload_t*)hash_payload_create(type);
case CONFIGURATION: case CONFIGURATION:
case CONFIGURATION_V1: case CONFIGURATION_V1:
@ -283,6 +272,10 @@ bool payload_is_known(payload_type_t type)
return TRUE; return TRUE;
} }
#endif #endif
if (type >= NAT_D_DRAFT_00_03_V1 && type <= NAT_OA_DRAFT_00_03_V1)
{
return TRUE;
}
return FALSE; return FALSE;
} }

View File

@ -123,7 +123,7 @@ enum payload_type_t {
NAT_D_V1 = 20, NAT_D_V1 = 20,
/** /**
* NAT original address payload (NAT-OA) * NAT original address payload (NAT-OA).
*/ */
NAT_OA_V1 = 21, NAT_OA_V1 = 21,
@ -220,6 +220,16 @@ enum payload_type_t {
ID_PEER = 128, ID_PEER = 128,
#endif /* ME */ #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. * Header has a value of PRIVATE USE space.
* *

View File

@ -253,6 +253,8 @@ typedef enum {
IKEV1_ENCAP_TRANSPORT = 2, IKEV1_ENCAP_TRANSPORT = 2,
IKEV1_ENCAP_UDP_TUNNEL = 3, IKEV1_ENCAP_UDP_TUNNEL = 3,
IKEV1_ENCAP_UDP_TRANSPORT = 4, 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; } ikev1_esp_encap_t;
/** /**
@ -810,14 +812,30 @@ static u_int16_t get_ikev1_auth(auth_method_t method)
/** /**
* Get IKEv1 encapsulation mode * 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) switch (mode)
{ {
case MODE_TUNNEL: 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: 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: default:
return IKEV1_ENCAP_TUNNEL; return IKEV1_ENCAP_TUNNEL;
} }
@ -1125,9 +1143,11 @@ METHOD(proposal_substructure_t, get_encap_mode, ipsec_mode_t,
case IKEV1_ENCAP_TUNNEL: case IKEV1_ENCAP_TUNNEL:
return MODE_TUNNEL; return MODE_TUNNEL;
case IKEV1_ENCAP_UDP_TRANSPORT: case IKEV1_ENCAP_UDP_TRANSPORT:
case IKEV1_ENCAP_UDP_TRANSPORT_DRAFT_00_03:
*udp = TRUE; *udp = TRUE;
return MODE_TRANSPORT; return MODE_TRANSPORT;
case IKEV1_ENCAP_UDP_TUNNEL: case IKEV1_ENCAP_UDP_TUNNEL:
case IKEV1_ENCAP_UDP_TUNNEL_DRAFT_00_03:
*udp = TRUE; *udp = TRUE;
return MODE_TUNNEL; return MODE_TUNNEL;
default: 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, static void set_from_proposal_v1_esp(private_proposal_substructure_t *this,
proposal_t *proposal, u_int32_t lifetime, u_int64_t lifebytes, 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; transform_substructure_t *transform = NULL;
u_int16_t alg, key_size; 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_substructure_t *proposal_substructure_create_from_proposal_v1(
proposal_t *proposal, u_int32_t lifetime, u_int64_t lifebytes, 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; 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( proposal_substructure_t *proposal_substructure_create_from_proposals_v1(
linked_list_t *proposals, u_int32_t lifetime, u_int64_t lifebytes, 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; private_proposal_substructure_t *this = NULL;
enumerator_t *enumerator; 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( proposal_substructure_t *proposal_substructure_create_for_ipcomp_v1(
u_int32_t lifetime, u_int64_t lifebytes, u_int16_t cpi, 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; private_proposal_substructure_t *this;
transform_substructure_t *transform; transform_substructure_t *transform;

View File

@ -23,6 +23,7 @@
#ifndef PROPOSAL_SUBSTRUCTURE_H_ #ifndef PROPOSAL_SUBSTRUCTURE_H_
#define PROPOSAL_SUBSTRUCTURE_H_ #define PROPOSAL_SUBSTRUCTURE_H_
typedef enum encap_t encap_t;
typedef struct proposal_substructure_t proposal_substructure_t; typedef struct proposal_substructure_t proposal_substructure_t;
#include <library.h> #include <library.h>
@ -33,6 +34,15 @@ typedef struct proposal_substructure_t proposal_substructure_t;
#include <kernel/kernel_ipsec.h> #include <kernel/kernel_ipsec.h>
#include <sa/authenticator.h> #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. * Class representing an IKEv1/IKEv2 proposal substructure.
*/ */
@ -179,12 +189,12 @@ proposal_substructure_t *proposal_substructure_create_from_proposal_v2(
* @param lifebytes lifebytes, in bytes * @param lifebytes lifebytes, in bytes
* @param auth authentication method to use, or AUTH_NONE * @param auth authentication method to use, or AUTH_NONE
* @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL * @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 * @return proposal_substructure_t object PROPOSAL_SUBSTRUCTURE_V1
*/ */
proposal_substructure_t *proposal_substructure_create_from_proposal_v1( proposal_substructure_t *proposal_substructure_create_from_proposal_v1(
proposal_t *proposal, u_int32_t lifetime, u_int64_t lifebytes, 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. * 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 lifebytes lifebytes, in bytes
* @param auth authentication method to use, or AUTH_NONE * @param auth authentication method to use, or AUTH_NONE
* @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL * @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 * @return IKEv1 proposal_substructure_t PROPOSAL_SUBSTRUCTURE_V1
*/ */
proposal_substructure_t *proposal_substructure_create_from_proposals_v1( proposal_substructure_t *proposal_substructure_create_from_proposals_v1(
linked_list_t *proposals, u_int32_t lifetime, u_int64_t lifebytes, 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 * 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 lifebytes lifebytes, in bytes
* @param cpi the CPI to be used * @param cpi the CPI to be used
* @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL * @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 * @param proposal_number the proposal number of the proposal to be linked
* @return IKEv1 proposal_substructure_t PROPOSAL_SUBSTRUCTURE_V1 * @return IKEv1 proposal_substructure_t PROPOSAL_SUBSTRUCTURE_V1
*/ */
proposal_substructure_t *proposal_substructure_create_for_ipcomp_v1( proposal_substructure_t *proposal_substructure_create_for_ipcomp_v1(
u_int32_t lifetime, u_int64_t lifebytes, u_int16_t cpi, 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_ @}*/ #endif /** PROPOSAL_SUBSTRUCTURE_H_ @}*/

View File

@ -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, sa_payload_t *sa_payload_create_from_proposals_v1(linked_list_t *proposals,
u_int32_t lifetime, u_int64_t lifebytes, 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,
u_int16_t cpi) encap_t udp, u_int16_t cpi)
{ {
proposal_substructure_t *substruct; proposal_substructure_t *substruct;
private_sa_payload_t *this; 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, sa_payload_t *sa_payload_create_from_proposal_v1(proposal_t *proposal,
u_int32_t lifetime, u_int64_t lifebytes, 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,
u_int16_t cpi) encap_t udp, u_int16_t cpi)
{ {
private_sa_payload_t *this; private_sa_payload_t *this;
linked_list_t *proposals; linked_list_t *proposals;

View File

@ -133,13 +133,13 @@ sa_payload_t *sa_payload_create_from_proposal_v2(proposal_t *proposal);
* @param lifebytes lifebytes, in bytes * @param lifebytes lifebytes, in bytes
* @param auth authentication method to use, or AUTH_NONE * @param auth authentication method to use, or AUTH_NONE
* @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL * @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 * @param cpi CPI in case IPComp should be used
* @return sa_payload_t object * @return sa_payload_t object
*/ */
sa_payload_t *sa_payload_create_from_proposals_v1(linked_list_t *proposals, sa_payload_t *sa_payload_create_from_proposals_v1(linked_list_t *proposals,
u_int32_t lifetime, u_int64_t lifebytes, 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); 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 lifebytes lifebytes, in bytes
* @param auth authentication method to use, or AUTH_NONE * @param auth authentication method to use, or AUTH_NONE
* @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL * @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 * @param cpi CPI in case IPComp should be used
* @return sa_payload_t object * @return sa_payload_t object
*/ */
sa_payload_t *sa_payload_create_from_proposal_v1(proposal_t *proposal, sa_payload_t *sa_payload_create_from_proposal_v1(proposal_t *proposal,
u_int32_t lifetime, u_int64_t lifebytes, 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); u_int16_t cpi);
#endif /** SA_PAYLOAD_H_ @}*/ #endif /** SA_PAYLOAD_H_ @}*/

View File

@ -72,6 +72,7 @@ enum ike_extension_t {
/** /**
* peer supports NAT traversal as specified in RFC4306 or RFC3947 * peer supports NAT traversal as specified in RFC4306 or RFC3947
* including some RFC3947 drafts
*/ */
EXT_NATT = (1<<0), EXT_NATT = (1<<0),
@ -119,6 +120,12 @@ enum ike_extension_t {
* peer supports Cisco Unity configuration attributes * peer supports Cisco Unity configuration attributes
*/ */
EXT_CISCO_UNITY = (1<<9), 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),
}; };
/** /**

View File

@ -235,7 +235,8 @@ METHOD(task_t, build_i, status_t,
this->lifetime += this->peer_cfg->get_over_time(this->peer_cfg); this->lifetime += this->peer_cfg->get_over_time(this->peer_cfg);
proposals = this->ike_cfg->get_proposals(this->ike_cfg); proposals = this->ike_cfg->get_proposals(this->ike_cfg);
sa_payload = sa_payload_create_from_proposals_v1(proposals, 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)); proposals->destroy_offset(proposals, offsetof(proposal_t, destroy));
message->add_payload(message, &sa_payload->payload_interface); message->add_payload(message, &sa_payload->payload_interface);
@ -520,7 +521,8 @@ METHOD(task_t, build_r, status_t,
identification_t *id; identification_t *id;
sa_payload = sa_payload_create_from_proposal_v1(this->proposal, 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); message->add_payload(message, &sa_payload->payload_interface);
if (!this->ph1->add_nonce_ke(this->ph1, message)) if (!this->ph1->add_nonce_ke(this->ph1, message))

View File

@ -15,6 +15,28 @@
* for more details. * 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 "isakmp_natd.h"
#include <string.h> #include <string.h>
@ -74,6 +96,18 @@ struct private_isakmp_natd_t {
bool dst_matched; bool dst_matched;
}; };
/**
* 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. * Build NAT detection hash for a host.
*/ */
@ -162,7 +196,7 @@ static hash_payload_t *build_natd_payload(private_isakmp_natd_t *this, bool src,
{ {
return NULL; 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); payload->set_hash(payload, hash);
chunk_free(&hash); chunk_free(&hash);
return payload; return payload;
@ -221,7 +255,8 @@ static void process_payloads(private_isakmp_natd_t *this, message_t *message)
enumerator = message->create_payload_enumerator(message); enumerator = message->create_payload_enumerator(message);
while (enumerator->enumerate(enumerator, &payload)) 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; continue;
} }

View File

@ -13,6 +13,28 @@
* for more details. * 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 "isakmp_vendor.h"
#include <daemon.h> #include <daemon.h>
@ -39,6 +61,11 @@ struct private_isakmp_vendor_t {
* Are we the inititator of this task * Are we the inititator of this task
*/ */
bool initiator; bool initiator;
/**
* Index of best nat traversal VID found
*/
int best_natt_ext;
}; };
/** /**
@ -65,52 +92,59 @@ static struct {
{ "XAuth", EXT_XAUTH, TRUE, 8, { "XAuth", EXT_XAUTH, TRUE, 8,
"\x09\x00\x26\x89\xdf\xd6\xb7\x12"}, "\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 */ /* Dead peer detection, RFC 3706 */
{ "DPD", EXT_DPD, TRUE, 16, { "DPD", EXT_DPD, TRUE, 16,
"\xaf\xca\xd7\x13\x68\xa1\xf1\xc9\x6b\x86\x96\xfc\x77\x57\x01\x00"}, "\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, { "Cisco Unity", EXT_CISCO_UNITY, FALSE, 16,
"\x27\xba\xb5\xdc\x01\xea\x07\x60\xea\x4e\x31\x90\xac\x27\xc0\xd0"}, "\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, }, vendor_natt_ids[] = {
"\x61\x05\xc4\x22\xe7\x68\x47\xe4\x3f\x96\x84\x80\x12\x92\xae\xcd"},
{ "draft-ietf-ipsec-nat-t-ike", 0, FALSE, 16, /* NAT-Traversal VIDs ordered by preference */
"\x4d\xf3\x79\x28\xe9\xfc\x4f\xd1\xb3\x26\x21\x70\xd5\x15\xc6\x62"},
{ "draft-ietf-ipsec-nat-t-ike-00", 0, FALSE, 16, /* NAT-Traversal, MD5("RFC 3947") */
"\x44\x85\x15\x2d\x18\xb6\xbb\xcd\x0b\xe8\xa8\x46\x95\x79\xdd\xcc"}, { "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-02", 0, FALSE, 16, { "draft-ietf-ipsec-nat-t-ike-03", EXT_NATT | EXT_NATT_DRAFT_02_03,
"\xcd\x60\x46\x43\x35\xdf\x21\xf8\x7c\xfd\xb2\xfc\x68\xb6\xa4\x48"}, FALSE, 16,
{ "draft-ietf-ipsec-nat-t-ike-02\\n", 0, FALSE, 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"}, "\x7d\x94\x19\xa6\x53\x10\xca\x6f\x2c\x17\x9d\x92\x15\x52\x9d\x56"},
{ "draft-ietf-ipsec-nat-t-ike-04", 0, FALSE, 16, { "draft-ietf-ipsec-nat-t-ike-02", EXT_NATT | EXT_NATT_DRAFT_02_03,
"\x99\x09\xb6\x4e\xed\x93\x7c\x65\x73\xde\x52\xac\xe9\x52\xfa\x6b"}, FALSE, 16,
"\xcd\x60\x46\x43\x35\xdf\x21\xf8\x7c\xfd\xb2\xfc\x68\xb6\xa4\x48"},
{ "draft-ietf-ipsec-nat-t-ike-05", 0, FALSE, 16, { "draft-ietf-ipsec-nat-t-ike-02\\n", EXT_NATT | EXT_NATT_DRAFT_02_03,
"\x80\xd0\xbb\x3d\xef\x54\x56\x5e\xe8\x46\x45\xd4\xc8\x5c\xe3\xee"}, TRUE, 16,
"\x90\xcb\x80\x91\x3e\xbb\x69\x6e\x08\x63\x81\xb5\xec\x42\x7b\x1f"},
{ "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-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-08", 0, FALSE, 16, { "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"}, "\x8f\x8d\x83\x82\x6d\x24\x6b\x6f\xc7\xa8\xa6\xa4\x28\xc1\x1d\xe8"},
{ "Cisco Unity", EXT_CISCO_UNITY, FALSE, 16, { "draft-ietf-ipsec-nat-t-ike-07", 0, FALSE, 16,
"\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00"}, "\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-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-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", 0, FALSE, 16,
"\x4d\xf3\x79\x28\xe9\xfc\x4f\xd1\xb3\x26\x21\x70\xd5\x15\xc6\x62"},
{ "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, METHOD(task_t, build, status_t,
@ -136,6 +170,17 @@ METHOD(task_t, build, status_t,
message->add_payload(message, &vid_payload->payload_interface); 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; return this->initiator ? NEED_MORE : SUCCESS;
} }
@ -170,6 +215,26 @@ METHOD(task_t, process, status_t,
vendor_ids[i].extension); vendor_ids[i].extension);
} }
found = TRUE; 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) if (!found)
@ -180,6 +245,12 @@ METHOD(task_t, process, status_t,
} }
enumerator->destroy(enumerator); 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; 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, .initiator = initiator,
.ike_sa = ike_sa, .ike_sa = ike_sa,
.best_natt_ext = -1,
); );
return &this->public; return &this->public;

View File

@ -241,7 +241,8 @@ METHOD(task_t, build_i, status_t,
this->lifetime += this->peer_cfg->get_over_time(this->peer_cfg); this->lifetime += this->peer_cfg->get_over_time(this->peer_cfg);
proposals = this->ike_cfg->get_proposals(this->ike_cfg); proposals = this->ike_cfg->get_proposals(this->ike_cfg);
sa_payload = sa_payload_create_from_proposals_v1(proposals, 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)); proposals->destroy_offset(proposals, offsetof(proposal_t, destroy));
message->add_payload(message, &sa_payload->payload_interface); 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_t *sa_payload;
sa_payload = sa_payload_create_from_proposal_v1(this->proposal, 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); message->add_payload(message, &sa_payload->payload_interface);
return NEED_MORE; return NEED_MORE;

View File

@ -16,6 +16,28 @@
* for more details. * 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 "quick_mode.h"
#include <string.h> #include <string.h>
@ -595,6 +617,34 @@ static bool get_ts(private_quick_mode_t *this, message_t *message)
return TRUE; return TRUE;
} }
/**
* 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 * Add NAT-OA payloads
*/ */
@ -603,6 +653,7 @@ static void add_nat_oa_payloads(private_quick_mode_t *this, message_t *message)
identification_t *id; identification_t *id;
id_payload_t *nat_oa; id_payload_t *nat_oa;
host_t *src, *dst; host_t *src, *dst;
payload_type_t nat_oa_payload_type;
src = message->get_source(message); src = message->get_source(message);
dst = message->get_destination(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; src = this->initiator ? src : dst;
dst = this->initiator ? dst : src; 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 */ /* first NAT-OA is the initiator's address */
id = identification_create_from_sockaddr(src->get_sockaddr(src)); 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); message->add_payload(message, (payload_t*)nat_oa);
id->destroy(id); id->destroy(id);
/* second NAT-OA is that of the responder */ /* second NAT-OA is that of the responder */
id = identification_create_from_sockaddr(dst->get_sockaddr(dst)); 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); message->add_payload(message, (payload_t*)nat_oa);
id->destroy(id); id->destroy(id);
} }
@ -697,6 +750,7 @@ METHOD(task_t, build_i, status_t,
linked_list_t *list, *tsi, *tsr; linked_list_t *list, *tsi, *tsr;
proposal_t *proposal; proposal_t *proposal;
diffie_hellman_group_t group; diffie_hellman_group_t group;
encap_t encap;
this->udp = this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY); this->udp = this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY);
this->mode = this->config->get_mode(this->config); this->mode = this->config->get_mode(this->config);
@ -767,9 +821,10 @@ METHOD(task_t, build_i, status_t,
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
get_lifetimes(this); get_lifetimes(this);
encap = get_encap(this->ike_sa, this->udp);
sa_payload = sa_payload_create_from_proposals_v1(list, sa_payload = sa_payload_create_from_proposals_v1(list,
this->lifetime, this->lifebytes, AUTH_NONE, 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)); list->destroy_offset(list, offsetof(proposal_t, destroy));
message->add_payload(message, &sa_payload->payload_interface); message->add_payload(message, &sa_payload->payload_interface);
@ -1060,6 +1115,7 @@ METHOD(task_t, build_r, status_t,
case QM_INIT: case QM_INIT:
{ {
sa_payload_t *sa_payload; sa_payload_t *sa_payload;
encap_t encap;
this->spi_r = this->child_sa->alloc_spi(this->child_sa, PROTO_ESP); this->spi_r = this->child_sa->alloc_spi(this->child_sa, PROTO_ESP);
if (!this->spi_r) if (!this->spi_r)
@ -1086,9 +1142,10 @@ METHOD(task_t, build_r, status_t,
add_nat_oa_payloads(this, message); add_nat_oa_payloads(this, message);
} }
encap = get_encap(this->ike_sa, this->udp);
sa_payload = sa_payload_create_from_proposal_v1(this->proposal, sa_payload = sa_payload_create_from_proposal_v1(this->proposal,
this->lifetime, this->lifebytes, AUTH_NONE, 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); message->add_payload(message, &sa_payload->payload_interface);
if (!add_nonce(this, &this->nonce_r, message)) if (!add_nonce(this, &this->nonce_r, message))