diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2010-09-22 09:12:19 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2010-09-22 09:12:19 +0000 |
commit | 87a12cd7e768bc898075277fac69684da499e47e (patch) | |
tree | ddd37c7b67b49d019f8273a1f6b4248688f351a7 /sbin/iked | |
parent | 4644a56ba161c5256c8aa84e604d4f0657921836 (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/iked')
-rw-r--r-- | sbin/iked/iked.h | 4 | ||||
-rw-r--r-- | sbin/iked/ikev2.c | 6 | ||||
-rw-r--r-- | sbin/iked/ikev2_pld.c | 32 |
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); |