summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2010-09-22 09:12:19 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2010-09-22 09:12:19 +0000
commit87a12cd7e768bc898075277fac69684da499e47e (patch)
treeddd37c7b67b49d019f8273a1f6b4248688f351a7 /sbin
parent4644a56ba161c5256c8aa84e604d4f0657921836 (diff)
support INVALID_KE_PAYLOAD notification sent by the responder in case
the initiator chose wrong D-H group. in this case we throw away our SA and start over with a proper group. makes iked work as an initiator with strongswan/charon without any specific "ikesa" (phase 1) configuration. ok reyk
Diffstat (limited to 'sbin')
-rw-r--r--sbin/iked/iked.h4
-rw-r--r--sbin/iked/ikev2.c6
-rw-r--r--sbin/iked/ikev2_pld.c32
3 files changed, 36 insertions, 6 deletions
diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h
index 95f4f40c03a..2eaec5377b6 100644
--- a/sbin/iked/iked.h
+++ b/sbin/iked/iked.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: iked.h,v 1.19 2010/09/09 13:06:46 mikeb Exp $ */
+/* $OpenBSD: iked.h,v 1.20 2010/09/22 09:12:18 mikeb Exp $ */
/* $vantronix: iked.h,v 1.61 2010/06/03 07:57:33 reyk Exp $ */
/*
@@ -208,6 +208,7 @@ struct iked_policy {
struct sockaddr_storage pol_peer;
u_int8_t pol_peermask;
int pol_peernet;
+ struct group *pol_peerdh;
struct sockaddr_storage pol_local;
u_int8_t pol_localmask;
@@ -591,6 +592,7 @@ pid_t ikev1(struct iked *, struct iked_proc *);
/* ikev2.c */
pid_t ikev2(struct iked *, struct iked_proc *);
void ikev2_recv(struct iked *, struct iked_message *);
+int ikev2_init_ike_sa(struct iked *, struct iked_policy *);
int ikev2_sa_negotiate(struct iked_sa *, struct iked_proposals *,
struct iked_proposals *, u_int8_t);
int ikev2_policy2id(struct iked_static_id *, struct iked_id *, int);
diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c
index 5d7245e3351..84f36db73ce 100644
--- a/sbin/iked/ikev2.c
+++ b/sbin/iked/ikev2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikev2.c,v 1.24 2010/09/09 13:06:46 mikeb Exp $ */
+/* $OpenBSD: ikev2.c,v 1.25 2010/09/22 09:12:18 mikeb Exp $ */
/* $vantronix: ikev2.c,v 1.101 2010/06/03 07:57:33 reyk Exp $ */
/*
@@ -61,7 +61,6 @@ int ikev2_ike_auth(struct iked *, struct iked_sa *,
void ikev2_init_recv(struct iked *, struct iked_message *,
struct ike_header *);
-int ikev2_init_ike_sa(struct iked *, struct iked_policy *);
int ikev2_init_ike_auth(struct iked *, struct iked_sa *);
int ikev2_init_auth(struct iked *, struct iked_message *);
int ikev2_init_done(struct iked *, struct iked_sa *);
@@ -593,6 +592,9 @@ ikev2_init_ike_sa(struct iked *env, struct iked_policy *pol)
if ((sa = sa_new(env, 0, 0, 1, pol)) == NULL)
return (-1);
+ /* Pick peer's DH group if asked */
+ sa->sa_dhgroup = pol->pol_peerdh;
+
if (ikev2_sa_initiator(env, sa, NULL) == -1)
goto done;
diff --git a/sbin/iked/ikev2_pld.c b/sbin/iked/ikev2_pld.c
index cf14e2c78a0..72857a122dc 100644
--- a/sbin/iked/ikev2_pld.c
+++ b/sbin/iked/ikev2_pld.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikev2_pld.c,v 1.14 2010/07/28 15:45:04 jsg Exp $ */
+/* $OpenBSD: ikev2_pld.c,v 1.15 2010/09/22 09:12:18 mikeb Exp $ */
/* $vantronix: ikev2.c,v 1.101 2010/06/03 07:57:33 reyk Exp $ */
/*
@@ -633,11 +633,12 @@ ikev2_pld_notify(struct iked *env, struct ikev2_payload *pld,
struct ikev2_notify *n;
u_int8_t *buf, md[SHA_DIGEST_LENGTH];
size_t len;
- u_int16_t type;
u_int32_t spi32;
u_int64_t spi64;
struct iked_spi *rekey;
-
+ u_int16_t type;
+ u_int16_t group;
+
if ((n = ibuf_seek(msg->msg_data, offset, sizeof(*n))) == NULL)
return (-1);
type = betoh16(n->n_type);
@@ -707,6 +708,31 @@ ikev2_pld_notify(struct iked *env, struct ikev2_payload *pld,
print_map(n->n_protoid, ikev2_saproto_map),
print_spi(rekey->spi, n->n_spisize));
break;
+ case IKEV2_N_INVALID_KE_PAYLOAD:
+ if (len != sizeof(group)) {
+ log_debug("%s: malformed notification", __func__);
+ return (-1);
+ }
+ if (!msg->msg_sa->sa_hdr.sh_initiator) {
+ log_debug("%s: not an initiator", __func__);
+ sa_free(env, msg->msg_sa);
+ msg->msg_sa = NULL;
+ return (-1);
+ }
+ memcpy(&group, buf, len);
+ group = betoh16(group);
+ if ((msg->msg_policy->pol_peerdh = group_get(group))
+ == NULL) {
+ log_debug("%s: unable to select DH group %d", __func__,
+ group);
+ return (-1);
+ }
+ log_debug("%s: responder selected DH group %d", __func__,
+ group);
+ sa_free(env, msg->msg_sa);
+ msg->msg_sa = NULL;
+ timer_register_initiator(env, ikev2_init_ike_sa);
+ break;
}
return (0);