trac#301: fixed IPsec SAs flush in purge_remote() when NAT-T enabled but no NAT-T on tunnel
This commit is contained in:
parent
cdc8049f5c
commit
3723c0b8cf
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: isakmp.c,v 1.50 2009/02/03 20:21:45 tteras Exp $ */
|
||||
/* $NetBSD: isakmp.c,v 1.51 2009/02/11 15:18:59 vanhu Exp $ */
|
||||
|
||||
/* Id: isakmp.c,v 1.74 2006/05/07 21:32:59 manubsd Exp */
|
||||
|
||||
|
@ -3322,12 +3322,22 @@ purge_remote(iph1)
|
|||
* check in/outbound SAs.
|
||||
* Select only SAs where src == local and dst == remote (outgoing)
|
||||
* or src == remote and dst == local (incoming).
|
||||
* XXX we sometime have src/dst ports set to 0 and want to match
|
||||
* iph1->local/remote with ports set to 500. This is a bug, see trac:2
|
||||
*/
|
||||
#ifdef ENABLE_NATT
|
||||
if ((cmpsaddrmagic(iph1->local, src) || cmpsaddrmagic(iph1->remote, dst)) &&
|
||||
(cmpsaddrmagic(iph1->local, dst) || cmpsaddrmagic(iph1->remote, src))) {
|
||||
msg = next;
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
if ((CMPSADDR(iph1->local, src) || CMPSADDR(iph1->remote, dst)) &&
|
||||
(CMPSADDR(iph1->local, dst) || CMPSADDR(iph1->remote, src))) {
|
||||
msg = next;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
|
||||
iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sockmisc.c,v 1.12 2008/09/03 09:57:28 tteras Exp $ */
|
||||
/* $NetBSD: sockmisc.c,v 1.13 2009/02/11 15:18:59 vanhu Exp $ */
|
||||
|
||||
/* Id: sockmisc.c,v 1.24 2006/05/07 21:32:59 manubsd Exp */
|
||||
|
||||
|
@ -63,6 +63,7 @@
|
|||
#include "gcmalloc.h"
|
||||
#include "debugrm.h"
|
||||
#include "libpfkey.h"
|
||||
#include "isakmp_var.h"
|
||||
|
||||
#ifdef NOUSE_PRIVSEP
|
||||
#define BIND bind
|
||||
|
@ -196,6 +197,76 @@ cmpsaddrwild(addr1, addr2)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* compare two sockaddr with port, taking care specific situation:
|
||||
* one addr has 0 as port, and the other has 500 (network order), return equal
|
||||
* OUT: 0: equal.
|
||||
* 1: not equal.
|
||||
*/
|
||||
int
|
||||
cmpsaddrmagic(addr1, addr2)
|
||||
const struct sockaddr *addr1;
|
||||
const struct sockaddr *addr2;
|
||||
{
|
||||
caddr_t sa1, sa2;
|
||||
u_short port1, port2;
|
||||
|
||||
if (addr1 == 0 && addr2 == 0)
|
||||
return 0;
|
||||
if (addr1 == 0 || addr2 == 0)
|
||||
return 1;
|
||||
|
||||
#ifdef __linux__
|
||||
if (addr1->sa_family != addr2->sa_family)
|
||||
return 1;
|
||||
#else
|
||||
if (addr1->sa_len != addr2->sa_len
|
||||
|| addr1->sa_family != addr2->sa_family)
|
||||
return 1;
|
||||
|
||||
#endif /* __linux__ */
|
||||
|
||||
switch (addr1->sa_family) {
|
||||
case AF_INET:
|
||||
sa1 = (caddr_t)&((struct sockaddr_in *)addr1)->sin_addr;
|
||||
sa2 = (caddr_t)&((struct sockaddr_in *)addr2)->sin_addr;
|
||||
port1 = ((struct sockaddr_in *)addr1)->sin_port;
|
||||
port2 = ((struct sockaddr_in *)addr2)->sin_port;
|
||||
plog(LLV_DEBUG, LOCATION, NULL, "cmpsaddr_magic: port1 == %d, port2 == %d\n", port1, port2);
|
||||
if (!((port1 == IPSEC_PORT_ANY && port2 == ntohs(PORT_ISAKMP)) ||
|
||||
(port2 == IPSEC_PORT_ANY && port1 == ntohs(PORT_ISAKMP)) ||
|
||||
(port1 == port2))){
|
||||
plog(LLV_DEBUG, LOCATION, NULL, "cmpsaddr_magic: ports mismatch\n");
|
||||
return 1;
|
||||
}
|
||||
plog(LLV_DEBUG, LOCATION, NULL, "cmpsaddr_magic: ports matched\n");
|
||||
if (memcmp(sa1, sa2, sizeof(struct in_addr)) != 0)
|
||||
return 1;
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
sa1 = (caddr_t)&((struct sockaddr_in6 *)addr1)->sin6_addr;
|
||||
sa2 = (caddr_t)&((struct sockaddr_in6 *)addr2)->sin6_addr;
|
||||
port1 = ((struct sockaddr_in6 *)addr1)->sin6_port;
|
||||
port2 = ((struct sockaddr_in6 *)addr2)->sin6_port;
|
||||
if (!((port1 == IPSEC_PORT_ANY && port2 == PORT_ISAKMP) ||
|
||||
(port2 == IPSEC_PORT_ANY && port1 == PORT_ISAKMP) ||
|
||||
(port1 == port2)))
|
||||
return 1;
|
||||
if (memcmp(sa1, sa2, sizeof(struct in6_addr)) != 0)
|
||||
return 1;
|
||||
if (((struct sockaddr_in6 *)addr1)->sin6_scope_id !=
|
||||
((struct sockaddr_in6 *)addr2)->sin6_scope_id)
|
||||
return 1;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* compare two sockaddr with strict match on port.
|
||||
* OUT: 0: equal.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sockmisc.h,v 1.8 2008/04/02 19:02:50 manu Exp $ */
|
||||
/* $NetBSD: sockmisc.h,v 1.9 2009/02/11 15:18:59 vanhu Exp $ */
|
||||
|
||||
/* Id: sockmisc.h,v 1.9 2005/10/05 16:55:41 manubsd Exp */
|
||||
|
||||
|
@ -57,6 +57,7 @@ extern const int niflags;
|
|||
extern int cmpsaddrwop __P((const struct sockaddr *, const struct sockaddr *));
|
||||
extern int cmpsaddrwild __P((const struct sockaddr *, const struct sockaddr *));
|
||||
extern int cmpsaddrstrict __P((const struct sockaddr *, const struct sockaddr *));
|
||||
extern int cmpsaddrmagic __P((const struct sockaddr *, const struct sockaddr *));
|
||||
|
||||
#ifdef ENABLE_NATT
|
||||
#define CMPSADDR(saddr1, saddr2) cmpsaddrstrict((saddr1), (saddr2))
|
||||
|
|
Loading…
Reference in New Issue