Bug fixes from the ipsec-tools 0.6 branch:

- Fix NAT-T problems that prevented multiple peers behind the same NAT
  to talk to the same machine outside the NAT. This also require kernel
  fixes (already committed eralier)
- Fix a LP64 bug
- Fix NAT-T RFC conformance bugs (missing non ESP marker in packets)
- Add a -p option to setkey to display ports that could be used for ESP
  over UDP when printing policies
This commit is contained in:
manu 2005-04-27 05:19:49 +00:00
parent 6490a3e8e5
commit 10802677c9
14 changed files with 149 additions and 51 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ipsec_dump_policy.c,v 1.1.1.2 2005/02/23 14:54:07 manu Exp $ */
/* $NetBSD: ipsec_dump_policy.c,v 1.2 2005/04/27 05:19:49 manu Exp $ */
/* Id: ipsec_dump_policy.c,v 1.7 2004/10/29 16:37:03 ludvigm Exp */
@ -65,10 +65,11 @@ static const char *ipsp_policy_strs[] = {
};
static char *ipsec_dump_ipsecrequest __P((char *, size_t,
struct sadb_x_ipsecrequest *, size_t));
struct sadb_x_ipsecrequest *, size_t, int));
static char *ipsec_dump_policy1 __P((caddr_t, char *, int));
static int set_addresses __P((char *, size_t, struct sockaddr *,
struct sockaddr *));
static char *set_address __P((char *, size_t, struct sockaddr *));
struct sockaddr *, int));
static char *set_address __P((char *, size_t, struct sockaddr *, int));
/*
* policy is sadb_x_policy buffer.
@ -79,6 +80,23 @@ char *
ipsec_dump_policy(policy, delimiter)
caddr_t policy;
char *delimiter;
{
return ipsec_dump_policy1(policy, delimiter, 0);
}
char *
ipsec_dump_policy_withports(policy, delimiter)
caddr_t policy;
char *delimiter;
{
return ipsec_dump_policy1(policy, delimiter, 1);
}
static char *
ipsec_dump_policy1(policy, delimiter, withports)
caddr_t policy;
char *delimiter;
int withports;
{
struct sadb_x_policy *xpl = (struct sadb_x_policy *)policy;
struct sadb_x_ipsecrequest *xisr;
@ -233,7 +251,7 @@ ipsec_dump_policy(policy, delimiter)
xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xpl + off);
if (ipsec_dump_ipsecrequest(isrbuf, sizeof(isrbuf), xisr,
PFKEY_EXTLEN(xpl) - off) == NULL) {
PFKEY_EXTLEN(xpl) - off, withports) == NULL) {
free(buf);
return NULL;
}
@ -257,11 +275,12 @@ ipsec_dump_policy(policy, delimiter)
}
static char *
ipsec_dump_ipsecrequest(buf, len, xisr, bound)
ipsec_dump_ipsecrequest(buf, len, xisr, bound, withports)
char *buf;
size_t len;
struct sadb_x_ipsecrequest *xisr;
size_t bound; /* boundary */
int withports;
{
const char *proto, *mode, *level;
char abuf[NI_MAXHOST * 2 + 2];
@ -314,7 +333,8 @@ ipsec_dump_ipsecrequest(buf, len, xisr, bound)
__ipsec_errcode = EIPSEC_INVAL_ADDRESS;
return NULL;
}
if (set_addresses(abuf, sizeof(abuf), sa1, sa2) != 0) {
if (set_addresses(abuf, sizeof(abuf),
sa1, sa2, withports) != 0) {
__ipsec_errcode = EIPSEC_INVAL_ADDRESS;
return NULL;
}
@ -355,16 +375,17 @@ ipsec_dump_ipsecrequest(buf, len, xisr, bound)
}
static int
set_addresses(buf, len, sa1, sa2)
set_addresses(buf, len, sa1, sa2, withports)
char *buf;
size_t len;
struct sockaddr *sa1;
struct sockaddr *sa2;
int withports;
{
char tmp1[NI_MAXHOST], tmp2[NI_MAXHOST];
if (set_address(tmp1, sizeof(tmp1), sa1) == NULL ||
set_address(tmp2, sizeof(tmp2), sa2) == NULL)
if (set_address(tmp1, sizeof(tmp1), sa1, withports) == NULL ||
set_address(tmp2, sizeof(tmp2), sa2, withports) == NULL)
return -1;
if (strlen(tmp1) + 1 + strlen(tmp2) + 1 > len)
return -1;
@ -373,17 +394,27 @@ set_addresses(buf, len, sa1, sa2)
}
static char *
set_address(buf, len, sa)
set_address(buf, len, sa, withports)
char *buf;
size_t len;
struct sockaddr *sa;
int withports;
{
const int niflags = NI_NUMERICHOST;
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
char host[NI_MAXHOST];
char serv[NI_MAXSERV];
if (len < 1)
return NULL;
buf[0] = '\0';
if (getnameinfo(sa, sysdep_sa_len(sa), buf, len, NULL, 0, niflags) != 0)
if (getnameinfo(sa, sysdep_sa_len(sa), host, sizeof(host), serv,
sizeof(serv), niflags) != 0)
return NULL;
if (withports)
snprintf(buf, len, "%s[%s]", host, serv);
else
snprintf(buf, len, "%s", host);
return buf;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: libpfkey.h,v 1.3 2005/02/24 20:59:24 manu Exp $ */
/* $NetBSD: libpfkey.h,v 1.4 2005/04/27 05:19:49 manu Exp $ */
/* Id: libpfkey.h,v 1.8.2.1 2005/02/24 13:33:54 manubsd Exp */
@ -47,6 +47,7 @@
struct sadb_msg;
extern void pfkey_sadump __P((struct sadb_msg *));
extern void pfkey_spdump __P((struct sadb_msg *));
extern void pfkey_spdump_withports __P((struct sadb_msg *));
struct sockaddr;
struct sadb_alg;
@ -57,6 +58,7 @@ int ipsec_check_keylen __P((u_int, u_int, u_int));
int ipsec_check_keylen2 __P((u_int, u_int, u_int));
int ipsec_get_keylen __P((u_int, u_int, struct sadb_alg *));
char *ipsec_dump_policy __P((caddr_t policy, char *delimiter));
char *ipsec_dump_policy_withports __P((caddr_t policy, char *delimiter));
void ipsec_hexdump __P((caddr_t buf, int len));
int ipsec_get_policylen __P((caddr_t policy));
caddr_t ipsec_set_policy __P((char *msg, int msglen));

View File

@ -1,4 +1,4 @@
/* $NetBSD: pfkey_dump.c,v 1.2 2005/04/10 21:20:55 manu Exp $ */
/* $NetBSD: pfkey_dump.c,v 1.3 2005/04/27 05:19:49 manu Exp $ */
/* $KAME: pfkey_dump.c,v 1.45 2003/09/08 10:14:56 itojun Exp $ */
@ -110,6 +110,7 @@ static char *str_prefport __P((u_int, u_int, u_int, u_int));
static void str_upperspec __P((u_int, u_int, u_int));
static char *str_time __P((time_t));
static void str_lifetime_byte __P((struct sadb_lifetime *, char *));
static void pfkey_spdump1(struct sadb_msg *, int);
struct val2str {
int val;
@ -411,6 +412,21 @@ pfkey_sadump(m)
void
pfkey_spdump(m)
struct sadb_msg *m;
{
return pfkey_spdump1(m, 0);
}
void
pfkey_spdump_withports(m)
struct sadb_msg *m;
{
return pfkey_spdump1(m, 1);
}
static void
pfkey_spdump1(m, withports)
struct sadb_msg *m;
int withports;
{
char pbuf[NI_MAXSERV];
caddr_t mhp[SADB_EXT_MAX + 1];
@ -515,7 +531,11 @@ pfkey_spdump(m)
printf("no X_POLICY extension.\n");
return;
}
d_xpl = ipsec_dump_policy((char *)m_xpl, "\n\t");
if (withports)
d_xpl = ipsec_dump_policy_withports((char *)m_xpl, "\n\t");
else
d_xpl = ipsec_dump_policy((char *)m_xpl, "\n\t");
if (!d_xpl)
printf("\n\tPolicy:[%s]\n", ipsec_strerror());
else {

View File

@ -1,4 +1,4 @@
/* $NetBSD: ipsec_doi.c,v 1.2 2005/04/18 11:15:01 manu Exp $ */
/* $NetBSD: ipsec_doi.c,v 1.3 2005/04/27 05:19:50 manu Exp $ */
/* Id: ipsec_doi.c,v 1.26.2.1 2005/02/17 13:19:18 vanhu Exp */
@ -2611,17 +2611,19 @@ setph1attr(sa, buf)
int attrlen = 0;
if (sa->lifetime) {
u_int32_t lifetime = htonl((u_int32_t)sa->lifetime);
attrlen += sizeof(struct isakmp_data)
+ sizeof(struct isakmp_data);
if (sa->lifetime > 0xffff)
attrlen += sizeof(sa->lifetime);
attrlen += sizeof(lifetime);
if (buf) {
p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD_TYPE,
OAKLEY_ATTR_SA_LD_TYPE_SEC);
if (sa->lifetime > 0xffff) {
u_int32_t v = htonl((u_int32_t)sa->lifetime);
p = isakmp_set_attr_v(p, OAKLEY_ATTR_SA_LD,
(caddr_t)&v, sizeof(v));
(caddr_t)&lifetime,
sizeof(lifetime));
} else {
p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD,
sa->lifetime);
@ -2630,17 +2632,19 @@ setph1attr(sa, buf)
}
if (sa->lifebyte) {
u_int32_t lifebyte = htonl((u_int32_t)sa->lifebyte);
attrlen += sizeof(struct isakmp_data)
+ sizeof(struct isakmp_data);
if (sa->lifebyte > 0xffff)
attrlen += sizeof(sa->lifebyte);
attrlen += sizeof(lifebyte);
if (buf) {
p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD_TYPE,
OAKLEY_ATTR_SA_LD_TYPE_KB);
if (sa->lifebyte > 0xffff) {
u_int32_t v = htonl((u_int32_t)sa->lifebyte);
p = isakmp_set_attr_v(p, OAKLEY_ATTR_SA_LD,
(caddr_t)&v, sizeof(v));
(caddr_t)&lifebyte,
sizeof(lifebyte));
} else {
p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD,
sa->lifebyte);

View File

@ -1,4 +1,4 @@
/* $NetBSD: isakmp.c,v 1.2 2005/04/19 19:42:09 manu Exp $ */
/* $NetBSD: isakmp.c,v 1.3 2005/04/27 05:19:50 manu Exp $ */
/* Id: isakmp.c,v 1.34.2.2 2005/03/13 17:31:55 vanhu Exp */
@ -431,14 +431,14 @@ isakmp_main(msg, remote, local)
#ifdef ENABLE_NATT
/* Floating ports for NAT-T */
if ((iph1->natt_flags & NAT_DETECTED) &&
if (NATT_AVAILABLE(iph1) &&
! (iph1->natt_flags & NAT_PORTS_CHANGED) &&
((cmpsaddrstrict(iph1->remote, remote) != 0) ||
(cmpsaddrstrict(iph1->local, local) != 0)))
{
/* prevent memory leak */
racoon_free (iph1->remote);
racoon_free (iph1->local);
racoon_free(iph1->remote);
racoon_free(iph1->local);
/* copy-in new addresses */
iph1->remote = dupsaddr(remote);
@ -447,7 +447,7 @@ isakmp_main(msg, remote, local)
/* set the flag to prevent further port floating
(FIXME: should we allow it? E.g. when the NAT gw
is rebooted?) */
iph1->natt_flags |= NAT_PORTS_CHANGED;
iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER;
/* print some neat info */
plog (LLV_INFO, LOCATION, NULL,
@ -1209,11 +1209,15 @@ isakmp_ph2begin_r(iph1, msg)
}
switch (iph2->dst->sa_family) {
case AF_INET:
#ifndef ENABLE_NATT
((struct sockaddr_in *)iph2->dst)->sin_port = 0;
#endif
break;
#ifdef INET6
case AF_INET6:
#ifndef ENABLE_NATT
((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0;
#endif
break;
#endif
default:
@ -1230,11 +1234,15 @@ isakmp_ph2begin_r(iph1, msg)
}
switch (iph2->src->sa_family) {
case AF_INET:
#ifndef ENABLE_NATT
((struct sockaddr_in *)iph2->src)->sin_port = 0;
#endif
break;
#ifdef INET6
case AF_INET6:
#ifndef ENABLE_NATT
((struct sockaddr_in6 *)iph2->src)->sin6_port = 0;
#endif
break;
#endif
default:
@ -1673,7 +1681,7 @@ isakmp_send(iph1, sbuf)
vchar_t *vbuf = NULL;
#ifdef ENABLE_NATT
size_t extralen = NON_ESP_MARKER_USE(iph1) * NON_ESP_MARKER_LEN;
size_t extralen = NON_ESP_MARKER_USE(iph1) ? NON_ESP_MARKER_LEN : 0;
#ifdef ENABLE_FRAG
/*
@ -2677,6 +2685,7 @@ copy_ph1addresses(iph1, rmconf, remote, local)
delph1(iph1);
return -1;
}
port = NULL;
switch (iph1->local->sa_family) {
case AF_INET:
port = &((struct sockaddr_in *)iph1->local)->sin_port;
@ -2704,7 +2713,12 @@ copy_ph1addresses(iph1, rmconf, remote, local)
delph1(iph1);
return -1;
}
#ifdef ENABLE_NATT
if ( port != NULL && *port == htons(lcconf->port_isakmp_natt) ) {
plog (LLV_DEBUG, LOCATION, NULL, "Marking ports as changed\n");
iph1->natt_flags |= NAT_ADD_NON_ESP_MARKER;
}
#endif
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: isakmp_cfg.c,v 1.2 2005/04/04 21:43:26 manu Exp $ */
/* $NetBSD: isakmp_cfg.c,v 1.3 2005/04/27 05:19:50 manu Exp $ */
/* Id: isakmp_cfg.c,v 1.26.2.1 2005/03/16 00:13:38 manubsd Exp */
@ -971,8 +971,10 @@ isakmp_cfg_send(iph1, payload, np, flags, new_exchange)
iph2->src = dupsaddr(iph1->local);
switch (iph1->remote->sa_family) {
case AF_INET:
#ifndef ENABLE_NATT
((struct sockaddr_in *)iph2->dst)->sin_port = 0;
((struct sockaddr_in *)iph2->src)->sin_port = 0;
#endif
break;
#ifdef INET6
case AF_INET6:

View File

@ -1,4 +1,4 @@
/* $NetBSD: isakmp_inf.c,v 1.2 2005/04/19 19:42:09 manu Exp $ */
/* $NetBSD: isakmp_inf.c,v 1.3 2005/04/27 05:19:50 manu Exp $ */
/* Id: isakmp_inf.c,v 1.14.4.2 2005/03/02 20:00:03 vanhu Exp */
@ -619,8 +619,10 @@ isakmp_info_send_common(iph1, payload, np, flags)
iph2->src = dupsaddr(iph1->local);
switch (iph1->remote->sa_family) {
case AF_INET:
#ifndef ENABLE_NATT
((struct sockaddr_in *)iph2->dst)->sin_port = 0;
((struct sockaddr_in *)iph2->src)->sin_port = 0;
#endif
break;
#ifdef INET6
case AF_INET6:

View File

@ -1,4 +1,4 @@
/* $NetBSD: isakmp_quick.c,v 1.2 2005/04/19 19:42:09 manu Exp $ */
/* $NetBSD: isakmp_quick.c,v 1.3 2005/04/27 05:19:50 manu Exp $ */
/* Id: isakmp_quick.c,v 1.13.2.1 2005/03/02 20:00:03 vanhu Exp */
@ -451,6 +451,13 @@ quick_i2recv(iph2, msg0)
isakmp_check_notify(pa->ptr, iph2->ph1);
break;
#ifdef ENABLE_NATT
case ISAKMP_NPTYPE_NATOA_DRAFT:
case ISAKMP_NPTYPE_NATOA_RFC:
/* Ignore original source/destination messages */
break;
#endif
default:
/* don't send information, see ident_r1recv() */
plog(LLV_ERROR, LOCATION, iph2->ph1->remote,

View File

@ -1,4 +1,4 @@
/* $NetBSD: nattraversal.c,v 1.1.1.2 2005/02/23 14:54:22 manu Exp $ */
/* $NetBSD: nattraversal.c,v 1.2 2005/04/27 05:19:50 manu Exp $ */
/*
* Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany.
@ -292,7 +292,7 @@ natt_float_ports (struct ph1handle *iph1)
set_port (iph1->local, iph1->natt_options->float_port);
set_port (iph1->remote, iph1->natt_options->float_port);
iph1->natt_flags |= NAT_PORTS_CHANGED;
iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER;
natt_keepalive_add_ph1 (iph1);
}
@ -393,7 +393,7 @@ natt_keepalive_add_ph1 (struct ph1handle *iph1)
/* Should only the NATed host send keepalives?
If yes, add '(iph1->natt_flags & NAT_DETECTED_ME)'
to the following condition. */
if (iph1->natt_flags & NAT_PORTS_CHANGED &&
if (iph1->natt_flags & NAT_DETECTED &&
! (iph1->natt_flags & NAT_KA_QUEUED)) {
ret = natt_keepalive_add (iph1->local, iph1->remote);
if (ret == 0)

View File

@ -1,4 +1,4 @@
/* $NetBSD: nattraversal.h,v 1.1.1.2 2005/02/23 14:54:22 manu Exp $ */
/* $NetBSD: nattraversal.h,v 1.2 2005/04/27 05:19:50 manu Exp $ */
/*
* Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany.
@ -40,13 +40,14 @@
#define NAT_DETECTED_PEER (1L<<2)
#define NAT_PORTS_CHANGED (1L<<3)
#define NAT_KA_QUEUED (1L<<4)
#define NAT_ADD_NON_ESP_MARKER (1L<<5)
#define NATT_AVAILABLE(ph1) ((iph1)->natt_flags & NAT_ANNOUNCED)
#define NAT_DETECTED (NAT_DETECTED_ME | NAT_DETECTED_PEER)
#define NON_ESP_MARKER_LEN sizeof(u_int32_t)
#define NON_ESP_MARKER_USE(iph1) (((iph1)->natt_flags & NAT_PORTS_CHANGED) / NAT_PORTS_CHANGED)
#define NON_ESP_MARKER_USE(iph1) ((iph1)->natt_flags & NAT_ADD_NON_ESP_MARKER)
/* These are the values from parsing "remote {}"
block of the config file. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: pfkey.c,v 1.2 2005/04/19 19:42:09 manu Exp $ */
/* $NetBSD: pfkey.c,v 1.3 2005/04/27 05:19:50 manu Exp $ */
/* Id: pfkey.c,v 1.31.2.1 2005/02/18 10:01:40 vanhu Exp */
@ -2840,13 +2840,13 @@ sadbsecas2str(src, dst, proto, spi, mode)
p += i;
blen -= i;
i = snprintf(p, blen, "%s->", saddrwop2str(src));
i = snprintf(p, blen, "%s->", saddr2str(src));
if (i < 0 || i >= blen)
return NULL;
p += i;
blen -= i;
i = snprintf(p, blen, "%s ", saddrwop2str(dst));
i = snprintf(p, blen, "%s ", saddr2str(dst));
if (i < 0 || i >= blen)
return NULL;
p += i;

View File

@ -1,4 +1,4 @@
.\" $NetBSD: setkey.8,v 1.9 2005/04/17 01:03:46 wiz Exp $
.\" $NetBSD: setkey.8,v 1.10 2005/04/27 05:19:50 manu Exp $
.\"
.\" $KAME: setkey.8,v 1.93 2003/09/24 23:44:46 itojun Exp $
.\"
@ -51,7 +51,7 @@
.Op Fl aklPrv
.Fl D
.Nm setkey
.Op Fl Pv
.Op Fl Pvp
.Fl F
.Nm setkey
.Op Fl H
@ -94,9 +94,14 @@ A dead SAD entry is one that has expired but remains in the
system because it is referenced by some SPD entries.
.It Fl D
Dump the SAD entries.
If
.Fl P ,
is also specified, SPD entries are dumped.
If
.Fl P
is also specified, the SPD entries are dumped.
.Fl p
is specified with
.Fl P ,
the ports that can be used for ESP over UDP are displayed in policies.
.It Fl F
Flush the SAD entries.
If

View File

@ -1,4 +1,4 @@
/* $NetBSD: setkey.c,v 1.3 2005/02/23 15:17:51 manu Exp $ /
/* $NetBSD: setkey.c,v 1.4 2005/04/27 05:19:50 manu Exp $ /
/* KAME: setkey.c,v 1.36 2003/09/24 23:52:51 itojun Exp */
@ -108,6 +108,7 @@ int f_policy = 0;
int f_hexdump = 0;
int f_tflag = 0;
int f_notreally = 0;
int f_withports = 0;
#ifdef HAVE_POLICY_FWD
int f_rfcmode = 1;
#define RK_OPTS "rk"
@ -175,7 +176,7 @@ main(argc, argv)
thiszone = gmt2local(0);
while ((c = getopt(argc, argv, "acdf:HlnvxDFPhVrk?")) != -1) {
while ((c = getopt(argc, argv, "acdf:HlnvxDFPphVrk?")) != -1) {
switch (c) {
case 'c':
f_mode = MODE_STDIN;
@ -215,6 +216,9 @@ main(argc, argv)
case 'P':
f_policy = 1;
break;
case 'p':
f_withports = 1;
break;
case 'v':
f_verbose = 1;
break;
@ -608,11 +612,17 @@ postproc(msg, len)
break;
case SADB_X_SPDGET:
pfkey_spdump(msg);
if (f_withports)
pfkey_spdump_withports(msg);
else
pfkey_spdump(msg);
break;
case SADB_X_SPDDUMP:
pfkey_spdump(msg);
if (f_withports)
pfkey_spdump_withports(msg);
else
pfkey_spdump(msg);
if (msg->sadb_msg_seq == 0) break;
msg = (struct sadb_msg *)((caddr_t)msg +
PFKEY_UNUNIT64(msg->sadb_msg_len));

View File

@ -1,5 +1,5 @@
#define TOP_PACKAGE "ipsec-tools"
#define TOP_PACKAGE_NAME "ipsec-tools"
#define TOP_PACKAGE_VERSION "0.6-nb20050410"
#define TOP_PACKAGE_STRING "ipsec-tools 0.6-nb20050410"
#define TOP_PACKAGE_VERSION "0.6-nb20050426"
#define TOP_PACKAGE_STRING "ipsec-tools 0.6-nb20050426"
#define TOP_PACKAGE_URL "http://ipsec-tools.sourceforge.net"