aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2008-04-25 12:41:37 +0000
committerMartin Willi <martin@strongswan.org>2008-04-25 12:41:37 +0000
commit3444390241db7d0c598e026ba598f4263b3620ef (patch)
tree281972313638f85a74db44a36c77ed5efc053193
parent1aedf08183a70a4259b74f0b074da6bda483c513 (diff)
downloadstrongswan-3444390241db7d0c598e026ba598f4263b3620ef.tar.bz2
strongswan-3444390241db7d0c598e026ba598f4263b3620ef.tar.xz
supporting multiple comma seperated subnets in left/rightsubnet definition
e.g. leftsubnet=10.2.0.0/16,10.4.0.0/16
-rw-r--r--src/charon/plugins/stroke/stroke_config.c82
-rw-r--r--src/charon/plugins/stroke/stroke_socket.c4
-rw-r--r--src/starter/cmp.c2
-rw-r--r--src/starter/confread.c35
-rw-r--r--src/starter/confread.h2
-rw-r--r--src/starter/ipsec.conf.54
-rw-r--r--src/starter/starterstroke.c4
-rw-r--r--src/starter/starterwhack.c22
-rw-r--r--src/stroke/stroke.c15
-rw-r--r--src/stroke/stroke_msg.h3
10 files changed, 116 insertions, 57 deletions
diff --git a/src/charon/plugins/stroke/stroke_config.c b/src/charon/plugins/stroke/stroke_config.c
index 931dc9c39..54b3bf896 100644
--- a/src/charon/plugins/stroke/stroke_config.c
+++ b/src/charon/plugins/stroke/stroke_config.c
@@ -472,9 +472,9 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
}
if (!vip)
{ /* if it is set to something like %poolname, request an address */
- if (msg->add_conn.me.subnet)
+ if (msg->add_conn.me.subnets)
{ /* use the same addreass as in subnet, if any */
- if (strchr(msg->add_conn.me.subnet, '.'))
+ if (strchr(msg->add_conn.me.subnets, '.'))
{
vip = host_create_any(AF_INET);
}
@@ -620,27 +620,67 @@ static void build_auth_info(private_stroke_config_t *this,
/**
* build a traffic selector from a stroke_end
*/
-static traffic_selector_t *build_ts(private_stroke_config_t *this,
- stroke_end_t *end)
+static void add_ts(private_stroke_config_t *this,
+ stroke_end_t *end, child_cfg_t *child_cfg, bool local)
{
+ traffic_selector_t *ts;
+
if (end->tohost)
{
- return traffic_selector_create_dynamic(end->protocol,
+ ts = traffic_selector_create_dynamic(end->protocol,
end->port ? end->port : 0, end->port ? end->port : 65535);
+ child_cfg->add_traffic_selector(child_cfg, local, ts);
}
else
{
host_t *net;
- net = host_create_from_string(end->subnet ? end->subnet : end->address,
- IKEV2_UDP_PORT);
- if (!net)
+ if (!end->subnets)
{
- DBG1(DBG_CFG, "invalid subnet: %s", end->subnet);
- return NULL;
+ net = host_create_from_string(end->address, IKEV2_UDP_PORT);
+ if (net)
+ {
+ ts = traffic_selector_create_from_subnet(net, 0, end->protocol,
+ end->port);
+ child_cfg->add_traffic_selector(child_cfg, local, ts);
+ }
+ }
+ else
+ {
+ char *del, *start, *bits;
+
+ start = end->subnets;
+ do
+ {
+ int intbits = 0;
+
+ del = strchr(start, ',');
+ if (del)
+ {
+ *del = '\0';
+ }
+ bits = strchr(start, '/');
+ if (bits)
+ {
+ *bits = '\0';
+ intbits = atoi(bits + 1);
+ }
+
+ net = host_create_from_string(start, IKEV2_UDP_PORT);
+ if (net)
+ {
+ ts = traffic_selector_create_from_subnet(net, intbits,
+ end->protocol, end->port);
+ child_cfg->add_traffic_selector(child_cfg, local, ts);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "invalid subnet: %s, skipped", start);
+ }
+ start = del + 1;
+ }
+ while (del);
}
- return traffic_selector_create_from_subnet(net,
- end->subnet ? end->subnet_mask : 0, end->protocol, end->port);
}
}
@@ -651,7 +691,6 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
stroke_msg_t *msg)
{
child_cfg_t *child_cfg;
- traffic_selector_t *ts;
action_t dpd;
switch (msg->add_conn.dpd.action)
@@ -673,21 +712,8 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
msg->add_conn.me.updown, msg->add_conn.me.hostaccess,
msg->add_conn.mode, dpd, ACTION_NONE);
- ts = build_ts(this, &msg->add_conn.me);
- if (!ts)
- {
- child_cfg->destroy(child_cfg);
- return NULL;
- }
- child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
-
- ts = build_ts(this, &msg->add_conn.other);
- if (!ts)
- {
- child_cfg->destroy(child_cfg);
- return NULL;
- }
- child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
+ add_ts(this, &msg->add_conn.me, child_cfg, TRUE);
+ add_ts(this, &msg->add_conn.other, child_cfg, FALSE);
add_proposals(this, msg->add_conn.algorithms.esp, NULL, child_cfg);
diff --git a/src/charon/plugins/stroke/stroke_socket.c b/src/charon/plugins/stroke/stroke_socket.c
index 53148b9c0..2ae22e447 100644
--- a/src/charon/plugins/stroke/stroke_socket.c
+++ b/src/charon/plugins/stroke/stroke_socket.c
@@ -140,7 +140,7 @@ static void pop_string(stroke_msg_t *msg, char **string)
static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
{
pop_string(msg, &end->address);
- pop_string(msg, &end->subnet);
+ pop_string(msg, &end->subnets);
pop_string(msg, &end->sourceip);
pop_string(msg, &end->id);
pop_string(msg, &end->cert);
@@ -149,7 +149,7 @@ static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
pop_string(msg, &end->updown);
DBG2(DBG_CFG, " %s=%s", label, end->address);
- DBG2(DBG_CFG, " %ssubnet=%s", label, end->subnet);
+ DBG2(DBG_CFG, " %ssubnet=%s", label, end->subnets);
DBG2(DBG_CFG, " %ssourceip=%s", label, end->sourceip);
DBG2(DBG_CFG, " %sid=%s", label, end->id);
DBG2(DBG_CFG, " %scert=%s", label, end->cert);
diff --git a/src/starter/cmp.c b/src/starter/cmp.c
index 610b08960..ad968db78 100644
--- a/src/starter/cmp.c
+++ b/src/starter/cmp.c
@@ -47,7 +47,7 @@ starter_cmp_end(starter_end_t *c1, starter_end_t *c2)
}
ADDCMP(nexthop);
STRCMP(srcip);
- SUBCMP(subnet);
+ STRCMP(subnet);
VARCMP(has_client);
VARCMP(has_client_wildcard);
VARCMP(has_port_wildcard);
diff --git a/src/starter/confread.c b/src/starter/confread.c
index 42b737ed4..606f1e327 100644
--- a/src/starter/confread.c
+++ b/src/starter/confread.c
@@ -32,7 +32,7 @@
#include "interfaces.h"
/* strings containing a colon are interpreted as an IPv6 address */
-#define ip_version(string) (strchr(string, ':') != NULL)? AF_INET6 : AF_INET;
+#define ip_version(string) (strchr(string, '.') ? AF_INET : AF_INET6)
static const char ike_defaults[] = "aes128-sha-modp2048";
static const char esp_defaults[] = "aes128-sha1, 3des-md5";
@@ -189,7 +189,6 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
conn->policy |= POLICY_GROUP | POLICY_TUNNEL;
anyaddr(conn->addr_family, &end->addr);
anyaddr(conn->tunnel_addr_family, &any);
- initsubnet(&any, 0, '0', &end->subnet);
end->has_client = TRUE;
}
else
@@ -251,22 +250,44 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
}
else
{
+ ip_subnet net;
+ char *pos;
+ int len = 0;
+
end->has_client = TRUE;
conn->tunnel_addr_family = ip_version(value);
- ugh = ttosubnet(value, 0, conn->tunnel_addr_family, &end->subnet);
+
+ pos = strchr(value, ',');
+ if (pos)
+ {
+ len = pos - value;
+ }
+ ugh = ttosubnet(value, len, ip_version(value), &net);
if (ugh != NULL)
{
plog("# bad subnet: %s=%s [%s]", name, value, ugh);
goto err;
}
+ end->subnet = clone_str(value, "subnet");
}
break;
case KW_SUBNETWITHIN:
+ {
+ ip_subnet net;
+
end->has_client = TRUE;
end->has_client_wildcard = TRUE;
conn->tunnel_addr_family = ip_version(value);
- ugh = ttosubnet(value, 0, conn->tunnel_addr_family, &end->subnet);
+
+ ugh = ttosubnet(value, 0, ip_version(value), &net);
+ if (ugh != NULL)
+ {
+ plog("# bad subnet: %s=%s [%s]", name, value, ugh);
+ goto err;
+ }
+ end->subnet = clone_str(value, "subnetwithin");
break;
+ }
case KW_PROTOPORT:
ugh = ttoprotoport(value, 0, &end->protocol, &end->port, &has_port_wildcard);
end->has_port_wildcard = has_port_wildcard;
@@ -827,6 +848,12 @@ free_also(also_t *head)
static void
confread_free_conn(starter_conn_t *conn)
{
+ pfree(conn->left.subnet);
+ pfree(conn->right.subnet);
+ pfree(conn->left.virt);
+ pfree(conn->right.virt);
+ pfree(conn->left.srcip);
+ pfree(conn->right.srcip);
free_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->left);
free_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->right);
free_args(KW_CONN_NAME, KW_CONN_LAST, (char *)conn);
diff --git a/src/starter/confread.h b/src/starter/confread.h
index 5c0b714d8..d7e8ec37a 100644
--- a/src/starter/confread.h
+++ b/src/starter/confread.h
@@ -65,7 +65,7 @@ struct starter_end {
char *iface;
ip_address addr;
ip_address nexthop;
- ip_subnet subnet;
+ char *subnet;
bool has_client;
bool has_client_wildcard;
bool has_port_wildcard;
diff --git a/src/starter/ipsec.conf.5 b/src/starter/ipsec.conf.5
index eefd216fb..fa66c886d 100644
--- a/src/starter/ipsec.conf.5
+++ b/src/starter/ipsec.conf.5
@@ -646,7 +646,9 @@ private subnet behind the left participant, expressed as
if omitted, essentially assumed to be \fIleft\fB/32\fR,
signifying that the left end of the connection goes to the left participant
only. When using IKEv2, the configured subnet of the peers may differ, the
-protocol narrows it to the greates common subnet.
+protocol narrows it to the greatest common subnet. Further, IKEv2 supports
+multiple subnets separated by commas. IKEv1 only interprets the first subnet
+of such a definition.
.TP
.B leftsubnetwithin
the peer can propose any subnet or single IP address that fits within the
diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c
index d75d25a72..66b007e39 100644
--- a/src/starter/starterstroke.c
+++ b/src/starter/starterstroke.c
@@ -161,9 +161,7 @@ static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, sta
msg_end->updown = push_string(msg, conn_end->updown);
ip_address2string(&conn_end->addr, buffer, sizeof(buffer));
msg_end->address = push_string(msg, buffer);
- ip_address2string(&conn_end->subnet.addr, buffer, sizeof(buffer));
- msg_end->subnet = push_string(msg, buffer);
- msg_end->subnet_mask = conn_end->subnet.maskbits;
+ msg_end->subnets = push_string(msg, conn_end->subnet);
msg_end->sendcert = conn_end->sendcert;
msg_end->hostaccess = conn_end->hostaccess;
msg_end->tohost = !conn_end->has_client;
diff --git a/src/starter/starterwhack.c b/src/starter/starterwhack.c
index 84c1972ed..4535a583e 100644
--- a/src/starter/starterwhack.c
+++ b/src/starter/starterwhack.c
@@ -32,6 +32,8 @@
#include "confread.h"
#include "files.h"
+#define ip_version(string) (strchr(string, '.') ? AF_INET : AF_INET6)
+
static int
pack_str (char **p, char **next, char **roof)
{
@@ -153,22 +155,22 @@ set_whack_end(whack_end_t *w, starter_end_t *end, sa_family_t family)
if (end->srcip && end->srcip[0] != '%')
{
int len = 0;
- char *pos, *v6;
+ char *pos;
pos = strchr(end->srcip, '/');
- v6 = strchr(end->srcip, ':');
if (pos)
{
/* use first address only for pluto */
len = pos - end->srcip;
}
w->has_srcip = !end->has_natip;
- ttoaddr(end->srcip, len, v6 ? AF_INET6 : AF_INET, &w->host_srcip);
+ ttoaddr(end->srcip, len, ip_version(end->srcip), &w->host_srcip);
}
else
{
anyaddr(AF_INET, &w->host_srcip);
- }
+ }
+
w->id = end->id;
w->cert = end->cert;
w->ca = end->ca;
@@ -183,7 +185,17 @@ set_whack_end(whack_end_t *w, starter_end_t *end, sa_family_t family)
w->host_nexthop = end->nexthop;
if (w->has_client)
- w->client = end->subnet;
+ {
+ char *pos;
+ int len = 0;
+
+ pos = strchr(end->subnet, ',');
+ if (pos)
+ {
+ len = pos - end->subnet;
+ }
+ ttosubnet(end->subnet, len, ip_version(end->subnet), &w->client);
+ }
else
w->client.addr.u.v4.sin_family = addrtypeof(&w->host_addr);
diff --git a/src/stroke/stroke.c b/src/stroke/stroke.c
index 77436801c..90d99acbc 100644
--- a/src/stroke/stroke.c
+++ b/src/stroke/stroke.c
@@ -100,8 +100,7 @@ static int send_stroke_msg (stroke_msg_t *msg)
static int add_connection(char *name,
char *my_id, char *other_id,
char *my_addr, char *other_addr,
- char *my_net, char *other_net,
- u_int my_netmask, u_int other_netmask)
+ char *my_nets, char *other_nets)
{
stroke_msg_t msg;
@@ -118,14 +117,12 @@ static int add_connection(char *name,
msg.add_conn.me.id = push_string(&msg, my_id);
msg.add_conn.me.address = push_string(&msg, my_addr);
- msg.add_conn.me.subnet = push_string(&msg, my_net);
- msg.add_conn.me.subnet_mask = my_netmask;
+ msg.add_conn.me.subnets = push_string(&msg, my_nets);
msg.add_conn.me.sendcert = 1;
msg.add_conn.other.id = push_string(&msg, other_id);
msg.add_conn.other.address = push_string(&msg, other_addr);
- msg.add_conn.other.subnet = push_string(&msg, other_net);
- msg.add_conn.other.subnet_mask = other_netmask;
+ msg.add_conn.other.subnets = push_string(&msg, other_nets);
msg.add_conn.other.sendcert = 1;
return send_stroke_msg(&msg);
@@ -277,8 +274,7 @@ static void exit_usage(char *error)
printf(" MY_NET OTHER_NET MY_NETBITS OTHER_NETBITS\n");
printf(" where: ID is any IKEv2 ID \n");
printf(" ADDR is a IPv4 address\n");
- printf(" NET is a IPv4 address of the subnet to tunnel\n");
- printf(" NETBITS is the size of the subnet, as the \"24\" in 192.168.0.0/24\n");
+ printf(" NET is a IPv4 subnet in CIDR notation\n");
printf(" Delete a connection:\n");
printf(" stroke delete NAME\n");
printf(" where: NAME is a connection name added with \"stroke add\"\n");
@@ -334,8 +330,7 @@ int main(int argc, char *argv[])
res = add_connection(argv[2],
argv[3], argv[4],
argv[5], argv[6],
- argv[7], argv[8],
- atoi(argv[9]), atoi(argv[10]));
+ argv[7], argv[8]);
break;
case STROKE_DELETE:
case STROKE_DEL:
diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h
index 96d13ae84..9fa3449ec 100644
--- a/src/stroke/stroke_msg.h
+++ b/src/stroke/stroke_msg.h
@@ -127,8 +127,7 @@ struct stroke_end_t {
char *address;
char *sourceip;
int sourceip_size;
- char *subnet;
- int subnet_mask;
+ char *subnets;
int sendcert;
int hostaccess;
int tohost;