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, 

Re: iked address pools

2013-06-06 Thread Peter Hessler
You can use cvs add against a mirror to add files.  Directories
require write access, so that won't work.  Then use cvs diff -Nup to
include all of the (N)ew files.

tech@ is the preferred mailing list for diffs.


On 2013 Jun 05 (Wed) at 23:23:53 -0600 (-0600), Ryan Slack wrote:
:I wish to submit a working implementation of address pools for iked,
:however as it's my first real code contribution and has 643 lines
:(mostly patch context) I'm wondering if posting here is the correct
:channel.
:
:Also, what is the preferred/normal way to include new files in a patch?
:
:--Ryan Slack
:

-- 
Be security conscious -- National Defense is at stake.



[PATCH] iked address pools

2013-06-06 Thread Ryan Slack
The following provides address pools for iked. It's nothing fancy, but
it seems to work, at least in the cursory testing done against the
Windows 7 client.

Each policy gets it's own pool, configured by config address start
ip - end ip.
There is a hard limit of 65536 addresses (8kb) per pool, which should be plenty.
There is NO ipv6 support, partly because I'm not really sure how or
why it would be needed.
A request for a specific ip that is available in the pool will be honoured.

Comments please!

--Ryan Slack


Index: addr_pool.c
===
RCS file: addr_pool.c
diff -N addr_pool.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ addr_pool.c 7 Jun 2013 03:05:46 -
@@ -0,0 +1,188 @@
+
+#include sys/socket.h
+
+#include netinet/in.h
+
+#include stdlib.h
+#include string.h
+#include errno.h
+#include err.h
+
+#include iked.h
+
+int
+addr_pool_init_mask(struct addr_pool* pool,
+   struct sockaddr_storage *address, u_int8_t prefixlengh)
+{
+   struct sockaddr_in  *a4;
+   /* struct sockaddr_in6  *a6; */
+
+   if(pool == NULL) return(-1);
+
+   memcpy(pool-addr, address, sizeof(pool-addr));
+
+   switch(address-ss_family){
+   case AF_INET:
+   if (!(16  prefixlengh  prefixlengh  30)) {
+   log_warnx(%s: prefixlengh (%d) out of range [16:30],
+ __func__,prefixlengh);
+   return(-1);
+   }
+   //pool-mask = prefixlen2mask(prefixlengh);
+   pool-size = (1(32 - prefixlengh)) - 2;
+
+   a4 = (struct sockaddr_in *)pool-addr;
+   a4-sin_addr.s_addr = ntohl(a4-sin_addr.s_addr) + 1;
+   a4-sin_addr.s_addr = htonl(a4-sin_addr.s_addr);
+
+   break;
+   case AF_INET6:
+   default:
+   errno = EAFNOSUPPORT;
+   log_warn(%s: ,__func__);
+   return (-1);
+   }
+
+   return(0);
+}
+
+int
+addr_pool_init_range(struct addr_pool* pool,
+struct sockaddr_storage *start,
+struct sockaddr_storage *end)
+{
+   struct sockaddr_in  *a4, *b4;
+   //struct sockaddr_in6   *a6, *b6;
+   uint32_t size_l;
+
+   if(pool == NULL || start == NULL || end == NULL) return(-1);
+
+   if (start-ss_family != end-ss_family) {
+   log_debug(%s: address family mismatch, __func__);
+   return (-1);
+   }
+
+
+   switch(start-ss_family){
+   case AF_INET:
+   a4 = (struct sockaddr_in *)start;
+   b4 = (struct sockaddr_in *)end;
+
+   size_l = ntohl(b4-sin_addr.s_addr) -
ntohl(a4-sin_addr.s_addr) + 1;
+
+   if ( size_l  ADDR_POOL_SIZE_MAX ) {
+   log_warnx(%s: size (%d) out of range
(%d),__func__, size_l, ADDR_POOL_SIZE_MAX);
+   return(-1);
+   }
+   pool-size = size_l;
+
+   break;
+   case AF_INET6:
+   default:
+   errno = EAFNOSUPPORT;
+   log_warn(%s: , __func__);
+   return (-1);
+   }
+
+   memcpy(pool-addr, start, sizeof(pool-addr));
+
+   return(0);
+}
+
+
+int
+addr_pool_alloc(struct addr_pool* pool)
+{
+   if((pool-pool = bit_alloc(pool-size))==NULL)
+   return (-1);
+
+   log_debug(%s: %s+%d, __func__,
+ print_host(pool-addr, NULL, 0), pool-size);
+
+   return(0);
+}
+
+int
+addr_pool_free(struct addr_pool* pool){
+   if(pool-size)
+   free(pool-pool);
+   return (0);
+}
+
+int
+addr_pool_reqest(struct addr_pool* pool, struct sockaddr_storage *address)
+{
+   struct sockaddr_in *a4;
+   //struct sockaddr_in6 *sa6,*pa6;
+   u_int32_t h_addr;
+   int32_t i;
+   if(pool-addr.ss_family != address-ss_family){
+   log_debug(%s: address family mismatch, __func__);
+   return(-1);
+   }
+   switch(pool-addr.ss_family){
+   case AF_INET:
+   a4 = ((struct sockaddr_in *)address);
+   h_addr = ntohl(((struct
sockaddr_in*)pool-addr)-sin_addr.s_addr);
+   i = ntohl(a4-sin_addr.s_addr) - h_addr;
+   if (0 = i  (uint32_t)i  pool-size 
!bit_test(pool-pool,i)) {
+   bit_set(pool-pool,i);
+   } else {
+   bit_ffc(pool-pool,pool-size,i);
+   bit_set(pool-pool,i);
+   a4-sin_addr.s_addr = htonl(h_addr + i);
+   }
+   log_debug(%s: assigned %s [%d], __func__,
+ print_host(address, NULL, 0), i);
+
+   break;
+   case AF_INET6:
+   default:
+   errno = EAFNOSUPPORT;
+   log_warn(%s: , __func__);
+   return (-1);
+   }
+
+   return (0);
+}
+
+int
+addr_pool_release(struct addr_pool* pool, struct sockaddr_storage 

iked address pools

2013-06-05 Thread Ryan Slack
I wish to submit a working implementation of address pools for iked,
however as it's my first real code contribution and has 643 lines
(mostly patch context) I'm wondering if posting here is the correct
channel.

Also, what is the preferred/normal way to include new files in a patch?

--Ryan Slack