summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorNiels Provos <provos@cvs.openbsd.org>1998-05-24 22:40:14 +0000
committerNiels Provos <provos@cvs.openbsd.org>1998-05-24 22:40:14 +0000
commitbea77fd5a0761e37dbba60e9c5a4a995bdaeef07 (patch)
tree5e395114ef53026b1ddeb10b004830467a4ef36e /sys
parentc3b360b3388a608999e98c2a85a4b49ab0eb152a (diff)
avoid source address spoofing for mutual hostile hosts which have SAs to
us, reported by Craig Metz <cmetz@inner.net>.
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/ip_ah.c44
-rw-r--r--sys/netinet/ip_esp.c46
2 files changed, 67 insertions, 23 deletions
diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c
index 1266a8157df..99d15f827dd 100644
--- a/sys/netinet/ip_ah.c
+++ b/sys/netinet/ip_ah.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ah.c,v 1.14 1998/05/18 21:10:30 provos Exp $ */
+/* $OpenBSD: ip_ah.c,v 1.15 1998/05/24 22:40:13 provos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -211,24 +211,32 @@ ah_input(register struct mbuf *m, int iphlen)
ipo = mtod(m, struct ip *);
if (ipo->ip_p == IPPROTO_IPIP) /* IP-in-IP encapsulation */
{
+ /* ipn will now contain the inner IP header */
+ m_copydata(m, ipo->ip_hl << 2, sizeof(struct ip), (caddr_t) &ipn);
+
/* Encapsulating SPI */
if (tdbp->tdb_osrc.s_addr && tdbp->tdb_odst.s_addr)
{
if (tdbp->tdb_flags & TDBF_UNIQUE)
- if ((ipn.ip_src.s_addr != ipo->ip_src.s_addr) ||
- (ipn.ip_dst.s_addr != ipo->ip_dst.s_addr))
- {
- if (encdebug)
- log(LOG_ALERT, "ah_input(): AH-tunnel with different internal addresses %x/%x, SA %08x/%x\n", ipo->ip_src, ipo->ip_dst, tdbp->tdb_spi, tdbp->tdb_dst);
- m_freem(m);
- ahstat.ahs_hdrops++;
- return;
- }
+ if ((ipn.ip_src.s_addr != ipo->ip_src.s_addr) ||
+ (ipn.ip_dst.s_addr != ipo->ip_dst.s_addr))
+ {
+ if (encdebug)
+ log(LOG_ALERT, "ah_input(): AH-tunnel with different internal addresses %x/%x, SA %08x/%x\n", ipo->ip_src, ipo->ip_dst, tdbp->tdb_spi, tdbp->tdb_dst);
+ m_freem(m);
+ ahstat.ahs_hdrops++;
+ return;
+ }
+
+ /*
+ * XXX Here we should be checking that the inner IP addresses
+ * XXX are acceptable/authorized.
+ */
}
else /* So we're paranoid */
{
if (encdebug)
- log(LOG_ALERT, "ah_input(): AH-tunnel used when expecting AH-transport, SA %08x/%x\n", tdbp->tdb_spi, tdbp->tdb_dst);
+ log(LOG_ALERT, "ah_input(): AH-tunnel used when expecting AH-transport, SA %08x/%x\n", tdbp->tdb_spi, tdbp->tdb_dst);
m_freem(m);
ahstat.ahs_hdrops++;
return;
@@ -236,6 +244,20 @@ ah_input(register struct mbuf *m, int iphlen)
}
/*
+ * Check that the source address is an expected one, if we know what
+ * it's supposed to be. This avoids source address spoofing.
+ */
+ if (tdbp->tdb_src.s_addr != INADDR_ANY)
+ if (ipo->ip_src.s_addr != tdbp->tdb_src.s_addr)
+ {
+ if (encdebug)
+ log(LOG_ALERT, "esp_input(): source address %x doesn't correspond to expected source %x, SA %08x/%x\n", ipo->ip_src, tdbp->tdb_src, tdbp->tdb_dst, tdbp->tdb_spi);
+ m_free(m);
+ ahstat.ahs_hdrops++;
+ return;
+ }
+
+ /*
* Interface pointer is already in first mbuf; chop off the
* `outer' header and reschedule.
*/
diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c
index 6c6fab1426c..f8a6ad7e847 100644
--- a/sys/netinet/ip_esp.c
+++ b/sys/netinet/ip_esp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_esp.c,v 1.14 1998/05/18 21:10:40 provos Exp $ */
+/* $OpenBSD: ip_esp.c,v 1.15 1998/05/24 22:40:12 provos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -210,30 +210,52 @@ esp_input(register struct mbuf *m, int iphlen)
ipo = mtod(m, struct ip *);
if (ipo->ip_p == IPPROTO_IPIP) /* IP-in-IP encapsulation */
{
+ /* ipn will now contain the inner IP header */
+ m_copydata(m, ipo->ip_hl << 2, sizeof(struct ip), (caddr_t) &ipn);
+
/* Encapsulating SPI */
if (tdbp->tdb_osrc.s_addr && tdbp->tdb_odst.s_addr)
{
if (tdbp->tdb_flags & TDBF_UNIQUE)
- if ((ipn.ip_src.s_addr != ipo->ip_src.s_addr) ||
- (ipn.ip_dst.s_addr != ipo->ip_dst.s_addr))
- {
- if (encdebug)
- log(LOG_ALERT, "esp_input(): ESP-tunnel with different internal addresses %x/%x, SA %08x/%x\n", ipo->ip_src, ipo->ip_dst, tdbp->tdb_spi, tdbp->tdb_dst);
- m_freem(m);
- espstat.esps_hdrops++;
- return;
- }
+ if ((ipn.ip_src.s_addr != ipo->ip_src.s_addr) ||
+ (ipn.ip_dst.s_addr != ipo->ip_dst.s_addr))
+ {
+ if (encdebug)
+ log(LOG_ALERT, "esp_input(): ESP-tunnel with different internal addresses %x/%x, SA %08x/%x\n", ipo->ip_src, ipo->ip_dst, tdbp->tdb_spi, tdbp->tdb_dst);
+ m_freem(m);
+ espstat.esps_hdrops++;
+ return;
+ }
+
+ /*
+ * XXX Here we should be checking that the inner IP addresses
+ * XXX are acceptable/authorized.
+ */
}
else /* So we're paranoid */
{
if (encdebug)
- log(LOG_ALERT, "esp_input(): ESP-tunnel used when expecting ESP-transport, SA %08x/%x\n", tdbp->tdb_spi, tdbp->tdb_dst);
+ log(LOG_ALERT, "esp_input(): ESP-tunnel used when expecting ESP-transport, SA %08x/%x\n", tdbp->tdb_spi, tdbp->tdb_dst);
m_freem(m);
espstat.esps_hdrops++;
return;
}
}
-
+
+ /*
+ * Check that the source address is an expected one, if we know what
+ * it's supposed to be. This avoids source address spoofing.
+ */
+ if (tdbp->tdb_src.s_addr != INADDR_ANY)
+ if (ipo->ip_src.s_addr != tdbp->tdb_src.s_addr)
+ {
+ if (encdebug)
+ log(LOG_ALERT, "esp_input(): source address %x doesn't correspond to expected source %x, SA %08x/%x\n", ipo->ip_src, tdbp->tdb_src, tdbp->tdb_dst, tdbp->tdb_spi);
+ m_free(m);
+ espstat.esps_hdrops++;
+ return;
+ }
+
/*
* Interface pointer is already in first mbuf; chop off the
* `outer' header and reschedule.