diff options
author | Martin Willi <martin@strongswan.org> | 2008-04-25 12:41:37 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2008-04-25 12:41:37 +0000 |
commit | 3444390241db7d0c598e026ba598f4263b3620ef (patch) | |
tree | 281972313638f85a74db44a36c77ed5efc053193 | |
parent | 1aedf08183a70a4259b74f0b074da6bda483c513 (diff) | |
download | strongswan-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.c | 82 | ||||
-rw-r--r-- | src/charon/plugins/stroke/stroke_socket.c | 4 | ||||
-rw-r--r-- | src/starter/cmp.c | 2 | ||||
-rw-r--r-- | src/starter/confread.c | 35 | ||||
-rw-r--r-- | src/starter/confread.h | 2 | ||||
-rw-r--r-- | src/starter/ipsec.conf.5 | 4 | ||||
-rw-r--r-- | src/starter/starterstroke.c | 4 | ||||
-rw-r--r-- | src/starter/starterwhack.c | 22 | ||||
-rw-r--r-- | src/stroke/stroke.c | 15 | ||||
-rw-r--r-- | src/stroke/stroke_msg.h | 3 |
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; |