ike: support multiple addresses, ranges and subnets in IKE address config
Replace the allowany semantic by a more powerful subnet and IP range matching. Multiple addresses, DNS names, subnets and ranges can be specified in a comma separated list. Initiators ignore the ranges/subnets, responders match configurations against all addresses, ranges and subnets.
This commit is contained in:
@@ -203,9 +203,9 @@ static void setup_tunnel(private_ha_tunnel_t *this,
|
||||
lib->credmgr->add_set(lib->credmgr, &this->creds.public);
|
||||
|
||||
/* create config and backend */
|
||||
ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, local, FALSE,
|
||||
ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, local,
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
remote, FALSE, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0);
|
||||
remote, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0);
|
||||
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,
|
||||
|
||||
@@ -544,16 +544,15 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
|
||||
if (this->port && num)
|
||||
{
|
||||
ike_cfg = ike_cfg_create(this->version, TRUE, FALSE,
|
||||
local, FALSE, this->port + num - 1,
|
||||
remote, FALSE, IKEV2_NATT_PORT,
|
||||
local, this->port + num - 1,
|
||||
remote, IKEV2_NATT_PORT,
|
||||
FRAGMENTATION_NO, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ike_cfg = ike_cfg_create(this->version, TRUE, FALSE,
|
||||
local, FALSE,
|
||||
ike_cfg = ike_cfg_create(this->version, TRUE, FALSE, local,
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
remote, FALSE, IKEV2_UDP_PORT,
|
||||
remote, IKEV2_UDP_PORT,
|
||||
FRAGMENTATION_NO, 0);
|
||||
}
|
||||
ike_cfg->add_proposal(ike_cfg, this->proposal->clone(this->proposal));
|
||||
|
||||
@@ -323,10 +323,9 @@ static gboolean initiate_connection(private_maemo_service_t *this,
|
||||
NULL);
|
||||
}
|
||||
|
||||
ike_cfg = ike_cfg_create(IKEV2, TRUE, FALSE, "0.0.0.0", FALSE,
|
||||
ike_cfg = ike_cfg_create(IKEV2, TRUE, FALSE, "0.0.0.0",
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
hostname, FALSE, IKEV2_UDP_PORT, FRAGMENTATION_NO,
|
||||
0);
|
||||
hostname, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0);
|
||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
||||
|
||||
peer_cfg = peer_cfg_create(this->current, ike_cfg,
|
||||
|
||||
@@ -102,10 +102,9 @@ METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
|
||||
DESTROY_IF(e);
|
||||
return NULL;
|
||||
}
|
||||
ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE,
|
||||
"0.0.0.0", FALSE,
|
||||
ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, "0.0.0.0",
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
address, FALSE, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0);
|
||||
address, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0);
|
||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
||||
med_cfg = peer_cfg_create(
|
||||
"mediation", ike_cfg,
|
||||
@@ -377,10 +376,9 @@ medcli_config_t *medcli_config_create(database_t *db)
|
||||
.db = db,
|
||||
.rekey = lib->settings->get_time(lib->settings, "medcli.rekey", 1200),
|
||||
.dpd = lib->settings->get_time(lib->settings, "medcli.dpd", 300),
|
||||
.ike = ike_cfg_create(IKEV2, FALSE, FALSE,
|
||||
"0.0.0.0", FALSE,
|
||||
.ike = ike_cfg_create(IKEV2, FALSE, FALSE, "0.0.0.0",
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
"0.0.0.0", FALSE, IKEV2_UDP_PORT,
|
||||
"0.0.0.0", IKEV2_UDP_PORT,
|
||||
FRAGMENTATION_NO, 0),
|
||||
);
|
||||
this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
|
||||
|
||||
@@ -139,10 +139,9 @@ medsrv_config_t *medsrv_config_create(database_t *db)
|
||||
.db = db,
|
||||
.rekey = lib->settings->get_time(lib->settings, "medsrv.rekey", 1200),
|
||||
.dpd = lib->settings->get_time(lib->settings, "medsrv.dpd", 300),
|
||||
.ike = ike_cfg_create(IKEV2, FALSE, FALSE,
|
||||
"0.0.0.0", FALSE,
|
||||
.ike = ike_cfg_create(IKEV2, FALSE, FALSE, "0.0.0.0",
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
"0.0.0.0", FALSE, IKEV2_UDP_PORT,
|
||||
"0.0.0.0", IKEV2_UDP_PORT,
|
||||
FRAGMENTATION_NO, 0),
|
||||
);
|
||||
this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
|
||||
|
||||
@@ -258,11 +258,9 @@ static ike_cfg_t *build_ike_cfg(private_sql_config_t *this, enumerator_t *e,
|
||||
{
|
||||
ike_cfg_t *ike_cfg;
|
||||
|
||||
ike_cfg = ike_cfg_create(IKEV2, certreq, force_encap,
|
||||
local, FALSE,
|
||||
ike_cfg = ike_cfg_create(IKEV2, certreq, force_encap, local,
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
remote, FALSE, IKEV2_UDP_PORT,
|
||||
FRAGMENTATION_NO, 0);
|
||||
remote, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0);
|
||||
add_ike_proposals(this, ike_cfg, id);
|
||||
return ike_cfg;
|
||||
}
|
||||
|
||||
@@ -191,53 +191,86 @@ static void add_proposals(private_stroke_config_t *this, char *string,
|
||||
*/
|
||||
static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
stroke_end_t tmp_end;
|
||||
ike_cfg_t *ike_cfg;
|
||||
host_t *host;
|
||||
u_int16_t ikeport;
|
||||
char me[256], other[256], *token;
|
||||
bool swapped = FALSE;;
|
||||
|
||||
host = host_create_from_dns(msg->add_conn.other.address, 0, 0);
|
||||
if (host)
|
||||
enumerator = enumerator_create_token(msg->add_conn.other.address, ",", " ");
|
||||
while (enumerator->enumerate(enumerator, &token))
|
||||
{
|
||||
if (hydra->kernel_interface->get_interface(hydra->kernel_interface,
|
||||
host, NULL))
|
||||
if (!strchr(token, '/'))
|
||||
{
|
||||
DBG2(DBG_CFG, "left is other host, swapping ends");
|
||||
tmp_end = msg->add_conn.me;
|
||||
msg->add_conn.me = msg->add_conn.other;
|
||||
msg->add_conn.other = tmp_end;
|
||||
host->destroy(host);
|
||||
}
|
||||
else
|
||||
{
|
||||
host->destroy(host);
|
||||
host = host_create_from_dns(msg->add_conn.me.address, 0, 0);
|
||||
host = host_create_from_dns(token, 0, 0);
|
||||
if (host)
|
||||
{
|
||||
if (!hydra->kernel_interface->get_interface(
|
||||
if (hydra->kernel_interface->get_interface(
|
||||
hydra->kernel_interface, host, NULL))
|
||||
{
|
||||
DBG1(DBG_CFG, "left nor right host is our side, "
|
||||
"assuming left=local");
|
||||
DBG2(DBG_CFG, "left is other host, swapping ends");
|
||||
tmp_end = msg->add_conn.me;
|
||||
msg->add_conn.me = msg->add_conn.other;
|
||||
msg->add_conn.other = tmp_end;
|
||||
host->destroy(host);
|
||||
swapped = TRUE;
|
||||
}
|
||||
host->destroy(host);
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (!swapped)
|
||||
{
|
||||
enumerator = enumerator_create_token(msg->add_conn.me.address, ",", " ");
|
||||
while (enumerator->enumerate(enumerator, &token))
|
||||
{
|
||||
if (!strchr(token, '/'))
|
||||
{
|
||||
host = host_create_from_dns(token, 0, 0);
|
||||
if (host)
|
||||
{
|
||||
if (!hydra->kernel_interface->get_interface(
|
||||
hydra->kernel_interface, host, NULL))
|
||||
{
|
||||
DBG1(DBG_CFG, "left nor right host is our side, "
|
||||
"assuming left=local");
|
||||
}
|
||||
host->destroy(host);
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
if (msg->add_conn.me.allow_any)
|
||||
{
|
||||
snprintf(me, sizeof(me), "%s,0.0.0.0/0,::/0",
|
||||
msg->add_conn.me.address);
|
||||
}
|
||||
if (msg->add_conn.other.allow_any)
|
||||
{
|
||||
snprintf(other, sizeof(other), "%s,0.0.0.0/0,::/0",
|
||||
msg->add_conn.other.address);
|
||||
}
|
||||
ikeport = msg->add_conn.me.ikeport;
|
||||
ikeport = (ikeport == IKEV2_UDP_PORT) ?
|
||||
charon->socket->get_port(charon->socket, FALSE) : ikeport;
|
||||
ike_cfg = ike_cfg_create(msg->add_conn.version,
|
||||
msg->add_conn.other.sendcert != CERT_NEVER_SEND,
|
||||
msg->add_conn.force_encap,
|
||||
msg->add_conn.me.address,
|
||||
msg->add_conn.me.allow_any,
|
||||
msg->add_conn.me.allow_any ?
|
||||
me : msg->add_conn.me.address,
|
||||
ikeport,
|
||||
msg->add_conn.other.address,
|
||||
msg->add_conn.other.allow_any,
|
||||
msg->add_conn.other.allow_any ?
|
||||
other : msg->add_conn.other.address,
|
||||
msg->add_conn.other.ikeport,
|
||||
msg->add_conn.fragmentation,
|
||||
msg->add_conn.ikedscp);
|
||||
|
||||
add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg, NULL);
|
||||
return ike_cfg;
|
||||
}
|
||||
@@ -824,7 +857,15 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strchr(ike_cfg->get_my_addr(ike_cfg), ':'))
|
||||
char *addr, *next, *hit;
|
||||
|
||||
/* guess virtual IP family based on local address. If
|
||||
* multiple addresses are specified, we look at the first
|
||||
* only, as with leftallowany a ::/0 is always appended. */
|
||||
addr = ike_cfg->get_my_addr(ike_cfg);
|
||||
next = strchr(addr, ',');
|
||||
hit = strchr(addr, ':');
|
||||
if (hit && (!next || hit < next))
|
||||
{
|
||||
vip = host_create_any(AF_INET6);
|
||||
}
|
||||
|
||||
@@ -544,7 +544,6 @@ METHOD(stroke_list_t, status, void,
|
||||
while (enumerator->enumerate(enumerator, &peer_cfg))
|
||||
{
|
||||
char *my_addr, *other_addr;
|
||||
bool my_allow_any, other_allow_any;
|
||||
|
||||
if (name && !streq(name, peer_cfg->get_name(peer_cfg)))
|
||||
{
|
||||
@@ -553,8 +552,8 @@ METHOD(stroke_list_t, status, void,
|
||||
|
||||
ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
|
||||
ike_version = peer_cfg->get_ike_version(peer_cfg);
|
||||
my_addr = ike_cfg->get_my_addr(ike_cfg, &my_allow_any);
|
||||
other_addr = ike_cfg->get_other_addr(ike_cfg, &other_allow_any);
|
||||
my_addr = ike_cfg->get_my_addr(ike_cfg);
|
||||
other_addr = ike_cfg->get_other_addr(ike_cfg);
|
||||
fprintf(out, "%12s: %s...%s %N", peer_cfg->get_name(peer_cfg),
|
||||
my_addr, other_addr, ike_version_names, ike_version);
|
||||
|
||||
|
||||
@@ -152,10 +152,9 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool,
|
||||
&ike_proposal, &esp_proposal, &ike_rekey, &esp_rekey))
|
||||
{
|
||||
DESTROY_IF(this->peer_cfg);
|
||||
ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE,
|
||||
local_addr, FALSE,
|
||||
ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, local_addr,
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
remote_addr, FALSE, IKEV2_UDP_PORT,
|
||||
remote_addr, IKEV2_UDP_PORT,
|
||||
FRAGMENTATION_NO, 0);
|
||||
ike_cfg->add_proposal(ike_cfg, create_proposal(ike_proposal, PROTO_IKE));
|
||||
this->peer_cfg = peer_cfg_create(
|
||||
@@ -251,10 +250,9 @@ METHOD(enumerator_t, ike_enumerator_enumerate, bool,
|
||||
&local_addr, &remote_addr, &ike_proposal))
|
||||
{
|
||||
DESTROY_IF(this->ike_cfg);
|
||||
this->ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE,
|
||||
local_addr, FALSE,
|
||||
this->ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, local_addr,
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
remote_addr, FALSE, IKEV2_UDP_PORT,
|
||||
remote_addr, IKEV2_UDP_PORT,
|
||||
FRAGMENTATION_NO, 0);
|
||||
this->ike_cfg->add_proposal(this->ike_cfg,
|
||||
create_proposal(ike_proposal, PROTO_IKE));
|
||||
|
||||
Reference in New Issue
Block a user