Use a connection specific option to en-/disable IKEv1 fragmentation

This commit is contained in:
Tobias Brunner
2012-12-24 13:00:01 +01:00
parent e645c15b9c
commit 97973f8609
25 changed files with 69 additions and 33 deletions
+10
View File
@@ -403,6 +403,16 @@ force UDP encapsulation for ESP packets even if no NAT situation is detected.
This may help to surmount restrictive firewalls. In order to force the peer to
encapsulate packets, NAT detection payloads are faked.
.TP
.BR fragmentation " = yes | " no
whether to use IKE fragmentation (proprietary IKEv1 extension). Acceptable
values are
.B yes
and
.B no
(the default). Fragmented messages sent by a peer are always accepted
irrespective of the value of this option. If enabled, and the peer supports it,
larger IKE messages will be sent in fragments.
.TP
.BR ike " = <cipher suites>"
comma-separated list of IKE/ISAKMP SA encryption/authentication algorithms
to be used, e.g.
-5
View File
@@ -178,11 +178,6 @@ openly transmitted hash of the PSK)
.BR charon.ignore_routing_tables
A space-separated list of routing tables to be excluded from route lookups
.TP
.BR charon.ike_fragmentation " [no]"
Enables IKE fragmentation (proprietary IKEv1 extension). Fragmented messages
are always accepted irrespective of the value of this option. If the peer
supports it larger messages will be sent in fragments.
.TP
.BR charon.ikesa_table_segments " [1]"
Number of exclusively locked segments in the hash table
.TP
+1 -1
View File
@@ -500,7 +500,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
*/
ike_cfg = ike_cfg_create(IKEV2, TRUE, encap, "0.0.0.0", FALSE,
charon->socket->get_port(charon->socket, FALSE),
(char*)address, FALSE, IKEV2_UDP_PORT);
(char*)address, FALSE, IKEV2_UDP_PORT, FALSE);
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
peer_cfg = peer_cfg_create(priv->name, ike_cfg,
CERT_SEND_IF_ASKED, UNIQUE_REPLACE, 1, /* keyingtries */
+1 -1
View File
@@ -106,7 +106,7 @@ static ike_cfg_t *load_ike_config(private_config_t *this,
settings->get_str(settings, "configs.%s.lhost", "%any", config), FALSE,
settings->get_int(settings, "configs.%s.lport", 500, config),
settings->get_str(settings, "configs.%s.rhost", "%any", config), FALSE,
settings->get_int(settings, "configs.%s.rport", 500, config));
settings->get_int(settings, "configs.%s.rport", 500, config), FALSE);
token = settings->get_str(settings, "configs.%s.proposal", NULL, config);
if (token)
{
@@ -471,7 +471,7 @@ static job_requeue_t initiate(private_android_service_t *this)
ike_cfg = ike_cfg_create(IKEV2, TRUE, TRUE, "0.0.0.0", FALSE,
charon->socket->get_port(charon->socket, FALSE),
this->gateway, FALSE, IKEV2_UDP_PORT);
this->gateway, FALSE, IKEV2_UDP_PORT, FALSE);
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
peer_cfg = peer_cfg_create("android", ike_cfg, CERT_SEND_IF_ASKED,
+16 -1
View File
@@ -89,6 +89,11 @@ struct private_ike_cfg_t {
*/
bool force_encap;
/**
* use IKEv1 fragmentation
*/
bool fragmentation;
/**
* List of proposals to use
*/
@@ -113,6 +118,12 @@ METHOD(ike_cfg_t, force_encap_, bool,
return this->force_encap;
}
METHOD(ike_cfg_t, fragmentation, bool,
private_ike_cfg_t *this)
{
return this->fragmentation;
}
METHOD(ike_cfg_t, get_my_addr, char*,
private_ike_cfg_t *this, bool *allow_any)
{
@@ -268,6 +279,7 @@ METHOD(ike_cfg_t, equals, bool,
this->version == other->version &&
this->certreq == other->certreq &&
this->force_encap == other->force_encap &&
this->fragmentation == other->fragmentation &&
streq(this->me, other->me) &&
streq(this->other, other->other) &&
this->my_port == other->my_port &&
@@ -299,7 +311,8 @@ METHOD(ike_cfg_t, destroy, void,
*/
ike_cfg_t *ike_cfg_create(ike_version_t version, bool certreq, bool force_encap,
char *me, bool my_allow_any, u_int16_t my_port,
char *other, bool other_allow_any, u_int16_t other_port)
char *other, bool other_allow_any, u_int16_t other_port,
bool fragmentation)
{
private_ike_cfg_t *this;
@@ -308,6 +321,7 @@ ike_cfg_t *ike_cfg_create(ike_version_t version, bool certreq, bool force_encap,
.get_version = _get_version,
.send_certreq = _send_certreq,
.force_encap = _force_encap_,
.fragmentation = _fragmentation,
.get_my_addr = _get_my_addr,
.get_other_addr = _get_other_addr,
.get_my_port = _get_my_port,
@@ -324,6 +338,7 @@ ike_cfg_t *ike_cfg_create(ike_version_t version, bool certreq, bool force_encap,
.version = version,
.certreq = certreq,
.force_encap = force_encap,
.fragmentation = fragmentation,
.me = strdup(me),
.other = strdup(other),
.my_allow_any = my_allow_any,
+11 -2
View File
@@ -134,10 +134,17 @@ struct ike_cfg_t {
/**
* Enforce UDP encapsulation by faking NATD notifies?
*
* @return TRUE to enfoce UDP encapsulation
* @return TRUE to enforce UDP encapsulation
*/
bool (*force_encap) (ike_cfg_t *this);
/**
* Use proprietary IKEv1 fragmentation
*
* @return TRUE to use fragmentation
*/
bool (*fragmentation) (ike_cfg_t *this);
/**
* Get the DH group to use for IKE_SA setup.
*
@@ -183,10 +190,12 @@ struct ike_cfg_t {
* @param other address/DNS name of remote peer
* @param other_allow_any allow override of remote address by any address
* @param other_port IKE port to use as dest, 500 uses IKEv2 port floating
* @param fragmentation use IKEv1 fragmentation
* @return ike_cfg_t object.
*/
ike_cfg_t *ike_cfg_create(ike_version_t version, bool certreq, bool force_encap,
char *me, bool my_allow_any, u_int16_t my_port,
char *other, bool other_allow_any, u_int16_t other_port);
char *other, bool other_allow_any, u_int16_t other_port,
bool fragmentation);
#endif /** IKE_CFG_H_ @}*/
@@ -266,7 +266,7 @@ static job_requeue_t initiate(private_android_service_t *this)
ike_cfg = ike_cfg_create(IKEV2, TRUE, FALSE, "0.0.0.0", FALSE,
charon->socket->get_port(charon->socket, FALSE),
hostname, FALSE, IKEV2_UDP_PORT);
hostname, FALSE, IKEV2_UDP_PORT, FALSE);
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
peer_cfg = peer_cfg_create("android", ike_cfg, CERT_SEND_IF_ASKED,
+1 -1
View File
@@ -205,7 +205,7 @@ static void setup_tunnel(private_ha_tunnel_t *this,
/* create config and backend */
ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, local, FALSE,
charon->socket->get_port(charon->socket, FALSE),
remote, FALSE, IKEV2_UDP_PORT);
remote, FALSE, IKEV2_UDP_PORT, FALSE);
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
peer_cfg = peer_cfg_create("ha", ike_cfg, CERT_NEVER_SEND,
UNIQUE_KEEP, 0, 86400, 0, 7200, 3600, FALSE, FALSE, 30,
@@ -490,14 +490,14 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
{
ike_cfg = ike_cfg_create(this->version, TRUE, FALSE,
local, FALSE, this->port + num - 1,
remote, FALSE, IKEV2_NATT_PORT);
remote, FALSE, IKEV2_NATT_PORT, FALSE);
}
else
{
ike_cfg = ike_cfg_create(this->version, TRUE, FALSE,
local, FALSE,
charon->socket->get_port(charon->socket, FALSE),
remote, FALSE, IKEV2_UDP_PORT);
remote, FALSE, IKEV2_UDP_PORT, FALSE);
}
ike_cfg->add_proposal(ike_cfg, this->proposal->clone(this->proposal));
peer_cfg = peer_cfg_create("load-test", ike_cfg,
+1 -1
View File
@@ -325,7 +325,7 @@ static gboolean initiate_connection(private_maemo_service_t *this,
ike_cfg = ike_cfg_create(IKEV2, TRUE, FALSE, "0.0.0.0", FALSE,
charon->socket->get_port(charon->socket, FALSE),
hostname, FALSE, IKEV2_UDP_PORT);
hostname, FALSE, IKEV2_UDP_PORT, FALSE);
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
peer_cfg = peer_cfg_create(this->current, ike_cfg,
+2 -2
View File
@@ -105,7 +105,7 @@ METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE,
"0.0.0.0", FALSE,
charon->socket->get_port(charon->socket, FALSE),
address, FALSE, IKEV2_UDP_PORT);
address, FALSE, IKEV2_UDP_PORT, FALSE);
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
med_cfg = peer_cfg_create(
"mediation", ike_cfg,
@@ -380,7 +380,7 @@ medcli_config_t *medcli_config_create(database_t *db)
.ike = ike_cfg_create(IKEV2, FALSE, FALSE,
"0.0.0.0", FALSE,
charon->socket->get_port(charon->socket, FALSE),
"0.0.0.0", FALSE, IKEV2_UDP_PORT),
"0.0.0.0", FALSE, IKEV2_UDP_PORT, FALSE),
);
this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
+1 -1
View File
@@ -142,7 +142,7 @@ medsrv_config_t *medsrv_config_create(database_t *db)
.ike = ike_cfg_create(IKEV2, FALSE, FALSE,
"0.0.0.0", FALSE,
charon->socket->get_port(charon->socket, FALSE),
"0.0.0.0", FALSE, IKEV2_UDP_PORT),
"0.0.0.0", FALSE, IKEV2_UDP_PORT, FALSE),
);
this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
+1 -1
View File
@@ -261,7 +261,7 @@ static ike_cfg_t *build_ike_cfg(private_sql_config_t *this, enumerator_t *e,
ike_cfg = ike_cfg_create(IKEV2, certreq, force_encap,
local, FALSE,
charon->socket->get_port(charon->socket, FALSE),
remote, FALSE, IKEV2_UDP_PORT);
remote, FALSE, IKEV2_UDP_PORT, FALSE);
add_ike_proposals(this, ike_cfg, id);
return ike_cfg;
}
+2 -1
View File
@@ -233,7 +233,8 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg
ikeport,
msg->add_conn.other.address,
msg->add_conn.other.allow_any,
msg->add_conn.other.ikeport);
msg->add_conn.other.ikeport,
msg->add_conn.fragmentation);
add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg, NULL);
return ike_cfg;
}
+2 -2
View File
@@ -155,7 +155,7 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool,
ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE,
local_addr, FALSE,
charon->socket->get_port(charon->socket, FALSE),
remote_addr, FALSE, IKEV2_UDP_PORT);
remote_addr, FALSE, IKEV2_UDP_PORT, FALSE);
ike_cfg->add_proposal(ike_cfg, create_proposal(ike_proposal, PROTO_IKE));
this->peer_cfg = peer_cfg_create(
name, ike_cfg, CERT_SEND_IF_ASKED, UNIQUE_NO,
@@ -253,7 +253,7 @@ METHOD(enumerator_t, ike_enumerator_enumerate, bool,
this->ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE,
local_addr, FALSE,
charon->socket->get_port(charon->socket, FALSE),
remote_addr, FALSE, IKEV2_UDP_PORT);
remote_addr, FALSE, IKEV2_UDP_PORT, FALSE);
this->ike_cfg->add_proposal(this->ike_cfg,
create_proposal(ike_proposal, PROTO_IKE));
+3 -8
View File
@@ -225,11 +225,6 @@ struct private_task_manager_t {
} frag;
/**
* TRUE if fragmentation (as sender) is enabled in config
*/
bool fragmentation;
/**
* List of queued tasks not yet in action
*/
@@ -411,12 +406,14 @@ static bool send_fragment(private_task_manager_t *this, bool request,
static bool send_packet(private_task_manager_t *this, bool request,
packet_t *packet)
{
ike_cfg_t *ike_cfg;
host_t *src, *dst;
chunk_t data;
ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
data = packet->get_data(packet);
if (this->ike_sa->supports_extension(this->ike_sa, EXT_IKE_FRAGMENTATION) &&
this->fragmentation && data.len > MAX_FRAGMENT_SIZE)
ike_cfg->fragmentation(ike_cfg) && data.len > MAX_FRAGMENT_SIZE)
{
fragment_payload_t *fragment;
u_int8_t num, count;
@@ -2001,8 +1998,6 @@ task_manager_v1_t *task_manager_v1_create(ike_sa_t *ike_sa)
"%s.retransmit_timeout", RETRANSMIT_TIMEOUT, charon->name),
.retransmit_base = lib->settings->get_double(lib->settings,
"%s.retransmit_base", RETRANSMIT_BASE, charon->name),
.fragmentation = lib->settings->get_bool(lib->settings,
"%s.ike_fragmentation", FALSE, charon->name),
);
if (!this->rng)
+4 -2
View File
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -156,14 +157,15 @@ METHOD(task_t, build, status_t,
{
vendor_id_payload_t *vid_payload;
bool strongswan, cisco_unity, fragmentation;
ike_cfg_t *ike_cfg;
int i;
strongswan = lib->settings->get_bool(lib->settings,
"%s.send_vendor_id", FALSE, charon->name);
cisco_unity = lib->settings->get_bool(lib->settings,
"%s.cisco_unity", FALSE, charon->name);
fragmentation = lib->settings->get_bool(lib->settings,
"%s.ike_fragmentation", FALSE, charon->name);
ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
fragmentation = ike_cfg->fragmentation(ike_cfg);
if (!this->initiator && fragmentation)
{
fragmentation = this->ike_sa->supports_extension(this->ike_sa,
+1
View File
@@ -138,6 +138,7 @@ static const token_info_t token_info[] =
{ ARG_STR, offsetof(starter_conn_t, aaa_identity), NULL },
{ ARG_MISC, 0, NULL /* KW_MOBIKE */ },
{ ARG_MISC, 0, NULL /* KW_FORCEENCAPS */ },
{ ARG_MISC, 0, NULL /* KW_FRAGMENTATION */ },
{ ARG_TIME, offsetof(starter_conn_t, sa_ike_life_seconds), NULL },
{ ARG_TIME, offsetof(starter_conn_t, sa_ipsec_life_seconds), NULL },
{ ARG_TIME, offsetof(starter_conn_t, sa_rekey_margin), NULL },
+3
View File
@@ -567,6 +567,9 @@ static void load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg
case KW_FORCEENCAPS:
KW_SA_OPTION_FLAG("yes", "no", SA_OPTION_FORCE_ENCAP)
break;
case KW_FRAGMENTATION:
KW_SA_OPTION_FLAG("yes", "no", SA_OPTION_FRAGMENTATION)
break;
case KW_MODECONFIG:
KW_SA_OPTION_FLAG("push", "pull", SA_OPTION_MODECFG_PUSH)
break;
+1
View File
@@ -81,6 +81,7 @@ typedef enum {
SA_OPTION_XAUTH_SERVER = 1 << 5, /* are we an XAUTH server? */
SA_OPTION_MOBIKE = 1 << 6, /* enable MOBIKE for IKEv2 */
SA_OPTION_FORCE_ENCAP = 1 << 7, /* force UDP encapsulation */
SA_OPTION_FRAGMENTATION = 1 << 8, /* enable IKEv1 fragmentation */
} sa_option_t;
typedef struct starter_end starter_end_t;
+1
View File
@@ -42,6 +42,7 @@ typedef enum {
KW_AAA_IDENTITY,
KW_MOBIKE,
KW_FORCEENCAPS,
KW_FRAGMENTATION,
KW_IKELIFETIME,
KW_KEYLIFE,
KW_REKEYMARGIN,
+1
View File
@@ -40,6 +40,7 @@ eap_identity, KW_EAP_IDENTITY
aaa_identity, KW_AAA_IDENTITY
mobike, KW_MOBIKE
forceencaps, KW_FORCEENCAPS
fragmentation, KW_FRAGMENTATION
ikelifetime, KW_IKELIFETIME
lifetime, KW_KEYLIFE
keylife, KW_KEYLIFE
+1
View File
@@ -180,6 +180,7 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
}
msg.add_conn.mobike = conn->options & SA_OPTION_MOBIKE;
msg.add_conn.force_encap = conn->options & SA_OPTION_FORCE_ENCAP;
msg.add_conn.fragmentation = conn->options & SA_OPTION_FRAGMENTATION;
msg.add_conn.ipcomp = conn->options & SA_OPTION_COMPRESS;
msg.add_conn.install_policy = conn->install_policy;
msg.add_conn.aggressive = conn->aggressive;
+1
View File
@@ -254,6 +254,7 @@ struct stroke_msg_t {
int mobike;
int aggressive;
int force_encap;
int fragmentation;
int ipcomp;
time_t inactivity;
int proxy_mode;