Re: iked: address pools for both families

2016-06-01 Thread Mike Belopuhov
On 1 June 2016 at 10:16, Patrick Wildt  wrote:
> Hi,
>
> Currently there is only one address pool which is either v4 or v6.
> This means that we cannot have dual-stack VPNs via iked.  Clients
> then might tunnel all IPv4 traffic, but IPv6 traffic is still using
> the non-encrypted default route, which might be a security issue.
> To enable dual-stack IKEv2, set up a second address pool which is
> specifically for v6.
>
> Patrick
>

Looks alright to me.  OK mikeb



iked: address pools for both families

2016-06-01 Thread Patrick Wildt
Hi,

Currently there is only one address pool which is either v4 or v6.
This means that we cannot have dual-stack VPNs via iked.  Clients
then might tunnel all IPv4 traffic, but IPv6 traffic is still using
the non-encrypted default route, which might be a security issue.
To enable dual-stack IKEv2, set up a second address pool which is
specifically for v6.

Patrick

diff --git sbin/iked/config.c sbin/iked/config.c
index 1650258..4b9b3a2 100644
--- sbin/iked/config.c
+++ sbin/iked/config.c
@@ -104,6 +104,10 @@ config_free_sa(struct iked *env, struct iked_sa *sa)
(void)RB_REMOVE(iked_addrpool, >sc_addrpool, sa);
free(sa->sa_addrpool);
}
+   if (sa->sa_addrpool6) {
+   (void)RB_REMOVE(iked_addrpool6, >sc_addrpool6, sa);
+   free(sa->sa_addrpool6);
+   }
 
if (sa->sa_policy) {
TAILQ_REMOVE(>sa_policy->pol_sapeers, sa, sa_peer_entry);
diff --git sbin/iked/iked.h sbin/iked/iked.h
index b1c3152..3fb7c9f 100644
--- sbin/iked/iked.h
+++ sbin/iked/iked.h
@@ -449,9 +449,13 @@ struct iked_sa {
 
struct iked_addr*sa_addrpool;   /* address from pool */
RB_ENTRY(iked_sa)sa_addrpool_entry; /* pool entries 
*/
+
+   struct iked_addr*sa_addrpool6;  /* address from pool */
+   RB_ENTRY(iked_sa)sa_addrpool6_entry;/* pool entries 
*/
 };
 RB_HEAD(iked_sas, iked_sa);
 RB_HEAD(iked_addrpool, iked_sa);
+RB_HEAD(iked_addrpool6, iked_sa);
 
 struct iked_message {
struct ibuf *msg_data;
@@ -599,6 +603,7 @@ struct iked {
char*sc_ocsp_url;
 
struct iked_addrpool sc_addrpool;
+   struct iked_addrpool6sc_addrpool6;
 };
 
 struct iked_socket {
@@ -691,6 +696,7 @@ struct iked_user *
 user_lookup(struct iked *, const char *);
 RB_PROTOTYPE(iked_sas, iked_sa, sa_entry, sa_cmp);
 RB_PROTOTYPE(iked_addrpool, iked_sa, sa_addrpool_entry, sa_addrpool_cmp);
+RB_PROTOTYPE(iked_addrpool6, iked_sa, sa_addrpool6_entry, sa_addrpool6_cmp);
 RB_PROTOTYPE(iked_users, iked_user, user_entry, user_cmp);
 RB_PROTOTYPE(iked_activesas, iked_childsa, csa_node, childsa_cmp);
 RB_PROTOTYPE(iked_flows, iked_flow, flow_node, flow_cmp);
diff --git sbin/iked/ikev2.c sbin/iked/ikev2.c
index 7d36800..d4c4290 100644
--- sbin/iked/ikev2.c
+++ sbin/iked/ikev2.c
@@ -122,7 +122,7 @@ int  ikev2_add_buf(struct ibuf *buf, struct ibuf *);
 int ikev2_ipcomp_enable(struct iked *, struct iked_sa *);
 voidikev2_ipcomp_csa_free(struct iked *, struct iked_childsa *);
 
-int ikev2_cp_setaddr(struct iked *, struct iked_sa *);
+int ikev2_cp_setaddr(struct iked *, struct iked_sa *, sa_family_t);
 int ikev2_cp_fixaddr(struct iked_sa *, struct iked_addr *,
struct iked_addr *);
 
@@ -1739,9 +1739,9 @@ ikev2_add_cp(struct iked *env, struct iked_sa *sa, struct 
ibuf *buf)
in6 = (ikecfg->cfg.address.addr_mask != 128 &&
(ikecfg->cfg_type ==
IKEV2_CFG_INTERNAL_IP6_ADDRESS) &&
-   sa->sa_addrpool &&
-   sa->sa_addrpool->addr_af == AF_INET6) ?
-   (struct sockaddr_in6 *)>sa_addrpool->addr :
+   sa->sa_addrpool6 &&
+   sa->sa_addrpool6->addr_af == AF_INET6) ?
+   (struct sockaddr_in6 *)>sa_addrpool6->addr :
(struct sockaddr_in6 *)>cfg.address.addr;
cfg->cfg_length = htobe16(17);
if (ibuf_add(buf, >sin6_addr.s6_addr, 16) == -1)
@@ -2184,7 +2184,8 @@ ikev2_resp_ike_auth(struct iked *env, struct iked_sa *sa)
else if (!sa_stateok(sa, IKEV2_STATE_VALID))
return (0); /* ignore */
 
-   if (ikev2_cp_setaddr(env, sa) < 0)
+   if (ikev2_cp_setaddr(env, sa, AF_INET) < 0 ||
+   ikev2_cp_setaddr(env, sa, AF_INET6) < 0)
return (-1);
 
if (ikev2_childsa_negotiate(env, sa, >sa_kex, >sa_proposals,
@@ -2943,6 +2944,12 @@ ikev2_ikesa_enable(struct iked *env, struct iked_sa *sa, 
struct iked_sa *nsa)
sa->sa_addrpool = NULL;
RB_INSERT(iked_addrpool, >sc_addrpool, nsa);
}
+   if (sa->sa_addrpool6) {
+   RB_REMOVE(iked_addrpool6, >sc_addrpool6, sa);
+   nsa->sa_addrpool6 = sa->sa_addrpool6;
+   sa->sa_addrpool6 = NULL;
+   RB_INSERT(iked_addrpool6, >sc_addrpool6, nsa);
+   }
 
log_debug("%s: activating new IKE SA", __func__);
sa_state(env, nsa, IKEV2_STATE_ESTABLISHED);
@@ -5029,7 +5036,7 @@ ikev2_print_id(struct iked_id *id, char *idstr, size_t 
idstrlen)
  * and remember it in the sa_addrpool attribute.
  */
 int
-ikev2_cp_setaddr(struct iked *env, struct iked_sa *sa)
+ikev2_cp_setaddr(struct iked *env, struct iked_sa *sa,