summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorAngelos D. Keromytis <angelos@cvs.openbsd.org>2001-01-10 19:48:30 +0000
committerAngelos D. Keromytis <angelos@cvs.openbsd.org>2001-01-10 19:48:30 +0000
commit57574fb81882b09d5b77ce181f3f3ff6ddfa8eed (patch)
tree5185271d1f94a0bf535e39c1689b46d963274a8a /sbin
parent83ed0c1e65a43f3b626d608f167fd60a4657150d (diff)
Handle DELETE payloads (delete the relevant IPsec SAs) -- problem
reported, patches tested, and feedback provided by newsham@lava.net
Diffstat (limited to 'sbin')
-rw-r--r--sbin/isakmpd/ipsec.c64
1 files changed, 60 insertions, 4 deletions
diff --git a/sbin/isakmpd/ipsec.c b/sbin/isakmpd/ipsec.c
index d3141145314..917ab8590b7 100644
--- a/sbin/isakmpd/ipsec.c
+++ b/sbin/isakmpd/ipsec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsec.c,v 1.32 2000/12/12 01:45:31 niklas Exp $ */
+/* $OpenBSD: ipsec.c,v 1.33 2001/01/10 19:48:29 angelos Exp $ */
/* $EOM: ipsec.c,v 1.143 2000/12/11 23:57:42 niklas Exp $ */
/*
@@ -1296,14 +1296,71 @@ int
ipsec_handle_leftover_payload (struct message *msg, u_int8_t type,
struct payload *payload)
{
+ u_int32_t spisz, nspis, *spis;
struct sockaddr *dst;
socklen_t dstlen;
+ int flag = 0, i;
+ u_int8_t proto;
struct sa *sa;
- int flag = 0;
- /* So far, the only thing we handle is an INITIAL-CONTACT NOTIFY. */
switch (type)
{
+ case ISAKMP_PAYLOAD_DELETE:
+ proto = GET_ISAKMP_DELETE_PROTO (payload->p);
+ nspis = GET_ISAKMP_DELETE_NSPIS (payload->p);
+ spisz = GET_ISAKMP_DELETE_SPI_SZ (payload->p);
+
+ if (spisz != sizeof (u_int32_t))
+ {
+ LOG_DBG ((LOG_SA, 40,
+ "ipsec_handle_leftover_payload: SPI size %d in DELETE "
+ "payload unsupported", spisz));
+ return -1;
+ }
+
+ if (nspis == 0)
+ {
+ LOG_DBG ((LOG_SA, 40, "ipsec_handle_leftover_payload: message "
+ "specified zero SPIs, ignoring"));
+ return -1;
+ }
+
+ spis = (u_int32_t *) malloc (nspis * spisz);
+ if (spis == NULL)
+ {
+ LOG_DBG ((LOG_SA, 70,
+ "ipsec_handle_leftover_payload: "
+ "DELETE failed to allocate %d SPIs of %d bytes each",
+ nspis, spisz));
+ return -1;
+ }
+
+ memcpy (spis, payload->p + ISAKMP_DELETE_SPI_OFF, nspis * spisz);
+ msg->transport->vtbl->get_dst (msg->transport, &dst, &dstlen);
+
+ for (i = 0; i < nspis; i++)
+ {
+ sa = ipsec_sa_lookup (((struct sockaddr_in *)dst)->sin_addr.s_addr,
+ spis[i], proto);
+ if (sa == NULL)
+ {
+ LOG_DBG ((LOG_SA, 30, "ipsec_handle_leftover_payload: "
+ "could not locate SA (SPI %08x, proto %u)",
+ spis[i], proto));
+ continue;
+ }
+
+ /* Delete the SA and search for the next */
+ LOG_DBG ((LOG_SA, 30, "ipsec_handle_leftover_payload: "
+ "DELETE made us delete SA %p (%d references)",
+ sa, sa->refcnt));
+
+ sa_free(sa);
+ }
+
+ free (spis);
+ payload->flags |= PL_MARK;
+ return 0;
case ISAKMP_PAYLOAD_NOTIFY:
switch (GET_ISAKMP_NOTIFY_MSG_TYPE (payload->p))
{
@@ -1340,7 +1397,6 @@ ipsec_handle_leftover_payload (struct message *msg, u_int8_t type,
sa_enter (msg->isakmp_sa);
payload->flags |= PL_MARK;
return 0;
- break;
}
}
return -1;