summaryrefslogtreecommitdiff
path: root/sbin/iked
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2010-06-14 08:10:33 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2010-06-14 08:10:33 +0000
commite834fcd4ecac4135ad6e8ed7ea7be646efaea5cd (patch)
treeb1e904ba3cd6d6a0811d72756affe0b53d9562fb /sbin/iked
parente1944808d62d45bb05963968faa0fde7ab36feed (diff)
More code for initiator mode (not finished yet)
Diffstat (limited to 'sbin/iked')
-rw-r--r--sbin/iked/config.c19
-rw-r--r--sbin/iked/iked.h14
-rw-r--r--sbin/iked/ikev2.c204
-rw-r--r--sbin/iked/ikev2_msg.c36
-rw-r--r--sbin/iked/ikev2_pld.c49
-rw-r--r--sbin/iked/policy.c43
-rw-r--r--sbin/iked/timer.c12
7 files changed, 313 insertions, 64 deletions
diff --git a/sbin/iked/config.c b/sbin/iked/config.c
index 89003de41f0..beb00fcdbd7 100644
--- a/sbin/iked/config.c
+++ b/sbin/iked/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.3 2010/06/10 14:08:37 reyk Exp $ */
+/* $OpenBSD: config.c,v 1.4 2010/06/14 08:10:32 reyk Exp $ */
/* $vantronix: config.c,v 1.30 2010/05/28 15:34:35 reyk Exp $ */
/*
@@ -57,6 +57,7 @@ config_new_sa(struct iked *env, int initiator)
TAILQ_INIT(&sa->sa_childsas);
TAILQ_INIT(&sa->sa_flows);
sa->sa_hdr.sh_initiator = initiator;
+ sa->sa_type = IKED_SATYPE_LOCAL;
if (initiator)
sa->sa_hdr.sh_ispi = config_getspi();
@@ -504,7 +505,7 @@ int
config_getsocket(struct iked *env, struct imsg *imsg,
void (*cb)(int, short, void *))
{
- struct iked_socket *sock;
+ struct iked_socket *sock, **sptr;
log_debug("%s: received socket fd %d", __func__, imsg->fd);
@@ -517,6 +518,20 @@ config_getsocket(struct iked *env, struct imsg *imsg,
sock->sock_fd = imsg->fd;
sock->sock_env = env;
+ switch (sock->sock_addr.ss_family) {
+ case AF_INET:
+ sptr = &env->sc_sock4;
+ break;
+ case AF_INET6:
+ sptr = &env->sc_sock6;
+ break;
+ default:
+ fatal("config_getsocket: socket af");
+ /* NOTREACHED */
+ }
+ if (*sptr == NULL)
+ *sptr = sock;
+
event_set(&sock->sock_ev, sock->sock_fd,
EV_READ|EV_PERSIST, cb, sock);
event_add(&sock->sock_ev, NULL);
diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h
index edbd6b0d17a..bc001a35d0e 100644
--- a/sbin/iked/iked.h
+++ b/sbin/iked/iked.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: iked.h,v 1.5 2010/06/11 12:47:18 reyk Exp $ */
+/* $OpenBSD: iked.h,v 1.6 2010/06/14 08:10:32 reyk Exp $ */
/* $vantronix: iked.h,v 1.61 2010/06/03 07:57:33 reyk Exp $ */
/*
@@ -292,6 +292,10 @@ struct iked_sa {
struct iked_sahdr sa_hdr;
u_int32_t sa_msgid;
+ int sa_type;
+#define IKED_SATYPE_LOOKUP 0 /* Used for lookup */
+#define IKED_SATYPE_LOCAL 1 /* Local SA */
+
struct iked_addr sa_peer;
struct iked_addr sa_local;
int sa_fd;
@@ -418,6 +422,9 @@ struct iked {
u_int8_t sc_certreqtype;
struct ibuf *sc_certreq;
+ struct iked_socket *sc_sock4;
+ struct iked_socket *sc_sock6;
+
struct control_sock sc_csock;
/* Event and signal handlers */
@@ -617,6 +624,9 @@ struct ibuf *
ikev2_msg_decrypt(struct iked *, struct iked_sa *,
struct ibuf *, struct ibuf *);
int ikev2_msg_integr(struct iked *, struct iked_sa *, struct ibuf *);
+int ikev2_msg_frompeer(struct iked_message *);
+struct iked_socket *
+ ikev2_msg_getsocket(struct iked *, int);
/* ikev2_pld.c */
int ikev2_pld_parse(struct iked *, struct ike_header *,
@@ -651,7 +661,7 @@ char *ca_x509_name(void *);
/* timer.c */
void timer_register_initiator(struct iked *,
- void (*)(struct iked *, struct iked_policy *));
+ int (*)(struct iked *, struct iked_policy *));
void timer_unregister_initiator(struct iked *);
/* proc.c */
diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c
index e7c5adfd4df..ef6291e2083 100644
--- a/sbin/iked/ikev2.c
+++ b/sbin/iked/ikev2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikev2.c,v 1.6 2010/06/11 12:47:18 reyk Exp $ */
+/* $OpenBSD: ikev2.c,v 1.7 2010/06/14 08:10:32 reyk Exp $ */
/* $vantronix: ikev2.c,v 1.101 2010/06/03 07:57:33 reyk Exp $ */
/*
@@ -57,7 +57,8 @@ struct iked_sa *
void ikev2_cb(int, short, void *);
void ikev2_recv(struct iked *, struct iked_message *);
-void ikev2_initiator(struct iked *, struct iked_policy *);
+
+int ikev2_init_ike_sa(struct iked *, struct iked_policy *);
int ikev2_resp_ike_sa_init(struct iked *, struct iked_message *);
int ikev2_resp_ike_auth(struct iked *, struct iked_sa *);
@@ -65,6 +66,7 @@ int ikev2_resp_ike_eap(struct iked *, struct iked_sa *, struct ibuf *);
int ikev2_resp_create_child_sa(struct iked *, struct iked_message *);
int ikev2_policy2id(struct iked_static_id *, struct iked_id *, int);
+int ikev2_sa_initiator(struct iked_sa *);
int ikev2_sa_keys(struct iked_sa *);
int ikev2_sa_tag(struct iked_sa *, struct iked_id *);
int ikev2_childsa_negotiate(struct iked *, struct iked_sa *,
@@ -111,7 +113,7 @@ ikev2_dispatch_parent(int fd, struct iked_proc *p, struct imsg *imsg)
if (env->sc_passive)
timer_unregister_initiator(env);
else
- timer_register_initiator(env, ikev2_initiator);
+ timer_register_initiator(env, ikev2_init_ike_sa);
return (0);
case IMSG_UDP_SOCKET:
return (config_getsocket(env, imsg, ikev2_msg_cb));
@@ -405,7 +407,7 @@ ikev2_recv(struct iked *env, struct iked_message *msg)
return;
}
- if (msg->msg_response)
+ if (!ikev2_msg_frompeer(msg))
return;
switch (hdr->ike_exchange) {
@@ -419,6 +421,12 @@ ikev2_recv(struct iked *env, struct iked_message *msg)
sa_state(env, sa, IKEV2_STATE_SA_INIT);
+ if ((sa->sa_rnonce =
+ ibuf_random(IKED_NONCE_SIZE)) == NULL) {
+ log_debug("%s: failed to get local nonce", __func__);
+ sa_free(env, sa);
+ return;
+ }
if ((ibuf_length(sa->sa_inonce) < IKED_NONCE_MIN) ||
(ibuf_length(sa->sa_rnonce) < IKED_NONCE_MIN)) {
log_debug("%s: invalid nonce", __func__);
@@ -431,6 +439,7 @@ ikev2_recv(struct iked *env, struct iked_message *msg)
return;
}
+
if (ikev2_policy2id(&msg->msg_policy->pol_localid,
&sa->sa_rid, 1) != 0) {
log_debug("%s: failed to get responder id", __func__);
@@ -471,11 +480,144 @@ ikev2_recv(struct iked *env, struct iked_message *msg)
sa_free(env, msg->msg_sa);
}
-void
-ikev2_initiator(struct iked *env, struct iked_policy *pol)
+int
+ikev2_init_ike_sa(struct iked *env, struct iked_policy *pol)
{
- /* XXX */
- log_debug("%s: not implemented", __func__);
+ struct iked_message req;
+ struct ike_header *hdr;
+ struct ikev2_payload *pld;
+ struct ikev2_keyexchange *ke;
+ struct ikev2_notify *n;
+ struct iked_sa *sa;
+ struct ibuf *buf;
+ struct group *group;
+ u_int8_t *ptr;
+ ssize_t len;
+ int ret = -1;
+ struct iked_socket *sock;
+ in_port_t port;
+
+ if ((sock = ikev2_msg_getsocket(env,
+ pol->pol_peer.ss_family)) == NULL)
+ return (-1);
+
+ /* Create a new initiator SA */
+ if ((sa = sa_new(env, 0, 0, 1, pol)) == NULL)
+ return (-1);
+
+ if (ikev2_sa_initiator(sa) == -1)
+ goto done;
+
+ if ((buf = ikev2_msg_init(env, &req,
+ &pol->pol_peer, pol->pol_peer.ss_len,
+ &pol->pol_local, pol->pol_local.ss_len, 0)) == NULL)
+ goto done;
+
+ /* Inherit the port from the 1st send socket */
+ port = htons(socket_getport(&sock->sock_addr));
+ (void)socket_af((struct sockaddr *)&req.msg_local, port);
+ (void)socket_af((struct sockaddr *)&req.msg_peer, port);
+
+ req.msg_fd = sock->sock_fd;
+ req.msg_sa = sa;
+
+ /* IKE header */
+ if ((hdr = ikev2_add_header(buf, sa, 0,
+ IKEV2_PAYLOAD_SA, IKEV2_EXCHANGE_IKE_SA_INIT,
+ IKEV2_FLAG_INITIATOR)) == NULL)
+ goto done;
+
+ /* SA payload */
+ if ((pld = ikev2_add_payload(buf)) == NULL)
+ goto done;
+ if ((len = ikev2_add_proposals(buf, &pol->pol_proposals,
+ IKEV2_SAPROTO_IKE)) == -1)
+ goto done;
+
+ if (ikev2_next_payload(pld, len, IKEV2_PAYLOAD_KE) == -1)
+ goto done;
+
+ /* KE payload */
+ if ((pld = ikev2_add_payload(buf)) == NULL)
+ goto done;
+ if ((ke = ibuf_advance(buf, sizeof(*ke))) == NULL)
+ goto done;
+ if ((group = sa->sa_dhgroup) == NULL) {
+ log_debug("%s: invalid dh", __func__);
+ goto done;
+ }
+ ke->kex_dhgroup = htobe16(group->id);
+ if (ikev2_add_buf(buf, sa->sa_dhiexchange) == -1)
+ goto done;
+ len = sizeof(*ke) + dh_getlen(group);
+
+ if (ikev2_next_payload(pld, len, IKEV2_PAYLOAD_NONCE) == -1)
+ goto done;
+
+ /* NONCE payload */
+ if ((pld = ikev2_add_payload(buf)) == NULL)
+ goto done;
+ if (ikev2_add_buf(buf, sa->sa_inonce) == -1)
+ goto done;
+ len = ibuf_size(sa->sa_inonce);
+
+ if ((env->sc_opts & IKED_OPT_NONATT) == 0) {
+ if (ikev2_next_payload(pld, len, IKEV2_PAYLOAD_NOTIFY) == -1)
+ goto done;
+
+ /* NAT-T notify payloads */
+ if ((pld = ikev2_add_payload(buf)) == NULL)
+ goto done;
+ if ((n = ibuf_advance(buf, sizeof(*n))) == NULL)
+ goto done;
+ n->n_type = htobe16(IKEV2_N_NAT_DETECTION_SOURCE_IP);
+ len = ikev2_nat_detection(&req, NULL, 0, 0, 0);
+ if ((ptr = ibuf_advance(buf, len)) == NULL)
+ goto done;
+ if ((len = ikev2_nat_detection(&req, ptr, len,
+ betoh16(n->n_type), 0)) == -1)
+ goto done;
+ len += sizeof(*n);
+
+ if (ikev2_next_payload(pld, len, IKEV2_PAYLOAD_NOTIFY) == -1)
+ goto done;
+
+ if ((pld = ikev2_add_payload(buf)) == NULL)
+ goto done;
+ if ((n = ibuf_advance(buf, sizeof(*n))) == NULL)
+ goto done;
+ n->n_type = htobe16(IKEV2_N_NAT_DETECTION_DESTINATION_IP);
+ len = ikev2_nat_detection(&req, NULL, 0, 0, 0);
+ if ((ptr = ibuf_advance(buf, len)) == NULL)
+ goto done;
+ if ((len = ikev2_nat_detection(&req, ptr, len,
+ betoh16(n->n_type), 0)) == -1)
+ goto done;
+ len += sizeof(*n);
+ }
+
+ if (ikev2_next_payload(pld, len, IKEV2_PAYLOAD_NONE) == -1)
+ goto done;
+
+ if (ikev2_set_header(hdr, ibuf_size(buf) - sizeof(*hdr)) == -1)
+ goto done;
+
+ (void)ikev2_pld_parse(env, hdr, &req, 0);
+
+ ibuf_release(sa->sa_1stmsg);
+ if ((sa->sa_1stmsg = ibuf_dup(buf)) == NULL) {
+ log_debug("%s: failed to copy 1st message", __func__);
+ goto done;
+ }
+
+ ret = ikev2_msg_send(env, req.msg_fd, &req);
+
+ done:
+ if (ret == -1)
+ sa_free(env, sa);
+ message_cleanup(env, &req);
+
+ return (ret);
}
int
@@ -1436,7 +1578,7 @@ ikev2_resp_create_child_sa(struct iked *env, struct iked_message *msg)
struct iked_sa *sa = msg->msg_sa;
struct iked_spi *rekey = &msg->msg_rekey;
- if (msg->msg_response)
+ if (!ikev2_msg_frompeer(msg))
return (0);
log_debug("%s: rekey %s spi %s", __func__,
@@ -1785,6 +1927,50 @@ ikev2_sa_negotiate(struct iked_sa *sa, struct iked_proposals *local,
}
int
+ikev2_sa_initiator(struct iked_sa *sa)
+{
+ struct iked_policy *pol = sa->sa_policy;
+ struct iked_transform *xform;
+ struct group *group;
+
+ if (sa->sa_dhgroup == NULL) {
+ if ((xform = config_findtransform(&pol->pol_proposals,
+ IKEV2_XFORMTYPE_DH)) == NULL) {
+ log_debug("%s: did not find dh transform", __func__);
+ return (-1);
+ }
+ if ((sa->sa_dhgroup =
+ group_get(xform->xform_id)) == NULL) {
+ log_debug("%s: invalid dh", __func__);
+ return (-1);
+ }
+ }
+ group = sa->sa_dhgroup;
+
+ if (!ibuf_length(sa->sa_dhiexchange)) {
+ if ((sa->sa_dhiexchange = ibuf_new(NULL,
+ dh_getlen(group))) == NULL) {
+ log_debug("%s: failed to alloc dh exchange", __func__);
+ return (-1);
+ }
+ if (dh_create_exchange(group, sa->sa_dhiexchange->buf) == -1) {
+ log_debug("%s: failed to get dh exchange", __func__);
+ return (-1);
+ }
+ }
+
+ if (!ibuf_length(sa->sa_inonce)) {
+ if ((sa->sa_inonce =
+ ibuf_random(IKED_NONCE_SIZE)) == NULL) {
+ log_debug("%s: failed to get local nonce", __func__);
+ return (-1);
+ }
+ }
+
+ return (0);
+}
+
+int
ikev2_sa_keys(struct iked_sa *sa)
{
struct iked_transform *xform;
diff --git a/sbin/iked/ikev2_msg.c b/sbin/iked/ikev2_msg.c
index 85d82138539..115f2a459d2 100644
--- a/sbin/iked/ikev2_msg.c
+++ b/sbin/iked/ikev2_msg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikev2_msg.c,v 1.1 2010/06/10 08:29:47 reyk Exp $ */
+/* $OpenBSD: ikev2_msg.c,v 1.2 2010/06/14 08:10:32 reyk Exp $ */
/* $vantronix: ikev2.c,v 1.101 2010/06/03 07:57:33 reyk Exp $ */
/*
@@ -786,3 +786,37 @@ ikev2_msg_authsign(struct iked *env, struct iked_sa *sa,
return (ret);
}
+
+int
+ikev2_msg_frompeer(struct iked_message *msg)
+{
+ struct iked_sa *sa = msg->msg_sa;
+ struct ike_header *hdr;
+
+ if (sa == NULL ||
+ (hdr = ibuf_seek(msg->msg_data, 0, sizeof(*hdr))) == NULL)
+ return (0);
+
+ if (!sa->sa_hdr.sh_initiator &&
+ (hdr->ike_flags & IKEV2_FLAG_INITIATOR))
+ return (1);
+ else if (sa->sa_hdr.sh_initiator &&
+ (hdr->ike_flags & IKEV2_FLAG_INITIATOR) == 0)
+ return (1);
+
+ return (0);
+}
+
+struct iked_socket *
+ikev2_msg_getsocket(struct iked *env, int af)
+{
+ switch (af) {
+ case AF_INET:
+ return (env->sc_sock4);
+ case AF_INET6:
+ return (env->sc_sock6);
+ }
+
+ log_debug("%s: af socket %d not available", __func__, af);
+ return (NULL);
+}
diff --git a/sbin/iked/ikev2_pld.c b/sbin/iked/ikev2_pld.c
index e75d81a6c91..07a241debfb 100644
--- a/sbin/iked/ikev2_pld.c
+++ b/sbin/iked/ikev2_pld.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikev2_pld.c,v 1.1 2010/06/10 08:29:47 reyk Exp $ */
+/* $OpenBSD: ikev2_pld.c,v 1.2 2010/06/14 08:10:32 reyk Exp $ */
/* $vantronix: ikev2.c,v 1.101 2010/06/03 07:57:33 reyk Exp $ */
/*
@@ -199,7 +199,7 @@ ikev2_pld_payloads(struct iked *env, struct iked_message *msg,
break;
}
- if (ret != 0 && !msg->msg_response) {
+ if (ret != 0 && ikev2_msg_frompeer(msg)) {
(void)ikev2_send_informational(env, msg);
return (-1);
}
@@ -259,7 +259,7 @@ ikev2_pld_sa(struct iked *env, struct ikev2_payload *pld,
print_map(sap.sap_protoid, ikev2_saproto_map), sap.sap_spisize,
sap.sap_transforms, print_spi(spi, sap.sap_spisize));
- if (!msg->msg_response) {
+ if (ikev2_msg_frompeer(msg)) {
if ((msg->msg_prop = config_add_proposal(&msg->msg_proposals,
sap.sap_proposalnr, sap.sap_protoid)) == NULL) {
log_debug("%s: invalid proposal", __func__);
@@ -278,7 +278,7 @@ ikev2_pld_sa(struct iked *env, struct ikev2_payload *pld,
return (-1);
}
- if (msg->msg_response)
+ if (!ikev2_msg_frompeer(msg))
return (0);
/* XXX we need a better way to get this */
@@ -345,7 +345,7 @@ ikev2_pld_xform(struct iked *env, struct ikev2_sa_proposal *sap,
ikev2_pld_attr(env, &xfrm, msg, offset + sizeof(xfrm),
betoh16(xfrm.xfrm_length) - sizeof(xfrm));
- if (!msg->msg_response) {
+ if (ikev2_msg_frompeer(msg)) {
if (config_add_transform(msg->msg_prop, xfrm.xfrm_type,
betoh16(xfrm.xfrm_id), msg->msg_attrlength,
msg->msg_attrlength) == NULL) {
@@ -422,7 +422,7 @@ ikev2_pld_ke(struct iked *env, struct ikev2_payload *pld,
print_hex(buf, 0, len);
- if (!msg->msg_response) {
+ if (ikev2_msg_frompeer(msg)) {
if ((msg->msg_sa->sa_dhiexchange =
ibuf_new(buf, len)) == NULL) {
log_debug("%s: failed to get exchange", __func__);
@@ -465,7 +465,7 @@ ikev2_pld_id(struct iked *env, struct ikev2_payload *pld,
log_debug("%s: id %s/%s length %d",
__func__, print_map(id.id_type, ikev2_id_map), idstr, len);
- if (msg->msg_response) {
+ if (!ikev2_msg_frompeer(msg)) {
ibuf_release(idb.id_buf);
return (0);
}
@@ -516,7 +516,7 @@ ikev2_pld_cert(struct iked *env, struct ikev2_payload *pld,
print_hex(buf, 0, len);
- if (msg->msg_response)
+ if (!ikev2_msg_frompeer(msg))
return (0);
if (!sa->sa_hdr.sh_initiator && !msg->msg_response) {
@@ -559,7 +559,7 @@ ikev2_pld_certreq(struct iked *env, struct ikev2_payload *pld,
__func__, print_map(cert.cert_type, ikev2_cert_map), len);
print_hex(buf, 0, len);
- if (msg->msg_response)
+ if (!ikev2_msg_frompeer(msg))
return (0);
if (!len || (len % SHA_DIGEST_LENGTH) != 0) {
@@ -604,7 +604,7 @@ ikev2_pld_auth(struct iked *env, struct ikev2_payload *pld,
print_hex(buf, 0, len);
- if (msg->msg_response)
+ if (!ikev2_msg_frompeer(msg))
return (0);
memcpy(&ikeauth, &policy->pol_auth, sizeof(ikeauth));
@@ -672,35 +672,26 @@ ikev2_pld_nonce(struct iked *env, struct ikev2_payload *pld,
u_int8_t *buf;
u_int8_t *msgbuf = ibuf_data(msg->msg_data);
struct iked_sa *sa = msg->msg_sa;
- struct ibuf *localnonce, *peernonce;
+ struct ibuf *peernonce;
buf = msgbuf + offset;
len = betoh16(pld->pld_length) - sizeof(*pld);
print_hex(buf, 0, len);
- if (!msg->msg_response) {
+ if (ikev2_msg_frompeer(msg)) {
if ((peernonce = ibuf_new(buf, len)) == NULL) {
log_debug("%s: failed to get peer nonce", __func__);
return (-1);
}
- if ((localnonce =
- ibuf_random(IKED_NONCE_SIZE)) == NULL) {
- log_debug("%s: failed to get local nonce", __func__);
- ibuf_release(peernonce);
- return (-1);
- }
-
- ibuf_release(sa->sa_inonce);
- ibuf_release(sa->sa_rnonce);
- log_debug("%s: updating nonces", __func__);
+ log_debug("%s: updating peer nonce", __func__);
if (sa->sa_hdr.sh_initiator) {
- sa->sa_inonce = localnonce;
+ ibuf_release(sa->sa_rnonce);
sa->sa_rnonce = peernonce;
} else {
+ ibuf_release(sa->sa_inonce);
sa->sa_inonce = peernonce;
- sa->sa_rnonce = localnonce;
}
}
@@ -827,7 +818,7 @@ ikev2_pld_delete(struct iked *env, struct ikev2_payload *pld,
case 8:
break;
default:
- if (!msg->msg_response &&
+ if (ikev2_msg_frompeer(msg) &&
del->del_protoid == IKEV2_SAPROTO_IKE) {
sa_state(env, sa, IKEV2_STATE_DELETE);
return (0);
@@ -842,7 +833,7 @@ ikev2_pld_delete(struct iked *env, struct ikev2_payload *pld,
return (-1);
}
- if (!msg->msg_response &&
+ if (ikev2_msg_frompeer(msg) &&
(localspi = calloc(cnt, sizeof(u_int64_t))) == NULL) {
log_warn("%s", __func__);
return (-1);
@@ -860,7 +851,7 @@ ikev2_pld_delete(struct iked *env, struct ikev2_payload *pld,
spi = betoh64(spi64);
break;
}
- if (msg->msg_response) {
+ if (!ikev2_msg_frompeer(msg)) {
log_debug("%s: spi %s", __func__, print_spi(spi, sz));
continue;
}
@@ -872,7 +863,7 @@ ikev2_pld_delete(struct iked *env, struct ikev2_payload *pld,
found++;
}
- if (msg->msg_response)
+ if (!ikev2_msg_frompeer(msg))
return (0);
if ((resp = ibuf_static()) == NULL)
@@ -1066,7 +1057,7 @@ ikev2_pld_cp(struct iked *env, struct ikev2_payload *pld,
i += betoh16(cfg->cfg_length) + sizeof(*cfg);
}
- if (msg->msg_response)
+ if (!ikev2_msg_frompeer(msg))
return (0);
if (sa)
diff --git a/sbin/iked/policy.c b/sbin/iked/policy.c
index c0d80aefe57..a17ff2938ad 100644
--- a/sbin/iked/policy.c
+++ b/sbin/iked/policy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: policy.c,v 1.3 2010/06/10 12:06:34 reyk Exp $ */
+/* $OpenBSD: policy.c,v 1.4 2010/06/14 08:10:32 reyk Exp $ */
/* $vantronix: policy.c,v 1.29 2010/05/28 15:34:35 reyk Exp $ */
/*
@@ -173,7 +173,8 @@ sa_new(struct iked *env, u_int64_t ispi, u_int64_t rspi,
{
struct iked_sa *sa;
- if ((sa = sa_lookup(env, ispi, rspi, initiator)) == NULL) {
+ if ((ispi == 0 && rspi == 0) ||
+ (sa = sa_lookup(env, ispi, rspi, initiator)) == NULL) {
/* Create new SA */
sa = config_new_sa(env, initiator);
}
@@ -181,20 +182,22 @@ sa_new(struct iked *env, u_int64_t ispi, u_int64_t rspi,
log_debug("%s: failed to get sa", __func__);
return (NULL);
}
- if (sa->sa_policy == NULL) {
+ if (sa->sa_policy == NULL)
sa->sa_policy = policy;
+
+ if (!initiator) {
+ sa->sa_staterequire = IKED_REQ_AUTH|IKED_REQ_SA;
+ if (policy != NULL && policy->pol_auth.auth_eap) {
+ sa->sa_staterequire |= IKED_REQ_CERT;
+ } else if (policy != NULL && policy->pol_auth.auth_method !=
+ IKEV2_AUTH_SHARED_KEY_MIC) {
+ sa->sa_staterequire |= IKED_REQ_VALID|IKED_REQ_CERT;
+ }
+ if (sa->sa_hdr.sh_ispi == 0)
+ sa->sa_hdr.sh_ispi = ispi;
+ if (sa->sa_hdr.sh_rspi == 0)
+ sa->sa_hdr.sh_rspi = rspi;
}
- sa->sa_staterequire = IKED_REQ_AUTH|IKED_REQ_SA;
- if (policy != NULL && policy->pol_auth.auth_eap) {
- sa->sa_staterequire |= IKED_REQ_CERT;
- } else if (policy != NULL &&
- policy->pol_auth.auth_method != IKEV2_AUTH_SHARED_KEY_MIC) {
- sa->sa_staterequire |= IKED_REQ_VALID|IKED_REQ_CERT;
- }
- if (sa->sa_hdr.sh_ispi == 0)
- sa->sa_hdr.sh_ispi = ispi;
- if (sa->sa_hdr.sh_rspi == 0)
- sa->sa_hdr.sh_rspi = rspi;
/* Re-insert node into the tree */
(void)RB_REMOVE(iked_sas, &env->sc_sas, sa);
@@ -268,12 +271,19 @@ sa_lookup(struct iked *env, u_int64_t ispi, u_int64_t rspi,
if ((sa = RB_FIND(iked_sas, &env->sc_sas, &key)) != NULL)
gettimeofday(&sa->sa_timeused, NULL);
+
return (sa);
}
static __inline int
sa_cmp(struct iked_sa *a, struct iked_sa *b)
{
+ log_debug("%s: ispi %s rspi %s <-> ispi %s rspi %s", __func__,
+ print_spi(a->sa_hdr.sh_ispi, 8),
+ print_spi(a->sa_hdr.sh_rspi, 8),
+ print_spi(b->sa_hdr.sh_ispi, 8),
+ print_spi(b->sa_hdr.sh_rspi, 8));
+
if (a->sa_hdr.sh_initiator != b->sa_hdr.sh_initiator)
return (-2);
@@ -282,8 +292,9 @@ sa_cmp(struct iked_sa *a, struct iked_sa *b)
if (a->sa_hdr.sh_ispi < b->sa_hdr.sh_ispi)
return (1);
- /* Responder SPI is not yet set */
- if (a->sa_hdr.sh_rspi == 0)
+ /* Responder SPI is not yet set in the local IKE SADB */
+ if ((b->sa_type == IKED_SATYPE_LOCAL && b->sa_hdr.sh_rspi == 0) ||
+ (a->sa_type == IKED_SATYPE_LOCAL && a->sa_hdr.sh_rspi == 0))
return (0);
if (a->sa_hdr.sh_rspi > b->sa_hdr.sh_rspi)
diff --git a/sbin/iked/timer.c b/sbin/iked/timer.c
index 44a5ce7a9ec..2664ed41251 100644
--- a/sbin/iked/timer.c
+++ b/sbin/iked/timer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: timer.c,v 1.1 2010/06/11 12:47:18 reyk Exp $ */
+/* $OpenBSD: timer.c,v 1.2 2010/06/14 08:10:32 reyk Exp $ */
/*
* Copyright (c) 2010 Reyk Floeter <reyk@vantronix.net>
@@ -39,7 +39,7 @@ struct timer_cbarg {
struct timeval tmr_first;
struct timeval tmr_last;
struct timeval tmr_tv;
- void (*tmr_initcb)(struct iked *, struct iked_policy *);
+ int (*tmr_initcb)(struct iked *, struct iked_policy *);
} timer_initiator;
void timer_initiator_cb(int, short, void *);
@@ -49,7 +49,7 @@ void timer_initiator_cb(int, short, void *);
void
timer_register_initiator(struct iked *env,
- void (*cb)(struct iked *, struct iked_policy *))
+ int (*cb)(struct iked *, struct iked_policy *))
{
struct timer_cbarg *tmr;
@@ -102,8 +102,10 @@ timer_initiator_cb(int fd, short event, void *arg)
log_debug("%s: initiating \"%s\"", __func__, pol->pol_name);
- if (tmr->tmr_initcb != NULL)
- tmr->tmr_initcb(env, pol);
+ if (tmr->tmr_initcb != NULL) {
+ /* Ignore error but what should we do on failure? */
+ (void)tmr->tmr_initcb(env, pol);
+ }
}
tmr->tmr_tv.tv_sec = IKED_TIMER_INITIATOR_INTERVAL;