Pull up following revision(s) (requested by ozaki-r in ticket #1306):
crypto/dist/ipsec-tools/src/setkey/parse.y: revision 1.23 sys/netipsec/key.c: revision 1.265 crypto/dist/ipsec-tools/src/setkey/token.l: revision 1.23 tests/net/ipsec/t_ipsec_misc.sh: revision 1.23 ipsec: fix a regression of the update API The update API updates an SA by creating a new SA and removing an existing SA. The previous change removed a newly added SA wrongly if an existing SA had been created by the getspi API. setkey: enable to use the getspi API If a specified SPI is not zero, tell the kernel to use the SPI by using SADB_EXT_SPIRANGE. Otherwise, the kernel picks a random SPI. It enables to mimic racoon. tests: add tests for getspi and udpate
This commit is contained in:
parent
0da30bf03c
commit
34255fb043
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: parse.y,v 1.18.4.1 2017/10/21 19:43:53 snj Exp $ */
|
||||
/* $NetBSD: parse.y,v 1.18.4.2 2019/07/25 08:58:21 martin Exp $ */
|
||||
|
||||
/* $KAME: parse.y,v 1.81 2003/07/01 04:01:48 itojun Exp $ */
|
||||
|
||||
|
@ -115,7 +115,7 @@ static int setkeymsg_add __P((unsigned int, unsigned int,
|
|||
}
|
||||
|
||||
%token EOT SLASH BLCL ELCL
|
||||
%token ADD UPDATE GET DELETE DELETEALL FLUSH DUMP EXIT
|
||||
%token ADD UPDATE GET GETSPI DELETE DELETEALL FLUSH DUMP EXIT
|
||||
%token PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
|
||||
%token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
|
||||
%token F_MODE MODE F_REQID
|
||||
|
@ -162,6 +162,7 @@ command
|
|||
: add_command
|
||||
| update_command
|
||||
| get_command
|
||||
| getspi_command
|
||||
| delete_command
|
||||
| deleteall_command
|
||||
| flush_command
|
||||
|
@ -261,6 +262,17 @@ get_command
|
|||
}
|
||||
;
|
||||
|
||||
/* getspi command */
|
||||
getspi_command
|
||||
: GETSPI ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
|
||||
{
|
||||
int status;
|
||||
|
||||
status = setkeymsg_add(SADB_GETSPI, $5, $3, $4);
|
||||
if (status < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* flush */
|
||||
flush_command
|
||||
: FLUSH protocol_spec EOT
|
||||
|
@ -1409,6 +1421,21 @@ setkeymsg_add(type, satype, srcs, dsts)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* SPI == 0 allows the kernel to pick a random SPI */
|
||||
if (type == SADB_GETSPI && p_spi != 0) {
|
||||
struct sadb_spirange spirange;
|
||||
u_int slen = sizeof(struct sadb_spirange);
|
||||
|
||||
memset(&spirange, 0, sizeof(spirange));
|
||||
spirange.sadb_spirange_len = PFKEY_UNIT64(slen);
|
||||
spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE;
|
||||
spirange.sadb_spirange_min = p_spi;
|
||||
spirange.sadb_spirange_max = p_spi;
|
||||
|
||||
memcpy(buf + l, &spirange, slen);
|
||||
l += slen;
|
||||
}
|
||||
|
||||
len = sizeof(struct sadb_sa);
|
||||
m_sa.sadb_sa_len = PFKEY_UNIT64(len);
|
||||
m_sa.sadb_sa_exttype = SADB_EXT_SA;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: token.l,v 1.19.8.1 2017/10/21 19:43:53 snj Exp $ */
|
||||
/* $NetBSD: token.l,v 1.19.8.2 2019/07/25 08:58:21 martin Exp $ */
|
||||
|
||||
/* $KAME: token.l,v 1.44 2003/10/21 07:20:58 itojun Exp $ */
|
||||
|
||||
|
@ -120,6 +120,7 @@ update { return(UPDATE); }
|
|||
delete { return(DELETE); }
|
||||
deleteall { return(DELETEALL); }
|
||||
get { return(GET); }
|
||||
getspi { return(GETSPI); }
|
||||
flush { return(FLUSH); }
|
||||
dump { return(DUMP); }
|
||||
exit { return(EXIT); }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: key.c,v 1.163.2.11 2019/07/22 18:07:07 martin Exp $ */
|
||||
/* $NetBSD: key.c,v 1.163.2.12 2019/07/25 08:58:21 martin Exp $ */
|
||||
/* $FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */
|
||||
/* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.163.2.11 2019/07/22 18:07:07 martin Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.163.2.12 2019/07/25 08:58:21 martin Exp $");
|
||||
|
||||
/*
|
||||
* This code is referred to RFC 2367
|
||||
|
@ -3517,7 +3517,8 @@ out:
|
|||
* others : found, pointer to a SA.
|
||||
*/
|
||||
static struct secasvar *
|
||||
key_lookup_and_remove_sav(struct secashead *sah, u_int32_t spi)
|
||||
key_lookup_and_remove_sav(struct secashead *sah, u_int32_t spi,
|
||||
const struct secasvar *hint)
|
||||
{
|
||||
struct secasvar *sav = NULL;
|
||||
u_int state;
|
||||
|
@ -3529,6 +3530,8 @@ key_lookup_and_remove_sav(struct secashead *sah, u_int32_t spi)
|
|||
KASSERT(sav->state == state);
|
||||
|
||||
if (sav->spi == spi) {
|
||||
if (hint != NULL && hint != sav)
|
||||
continue;
|
||||
sav->state = SADB_SASTATE_DEAD;
|
||||
SAVLIST_WRITER_REMOVE(sav);
|
||||
SAVLUT_WRITER_REMOVE(sav);
|
||||
|
@ -5777,7 +5780,8 @@ key_api_update(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
|
|||
* We need to lookup and remove the sav atomically, so get it again
|
||||
* here by a special API while we have a reference to it.
|
||||
*/
|
||||
oldsav = key_lookup_and_remove_sav(sah, sa0->sadb_sa_spi);
|
||||
oldsav = key_lookup_and_remove_sav(sah, sa0->sadb_sa_spi, sav);
|
||||
KASSERT(oldsav == NULL || oldsav == sav);
|
||||
/* We can release the reference because of oldsav */
|
||||
KEY_SA_UNREF(&sav);
|
||||
if (oldsav == NULL) {
|
||||
|
@ -6191,7 +6195,7 @@ key_api_delete(struct socket *so, struct mbuf *m,
|
|||
sah = key_getsah_ref(&saidx, CMP_HEAD);
|
||||
if (sah != NULL) {
|
||||
/* get a SA with SPI. */
|
||||
sav = key_lookup_and_remove_sav(sah, sa0->sadb_sa_spi);
|
||||
sav = key_lookup_and_remove_sav(sah, sa0->sadb_sa_spi, NULL);
|
||||
key_sah_unref(sah);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: t_ipsec_misc.sh,v 1.6.2.3 2017/11/21 11:11:20 martin Exp $
|
||||
# $NetBSD: t_ipsec_misc.sh,v 1.6.2.4 2019/07/25 08:58:21 martin Exp $
|
||||
#
|
||||
# Copyright (c) 2017 Internet Initiative Japan Inc.
|
||||
# All rights reserved.
|
||||
|
@ -40,9 +40,16 @@ setup_sasp()
|
|||
local lifetime=$5
|
||||
local update=$6
|
||||
local tmpfile=./tmp
|
||||
local saadd=add
|
||||
local saadd_algo_args="$algo_args"
|
||||
local extra=
|
||||
|
||||
if [ "$update" = sa ]; then
|
||||
if [ "$update" = getspi ]; then
|
||||
saadd=getspi
|
||||
saadd_algo_args=
|
||||
fi
|
||||
|
||||
if [ "$update" = sa -o "$update" = getspi ]; then
|
||||
extra="update $ip_local $ip_peer $proto 10000 $algo_args;
|
||||
update $ip_peer $ip_local $proto 10001 $algo_args;"
|
||||
elif [ "$update" = sp ]; then
|
||||
|
@ -51,8 +58,8 @@ setup_sasp()
|
|||
|
||||
export RUMP_SERVER=$SOCK_LOCAL
|
||||
cat > $tmpfile <<-EOF
|
||||
add $ip_local $ip_peer $proto 10000 -lh $lifetime -ls $lifetime $algo_args;
|
||||
add $ip_peer $ip_local $proto 10001 -lh $lifetime -ls $lifetime $algo_args;
|
||||
$saadd $ip_local $ip_peer $proto 10000 -lh $lifetime -ls $lifetime $saadd_algo_args;
|
||||
$saadd $ip_peer $ip_local $proto 10001 -lh $lifetime -ls $lifetime $saadd_algo_args;
|
||||
spdadd $ip_local $ip_peer any -P out ipsec $proto/transport//require;
|
||||
$extra
|
||||
EOF
|
||||
|
@ -67,8 +74,8 @@ setup_sasp()
|
|||
|
||||
export RUMP_SERVER=$SOCK_PEER
|
||||
cat > $tmpfile <<-EOF
|
||||
add $ip_local $ip_peer $proto 10000 -lh $lifetime -ls $lifetime $algo_args;
|
||||
add $ip_peer $ip_local $proto 10001 -lh $lifetime -ls $lifetime $algo_args;
|
||||
$saadd $ip_local $ip_peer $proto 10000 -lh $lifetime -ls $lifetime $saadd_algo_args;
|
||||
$saadd $ip_peer $ip_local $proto 10001 -lh $lifetime -ls $lifetime $saadd_algo_args;
|
||||
spdadd $ip_peer $ip_local any -P out ipsec $proto/transport//require;
|
||||
$extra
|
||||
EOF
|
||||
|
@ -370,6 +377,71 @@ add_test_update()
|
|||
atf_add_test_case ${name}
|
||||
}
|
||||
|
||||
test_getspi_update()
|
||||
{
|
||||
local proto=$1
|
||||
local algo=$2
|
||||
local ip_local=10.0.0.1
|
||||
local ip_peer=10.0.0.2
|
||||
local algo_args="$(generate_algo_args $proto $algo)"
|
||||
local proto_cap=$(echo $proto | tr 'a-z' 'A-Z')
|
||||
local outfile=./out
|
||||
|
||||
rump_server_crypto_start $SOCK_LOCAL netipsec
|
||||
rump_server_crypto_start $SOCK_PEER netipsec
|
||||
rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
|
||||
rump_server_add_iface $SOCK_PEER shmif0 $BUS
|
||||
|
||||
export RUMP_SERVER=$SOCK_LOCAL
|
||||
atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
|
||||
atf_check -s exit:0 rump.ifconfig shmif0 $ip_local/24
|
||||
|
||||
export RUMP_SERVER=$SOCK_PEER
|
||||
atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
|
||||
atf_check -s exit:0 rump.ifconfig shmif0 $ip_peer/24
|
||||
|
||||
setup_sasp $proto "$algo_args" $ip_local $ip_peer 100 getspi
|
||||
|
||||
extract_new_packets $BUS > $outfile
|
||||
|
||||
export RUMP_SERVER=$SOCK_LOCAL
|
||||
atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_peer
|
||||
|
||||
extract_new_packets $BUS > $outfile
|
||||
atf_check -s exit:0 -o match:"$ip_local > $ip_peer: $proto_cap" \
|
||||
cat $outfile
|
||||
atf_check -s exit:0 -o match:"$ip_peer > $ip_local: $proto_cap" \
|
||||
cat $outfile
|
||||
}
|
||||
|
||||
add_test_getspi_update()
|
||||
{
|
||||
local proto=$1
|
||||
local algo=$2
|
||||
local _algo=$(echo $algo | sed 's/-//g')
|
||||
local name= desc=
|
||||
|
||||
desc="Tests trying to getspi and udpate SA of $proto ($algo)"
|
||||
name="ipsec_getspi_update_sa_${proto}_${_algo}"
|
||||
|
||||
atf_test_case ${name} cleanup
|
||||
eval "
|
||||
${name}_head() {
|
||||
atf_set descr \"$desc\"
|
||||
atf_set require.progs rump_server setkey
|
||||
}
|
||||
${name}_body() {
|
||||
test_getspi_update $proto $algo
|
||||
rump_server_destroy_ifaces
|
||||
}
|
||||
${name}_cleanup() {
|
||||
\$DEBUG && dump
|
||||
cleanup
|
||||
}
|
||||
"
|
||||
atf_add_test_case ${name}
|
||||
}
|
||||
|
||||
add_sa()
|
||||
{
|
||||
local proto=$1
|
||||
|
@ -717,6 +789,7 @@ atf_init_test_cases()
|
|||
add_test_lifetime ipv6 esp $algo
|
||||
add_test_update esp $algo sa
|
||||
add_test_update esp $algo sp
|
||||
add_test_getspi_update esp $algo
|
||||
add_test_spi esp $algo new delete
|
||||
add_test_spi esp $algo old delete
|
||||
add_test_spi esp $algo new timeout
|
||||
|
@ -728,6 +801,7 @@ atf_init_test_cases()
|
|||
add_test_lifetime ipv6 ah $algo
|
||||
add_test_update ah $algo sa
|
||||
add_test_update ah $algo sp
|
||||
add_test_getspi_update ah $algo
|
||||
add_test_spi ah $algo new delete
|
||||
add_test_spi ah $algo old delete
|
||||
add_test_spi ah $algo new timeout
|
||||
|
|
Loading…
Reference in New Issue