diff options
author | Niels Provos <provos@cvs.openbsd.org> | 1998-05-24 22:40:14 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 1998-05-24 22:40:14 +0000 |
commit | bea77fd5a0761e37dbba60e9c5a4a995bdaeef07 (patch) | |
tree | 5e395114ef53026b1ddeb10b004830467a4ef36e /sys | |
parent | c3b360b3388a608999e98c2a85a4b49ab0eb152a (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.c | 44 | ||||
-rw-r--r-- | sys/netinet/ip_esp.c | 46 |
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. |