setkey: fix deleteall in Linux
Linux requires SADB_DELETE message to have SPI. So send a SADB_DELETE message for each matching SA. Trac #284. From: Gabriel Somlo <somlo@cmu.edu>
This commit is contained in:
parent
61b1fbae0d
commit
e3372d2f8f
5
crypto/dist/ipsec-tools/src/setkey/extern.h
vendored
5
crypto/dist/ipsec-tools/src/setkey/extern.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: extern.h,v 1.4 2006/09/09 16:22:37 manu Exp $ */
|
||||
/* $NetBSD: extern.h,v 1.5 2009/03/06 11:45:03 tteras Exp $ */
|
||||
|
||||
|
||||
|
||||
@ -14,6 +14,9 @@ int yyparse __P((void));
|
||||
void yyfatal __P((const char *));
|
||||
void yyerror __P((const char *));
|
||||
|
||||
u_int32_t *sendkeymsg_spigrep __P((unsigned int, struct addrinfo *,
|
||||
struct addrinfo *, int *));
|
||||
|
||||
extern int f_rfcmode;
|
||||
extern int lineno;
|
||||
extern int last_msg_type;
|
||||
|
26
crypto/dist/ipsec-tools/src/setkey/parse.y
vendored
26
crypto/dist/ipsec-tools/src/setkey/parse.y
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: parse.y,v 1.11 2008/12/29 12:54:33 mlelstv Exp $ */
|
||||
/* $NetBSD: parse.y,v 1.12 2009/03/06 11:45:03 tteras Exp $ */
|
||||
|
||||
/* $KAME: parse.y,v 1.81 2003/07/01 04:01:48 itojun Exp $ */
|
||||
|
||||
@ -211,11 +211,27 @@ delete_command
|
||||
deleteall_command
|
||||
: DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT
|
||||
{
|
||||
int status;
|
||||
|
||||
status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1);
|
||||
if (status < 0)
|
||||
#ifndef __linux__
|
||||
if (setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1) < 0)
|
||||
return -1;
|
||||
#else /* __linux__ */
|
||||
/* linux strictly adheres to RFC2367, and returns
|
||||
* an error if we send an SADB_DELETE request without
|
||||
* an SPI. Therefore, we must first retrieve a list
|
||||
* of SPIs for all matching SADB entries, and then
|
||||
* delete each one separately. */
|
||||
u_int32_t *spi;
|
||||
int i, n;
|
||||
|
||||
spi = sendkeymsg_spigrep($5, $3, $4, &n);
|
||||
for (i = 0; i < n; i++) {
|
||||
p_spi = spi[i];
|
||||
if (setkeymsg_addr(SADB_DELETE,
|
||||
$5, $3, $4, 0) < 0)
|
||||
return -1;
|
||||
}
|
||||
free(spi);
|
||||
#endif /* __linux__ */
|
||||
}
|
||||
;
|
||||
|
||||
|
165
crypto/dist/ipsec-tools/src/setkey/setkey.c
vendored
165
crypto/dist/ipsec-tools/src/setkey/setkey.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: setkey.c,v 1.12 2007/07/18 12:07:52 vanhu Exp $ */
|
||||
/* $NetBSD: setkey.c,v 1.13 2009/03/06 11:45:03 tteras Exp $ */
|
||||
|
||||
/* $KAME: setkey.c,v 1.36 2003/09/24 23:52:51 itojun Exp $ */
|
||||
|
||||
@ -445,6 +445,167 @@ promisc()
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate 'spi' array with SPIs matching 'satype', 'srcs', and 'dsts'
|
||||
* Return value is dynamically generated array of SPIs, also number of
|
||||
* SPIs through num_spi pointer.
|
||||
* On any error, set *num_spi to 0 and return NULL.
|
||||
*/
|
||||
u_int32_t *
|
||||
sendkeymsg_spigrep(satype, srcs, dsts, num_spi)
|
||||
unsigned int satype;
|
||||
struct addrinfo *srcs;
|
||||
struct addrinfo *dsts;
|
||||
int *num_spi;
|
||||
{
|
||||
struct sadb_msg msg, *m;
|
||||
char *buf;
|
||||
size_t len;
|
||||
ssize_t l;
|
||||
u_char rbuf[1024 * 32];
|
||||
caddr_t mhp[SADB_EXT_MAX + 1];
|
||||
struct sadb_address *saddr;
|
||||
struct sockaddr *s;
|
||||
struct addrinfo *a;
|
||||
struct sadb_sa *sa;
|
||||
u_int32_t *spi = NULL;
|
||||
int max_spi = 0, fail = 0;
|
||||
|
||||
*num_spi = 0;
|
||||
|
||||
if (f_notreally) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
|
||||
perror("setsockopt");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
msg.sadb_msg_version = PF_KEY_V2;
|
||||
msg.sadb_msg_type = SADB_DUMP;
|
||||
msg.sadb_msg_errno = 0;
|
||||
msg.sadb_msg_satype = satype;
|
||||
msg.sadb_msg_len = PFKEY_UNIT64(sizeof(msg));
|
||||
msg.sadb_msg_reserved = 0;
|
||||
msg.sadb_msg_seq = 0;
|
||||
msg.sadb_msg_pid = getpid();
|
||||
buf = (char *)&msg;
|
||||
len = sizeof(msg);
|
||||
|
||||
if (f_verbose) {
|
||||
kdebug_sadb(&msg);
|
||||
printf("\n");
|
||||
}
|
||||
if (f_hexdump) {
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i % 16 == 0)
|
||||
printf("%08x: ", i);
|
||||
printf("%02x ", buf[i] & 0xff);
|
||||
if (i % 16 == 15)
|
||||
printf("\n");
|
||||
}
|
||||
if (len % 16)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if ((l = send(so, buf, len, 0)) < 0) {
|
||||
perror("send");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m = (struct sadb_msg *)rbuf;
|
||||
do {
|
||||
if ((l = recv(so, rbuf, sizeof(rbuf), 0)) < 0) {
|
||||
perror("recv");
|
||||
fail = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (PFKEY_UNUNIT64(m->sadb_msg_len) != l) {
|
||||
warnx("invalid keymsg length");
|
||||
fail = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (f_verbose) {
|
||||
kdebug_sadb(m);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (m->sadb_msg_type != SADB_DUMP) {
|
||||
warnx("unexpected message type");
|
||||
fail = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (m->sadb_msg_errno != 0) {
|
||||
warnx("error encountered");
|
||||
fail = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* match satype */
|
||||
if (m->sadb_msg_satype != satype)
|
||||
continue;
|
||||
|
||||
pfkey_align(m, mhp);
|
||||
pfkey_check(mhp);
|
||||
|
||||
/* match src */
|
||||
saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
|
||||
if (saddr == NULL)
|
||||
continue;
|
||||
s = (struct sockaddr *)(saddr + 1);
|
||||
for (a = srcs; a; a = a->ai_next)
|
||||
if (memcmp(a->ai_addr, s, a->ai_addrlen) == 0)
|
||||
break;
|
||||
if (a == NULL)
|
||||
continue;
|
||||
|
||||
/* match dst */
|
||||
saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
|
||||
if (saddr == NULL)
|
||||
continue;
|
||||
s = (struct sockaddr *)(saddr + 1);
|
||||
for (a = dsts; a; a = a->ai_next)
|
||||
if (memcmp(a->ai_addr, s, a->ai_addrlen) == 0)
|
||||
break;
|
||||
if (a == NULL)
|
||||
continue;
|
||||
|
||||
if (*num_spi >= max_spi) {
|
||||
max_spi += 512;
|
||||
spi = realloc(spi, max_spi * sizeof(u_int32_t));
|
||||
}
|
||||
|
||||
sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
|
||||
if (sa != NULL)
|
||||
spi[(*num_spi)++] = (u_int32_t)ntohl(sa->sadb_sa_spi);
|
||||
|
||||
m = (struct sadb_msg *)((caddr_t)m + PFKEY_UNUNIT64(m->sadb_msg_len));
|
||||
|
||||
if (f_verbose) {
|
||||
kdebug_sadb(m);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
} while (m->sadb_msg_seq);
|
||||
|
||||
if (fail) {
|
||||
free(spi);
|
||||
*num_spi = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return spi;
|
||||
}
|
||||
|
||||
int
|
||||
sendkeymsg(buf, len)
|
||||
char *buf;
|
||||
@ -506,7 +667,7 @@ again:
|
||||
}
|
||||
|
||||
if (f_verbose) {
|
||||
kdebug_sadb((struct sadb_msg *)rbuf);
|
||||
kdebug_sadb(msg);
|
||||
printf("\n");
|
||||
}
|
||||
if (postproc(msg, l) < 0)
|
||||
|
Loading…
Reference in New Issue
Block a user