summaryrefslogtreecommitdiff
path: root/sbin/isakmpd
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/isakmpd')
-rw-r--r--sbin/isakmpd/exchange.c23
-rw-r--r--sbin/isakmpd/sa.h6
-rw-r--r--sbin/isakmpd/transport.c19
-rw-r--r--sbin/isakmpd/udp.c35
-rw-r--r--sbin/isakmpd/udp_encap.c11
-rw-r--r--sbin/isakmpd/virtual.c95
6 files changed, 109 insertions, 80 deletions
diff --git a/sbin/isakmpd/exchange.c b/sbin/isakmpd/exchange.c
index 28f48df08e7..b5d232f9c95 100644
--- a/sbin/isakmpd/exchange.c
+++ b/sbin/isakmpd/exchange.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: exchange.c,v 1.98 2004/06/20 17:17:34 ho Exp $ */
+/* $OpenBSD: exchange.c,v 1.99 2004/06/21 13:09:00 ho Exp $ */
/* $EOM: exchange.c,v 1.143 2000/12/04 00:02:25 angelos Exp $ */
/*
@@ -954,6 +954,12 @@ exchange_establish_p2(struct sa *isakmp_sa, u_int8_t type, char *name,
memcpy(exchange->cookies, isakmp_sa->cookies, ISAKMP_HDR_COOKIES_LEN);
getrandom(exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN);
exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
+#if defined (USE_NAT_TRAVERSAL)
+ if (isakmp_sa->flags & SA_FLAG_NAT_T_ENABLE)
+ exchange->flags |= EXCHANGE_FLAG_NAT_T_ENABLE;
+ if (isakmp_sa->flags & SA_FLAG_NAT_T_KEEPALIVE)
+ exchange->flags |= EXCHANGE_FLAG_NAT_T_KEEPALIVE;
+#endif
exchange_enter(exchange);
#ifdef USE_DEBUG
exchange_dump("exchange_establish_p2", exchange);
@@ -1141,6 +1147,12 @@ exchange_setup_p2(struct message *msg, u_int8_t doi)
GET_ISAKMP_HDR_RCOOKIE(buf,
exchange->cookies + ISAKMP_HDR_ICOOKIE_LEN);
GET_ISAKMP_HDR_MESSAGE_ID(buf, exchange->message_id);
+#if defined (USE_NAT_TRAVERSAL)
+ if (msg->isakmp_sa->flags & SA_FLAG_NAT_T_ENABLE)
+ exchange->flags |= EXCHANGE_FLAG_NAT_T_ENABLE;
+ if (msg->isakmp_sa->flags & SA_FLAG_NAT_T_KEEPALIVE)
+ exchange->flags |= EXCHANGE_FLAG_NAT_T_KEEPALIVE;
+#endif
exchange_enter(exchange);
#ifdef USE_DEBUG
exchange_dump("exchange_setup_p2", exchange);
@@ -1468,12 +1480,19 @@ exchange_finalize(struct message *msg)
else
id_doi = "<no doi>";
- if (msg->isakmp_sa && msg->isakmp_sa->transport)
+ if (msg->isakmp_sa->transport)
id_trp =
msg->isakmp_sa->transport->vtbl->decode_ids(msg->isakmp_sa->transport);
else
id_trp = "<no transport>";
+#if defined (USE_NAT_TRAVERSAL)
+ if (exchange->flags & EXCHANGE_FLAG_NAT_T_ENABLE)
+ msg->isakmp_sa->flags |= SA_FLAG_NAT_T_ENABLE;
+ if (exchange->flags & EXCHANGE_FLAG_NAT_T_KEEPALIVE)
+ msg->isakmp_sa->flags |= SA_FLAG_NAT_T_KEEPALIVE;
+#endif
+
LOG_DBG((LOG_EXCHANGE, 10,
"exchange_finalize: phase 1 done: %s, %s", id_doi,
id_trp));
diff --git a/sbin/isakmpd/sa.h b/sbin/isakmpd/sa.h
index ee3efd00559..1457d0ecc88 100644
--- a/sbin/isakmpd/sa.h
+++ b/sbin/isakmpd/sa.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sa.h,v 1.38 2004/06/20 15:20:07 ho Exp $ */
+/* $OpenBSD: sa.h,v 1.39 2004/06/21 13:09:00 ho Exp $ */
/* $EOM: sa.h,v 1.58 2000/10/10 12:39:01 provos Exp $ */
/*
@@ -236,6 +236,10 @@ struct sa {
/* This SA flag indicates if we should do DPD with the phase 1 SA peer. */
#define SA_FLAG_DPD 0x80
+/* NAT-T encapsulation state. Kept in isakmp_sa for the new p2 exchange. */
+#define SA_FLAG_NAT_T_ENABLE 0x100
+#define SA_FLAG_NAT_T_KEEPALIVE 0x200
+
extern void proto_free(struct proto * proto);
extern int sa_add_transform(struct sa *, struct payload *, int,
struct proto **);
diff --git a/sbin/isakmpd/transport.c b/sbin/isakmpd/transport.c
index 989d6a5ebaa..749468b01bb 100644
--- a/sbin/isakmpd/transport.c
+++ b/sbin/isakmpd/transport.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: transport.c,v 1.27 2004/06/20 15:24:05 ho Exp $ */
+/* $OpenBSD: transport.c,v 1.28 2004/06/21 13:09:00 ho Exp $ */
/* $EOM: transport.c,v 1.43 2000/10/10 12:36:39 provos Exp $ */
/*
@@ -75,7 +75,8 @@ transport_init(void)
void
transport_setup(struct transport *t, int toplevel)
{
- LOG_DBG((LOG_TRANSPORT, 70, "transport_setup: adding %p", t));
+ LOG_DBG((LOG_TRANSPORT, 70, "transport_setup: adding %p%s", t,
+ toplevel ? " (virtual)" : ""));
if (toplevel == 0)
LIST_INSERT_HEAD(&transport_list, t, link);
else {
@@ -199,7 +200,7 @@ transport_fd_set(fd_set * fds)
for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link))
if (t->virtual->flags & TRANSPORT_LISTEN) {
- n = t->virtual->vtbl->fd_set(t->virtual, fds, 1);
+ n = t->vtbl->fd_set(t, fds, 1);
if (n > max)
max = n;
@@ -226,7 +227,7 @@ transport_pending_wfd_set(fd_set * fds)
for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link)) {
if (TAILQ_FIRST(&t->virtual->sendq) ||
TAILQ_FIRST(&t->virtual->prio_sendq)) {
- n = t->virtual->vtbl->fd_set(t->virtual, fds, 1);
+ n = t->vtbl->fd_set(t, fds, 1);
LOG_DBG((LOG_TRANSPORT,95,"transport_pending_wfd_set: "
"transport %p (virtual %p) fd %d pending", t,
t->virtual, n));
@@ -248,9 +249,9 @@ transport_handle_messages(fd_set *fds)
for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link)) {
if ((t->flags & TRANSPORT_LISTEN) &&
- (*t->virtual->vtbl->fd_isset)(t->virtual, fds)) {
- (*t->virtual->vtbl->handle_message)(t->virtual);
- (*t->virtual->vtbl->fd_set)(t->virtual, fds, 0);
+ (*t->vtbl->fd_isset)(t, fds)) {
+ (*t->virtual->vtbl->handle_message)(t);
+ (*t->vtbl->fd_set)(t, fds, 0);
}
}
}
@@ -285,9 +286,9 @@ transport_send_messages(fd_set * fds)
for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link)) {
if ((TAILQ_FIRST(&t->virtual->sendq) ||
TAILQ_FIRST(&t->virtual->prio_sendq)) &&
- t->virtual->vtbl->fd_isset(t->virtual, fds)) {
+ t->vtbl->fd_isset(t, fds)) {
/* Remove fd bit. */
- t->virtual->vtbl->fd_set(t->virtual, fds, 0);
+ t->vtbl->fd_set(t, fds, 0);
/* Prefer a message from the prioritized sendq. */
if (TAILQ_FIRST(&t->virtual->prio_sendq)) {
diff --git a/sbin/isakmpd/udp.c b/sbin/isakmpd/udp.c
index cee6630c6b6..2f3c53fa20f 100644
--- a/sbin/isakmpd/udp.c
+++ b/sbin/isakmpd/udp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp.c,v 1.75 2004/06/20 15:24:05 ho Exp $ */
+/* $OpenBSD: udp.c,v 1.76 2004/06/21 13:09:01 ho Exp $ */
/* $EOM: udp.c,v 1.57 2001/01/26 10:09:57 niklas Exp $ */
/*
@@ -71,9 +71,11 @@
/* These are reused by udp_encap.c, thus not 'static' here. */
struct transport *udp_clone(struct transport *, struct sockaddr *);
-void udp_get_dst(struct transport *, struct sockaddr **);
-void udp_get_src(struct transport *, struct sockaddr **);
-char *udp_decode_ids(struct transport *);
+int udp_fd_set(struct transport *, fd_set *, int);
+int udp_fd_isset(struct transport *, fd_set *);
+void udp_get_dst(struct transport *, struct sockaddr **);
+void udp_get_src(struct transport *, struct sockaddr **);
+char *udp_decode_ids(struct transport *);
static struct transport *udp_create(char *);
static void udp_remove(struct transport *);
@@ -91,8 +93,8 @@ static struct transport_vtbl udp_transport_vtbl = {
0,
udp_remove,
udp_report,
- 0,
- 0,
+ udp_fd_set,
+ udp_fd_isset,
udp_handle_message,
udp_send_message,
udp_get_dst,
@@ -477,6 +479,27 @@ udp_send_message(struct message *msg, struct transport *t)
return 0;
}
+int
+udp_fd_set(struct transport *t, fd_set *fds, int bit)
+{
+ struct udp_transport *u = (struct udp_transport *)t;
+
+ if (bit)
+ FD_SET(u->s, fds);
+ else
+ FD_CLR(u->s, fds);
+
+ return u->s + 1;
+}
+
+int
+udp_fd_isset(struct transport *t, fd_set *fds)
+{
+ struct udp_transport *u = (struct udp_transport *)t;
+
+ return FD_ISSET(u->s, fds);
+}
+
/*
* Get transport T's peer address and stuff it into the sockaddr pointed
* to by DST.
diff --git a/sbin/isakmpd/udp_encap.c b/sbin/isakmpd/udp_encap.c
index aa5ba003726..d6cebf473f5 100644
--- a/sbin/isakmpd/udp_encap.c
+++ b/sbin/isakmpd/udp_encap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_encap.c,v 1.1 2004/06/20 15:24:05 ho Exp $ */
+/* $OpenBSD: udp_encap.c,v 1.2 2004/06/21 13:09:01 ho Exp $ */
/*
* Copyright (c) 1998, 1999, 2001 Niklas Hallqvist. All rights reserved.
@@ -68,6 +68,8 @@
/* Reused, from udp.c */
struct transport *udp_clone (struct transport *, struct sockaddr *);
+int udp_fd_set(struct transport *, fd_set *, int);
+int udp_fd_isset(struct transport *, fd_set *);
void udp_get_dst (struct transport *, struct sockaddr **);
void udp_get_src (struct transport *, struct sockaddr **);
char *udp_decode_ids (struct transport *);
@@ -86,8 +88,8 @@ static struct transport_vtbl udp_encap_transport_vtbl = {
0,
udp_encap_remove,
udp_encap_report,
- 0,
- 0,
+ udp_fd_set,
+ udp_fd_isset,
udp_encap_handle_message,
udp_encap_send_message,
udp_get_dst,
@@ -435,8 +437,7 @@ udp_encap_send_message(struct message *msg, struct transport *t)
}
new_iov[0].iov_base = &marker;
new_iov[0].iov_len = IPSEC_SPI_SIZE;
- memcpy (new_iov + sizeof *new_iov, msg->iov,
- msg->iovlen * sizeof *new_iov);
+ memcpy (new_iov + 1, msg->iov, msg->iovlen * sizeof *new_iov);
/*
* Sending on connected sockets requires that no destination address is
diff --git a/sbin/isakmpd/virtual.c b/sbin/isakmpd/virtual.c
index 5bcb2d76c06..00a44ad81fd 100644
--- a/sbin/isakmpd/virtual.c
+++ b/sbin/isakmpd/virtual.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: virtual.c,v 1.1 2004/06/20 15:24:05 ho Exp $ */
+/* $OpenBSD: virtual.c,v 1.2 2004/06/21 13:09:01 ho Exp $ */
/*
* Copyright (c) 2004 Håkan Olsson. All rights reserved.
@@ -60,8 +60,6 @@ static int virtual_bind_if(char *, struct sockaddr *, void *);
static struct transport *virtual_clone(struct transport *, struct sockaddr *);
static struct transport *virtual_create(char *);
static char *virtual_decode_ids (struct transport *);
-static int virtual_fd_set(struct transport *, fd_set *, int);
-static int virtual_fd_isset(struct transport *, fd_set *);
static void virtual_get_dst(struct transport *,
struct sockaddr **);
static struct msg_head *virtual_get_queue(struct message *);
@@ -80,8 +78,8 @@ static struct transport_vtbl virtual_transport_vtbl = {
virtual_reinit,
virtual_remove,
virtual_report,
- virtual_fd_set,
- virtual_fd_isset,
+ 0,
+ 0,
virtual_handle_message,
virtual_send_message,
virtual_get_dst,
@@ -249,6 +247,8 @@ virtual_bind(const struct sockaddr *addr)
sockaddr_set_port((struct sockaddr *)&tmp_sa, (in_port_t)lport);
v->main = udp_bind((struct sockaddr *)&tmp_sa);
+ if (!v->main)
+ return 0;
((struct transport *)v->main)->virtual = (struct transport *)v;
#if defined (USE_NAT_TRAVERSAL)
@@ -269,6 +269,8 @@ virtual_bind(const struct sockaddr *addr)
sockaddr_set_port((struct sockaddr *)&tmp_sa, (in_port_t)lport);
v->encap = udp_encap_bind((struct sockaddr *)&tmp_sa);
+ if (!v->encap)
+ return 0;
((struct transport *)v->encap)->virtual = (struct transport *)v;
#endif
v->encap_is_active = 0;
@@ -493,25 +495,32 @@ virtual_clone(struct transport *vt, struct sockaddr *raddr)
memcpy(v2, v, sizeof *v);
- if (v->encap_is_active) {
- v2->main = 0;
- v2->encap = v->encap->vtbl->clone(v->encap, raddr);
- v2->encap->virtual = (struct transport *)v2;
- } else {
+ if (v->encap_is_active)
+ v2->main = 0; /* No need to clone this. */
+ else {
v2->main = v->main->vtbl->clone(v->main, raddr);
v2->main->virtual = (struct transport *)v2;
- v2->encap = 0;
}
- LOG_DBG((LOG_TRANSPORT, 50, "virtual_clone: old %p new %p (->%s %p)",
- v, t, v->encap_is_active ? "encap" : "main",
+#if defined (USE_NAT_TRAVERSAL)
+ /* XXX fix strtol() call */
+ sockaddr_set_port(raddr, udp_encap_default_port ?
+ strtol(udp_encap_default_port, NULL, 10) : UDP_ENCAP_DEFAULT_PORT);
+ v2->encap = v->encap->vtbl->clone(v->encap, raddr);
+ v2->encap->virtual = (struct transport *)v2;
+#endif
+ LOG_DBG((LOG_TRANSPORT, 50, "virtual_clone: old %p new %p (%s is %p)",
+ v, t, v->encap_is_active ? "encap" : "main",
v->encap_is_active ? v2->encap : v2->main));
t->flags &= ~TRANSPORT_LISTEN;
transport_setup(t, 1);
transport_reference(t);
- transport_reference(v->encap_is_active ? v2->encap : v2->main);
-
+ if (v2->main)
+ transport_reference(v2->main);
+ if (v2->encap)
+ transport_reference(v2->encap);
+
return t;
}
@@ -583,9 +592,8 @@ virtual_report(struct transport *t)
static void
virtual_handle_message(struct transport *t)
{
- struct virtual_transport *v = (struct virtual_transport *)t;
-
- if (t == default_transport || t == default_transport6) {
+ if (t->virtual == default_transport ||
+ t->virtual == default_transport6) {
/* XXX drain pending message. See udp_handle_message(). */
virtual_reinit();
@@ -598,10 +606,7 @@ virtual_handle_message(struct transport *t)
return;
}
- if (v->encap_is_active)
- v->encap->vtbl->handle_message(v->encap);
- else
- v->main->vtbl->handle_message(v->main);
+ t->vtbl->handle_message(t);
}
static int
@@ -616,10 +621,19 @@ virtual_send_message(struct message *msg, struct transport *t)
"transport %p != NULL", t);
#if defined (USE_NAT_TRAVERSAL)
+ /*
+ * Activate NAT-T Encapsulation if
+ * - the exchange says we can, and
+ * - in ID_PROT, after step 4 (draft-ietf-ipsec-nat-t-ike-03), or
+ * - in other exchange (Aggressive, ), asap
+ * XXX ISAKMP_EXCH_BASE etc?
+ */
if (v->encap_is_active == 0 &&
- (msg->exchange->flags & EXCHANGE_FLAG_NAT_T_ENABLE)) {
+ (msg->exchange->flags & EXCHANGE_FLAG_NAT_T_ENABLE) &&
+ (msg->exchange->type != ISAKMP_EXCH_ID_PROT ||
+ msg->exchange->step > 4)) {
LOG_DBG((LOG_MESSAGE, 10, "virtual_send_message: "
- "switching to ENCAP"));
+ "enabling NAT-T encapsulation for this exchange"));
v->encap_is_active++;
}
#endif
@@ -630,39 +644,6 @@ virtual_send_message(struct message *msg, struct transport *t)
return v->main->vtbl->send_message(msg, v->main);
}
-static int
-virtual_fd_set(struct transport *t, fd_set *fds, int bit)
-{
- struct virtual_transport *v = (struct virtual_transport *)t;
- struct udp_transport *u;
-
- if (v->encap_is_active)
- u = (struct udp_transport *)v->encap;
- else
- u = (struct udp_transport *)v->main;
-
- if (bit)
- FD_SET(u->s, fds);
- else
- FD_CLR(u->s, fds);
-
- return u->s + 1;
-}
-
-static int
-virtual_fd_isset(struct transport *t, fd_set *fds)
-{
- struct virtual_transport *v = (struct virtual_transport *)t;
- struct udp_transport *u;
-
- if (v->encap_is_active)
- u = (struct udp_transport *)v->encap;
- else
- u = (struct udp_transport *)v->main;
-
- return FD_ISSET(u->s, fds);
-}
-
static void
virtual_get_src(struct transport *t, struct sockaddr **s)
{