b28f582c2a
common.nbd's nbd_server_set_tcp_port() tries to find a free port, and then uses it for the whole test run. However, this is racy because even if the port was free at the beginning, there is no guarantee it will continue to be available. Therefore, 233 currently cannot reliably be run concurrently with other NBD TCP tests. This patch addresses the problem by dropping nbd_server_set_tcp_port(), and instead finding a new port every time nbd_server_start_tcp_socket() is invoked. For this, we run qemu-nbd with --fork and on error evaluate the output to see whether it contains "Address already in use". If so, we try the next port. On success, we still want to continually redirect the output from qemu-nbd to stderr. To achieve both, we redirect qemu-nbd's stderr to a FIFO that we then open in bash. If the parent process exits with status 0 (which means that the server has started successfully), we launch a background cat process that copies the FIFO to stderr. On failure, we read the whole content into a variable and then evaluate it. While at it, use --fork in nbd_server_start_unix_socket(), too. Doing so allows us to drop nbd_server_wait_for_*_socket(). Note that the reason common.nbd did not use --fork before is that qemu-nbd did not have --pid-file. Signed-off-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20190508211820.17851-6-mreitz@redhat.com> Signed-off-by: Eric Blake <eblake@redhat.com>
157 lines
4.9 KiB
Bash
Executable File
157 lines
4.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Test NBD TLS certificate / authorization integration
|
|
#
|
|
# Copyright (C) 2018-2019 Red Hat, Inc.
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
# creator
|
|
owner=berrange@redhat.com
|
|
|
|
seq=$(basename $0)
|
|
echo "QA output created by $seq"
|
|
|
|
status=1 # failure is the default!
|
|
|
|
_cleanup()
|
|
{
|
|
nbd_server_stop
|
|
_cleanup_test_img
|
|
# If we aborted early we want to see this log for diagnosis
|
|
test -f "$TEST_DIR/server.log" && cat "$TEST_DIR/server.log"
|
|
rm -f "$TEST_DIR/server.log"
|
|
tls_x509_cleanup
|
|
}
|
|
trap "_cleanup; exit \$status" 0 1 2 3 15
|
|
|
|
# get standard environment, filters and checks
|
|
. ./common.rc
|
|
. ./common.filter
|
|
. ./common.pattern
|
|
. ./common.tls
|
|
. ./common.nbd
|
|
|
|
_supported_fmt raw qcow2
|
|
_supported_proto file
|
|
# If porting to non-Linux, consider using socat instead of ss in common.nbd
|
|
_require_command QEMU_NBD
|
|
|
|
tls_x509_init
|
|
|
|
echo
|
|
echo "== preparing TLS creds =="
|
|
|
|
tls_x509_create_root_ca "ca1"
|
|
tls_x509_create_root_ca "ca2"
|
|
tls_x509_create_server "ca1" "server1"
|
|
tls_x509_create_client "ca1" "client1"
|
|
tls_x509_create_client "ca2" "client2"
|
|
tls_x509_create_client "ca1" "client3"
|
|
|
|
echo
|
|
echo "== preparing image =="
|
|
_make_test_img 64M
|
|
$QEMU_IO -c 'w -P 0x11 1m 1m' "$TEST_IMG" | _filter_qemu_io
|
|
|
|
echo
|
|
echo "== check TLS client to plain server fails =="
|
|
nbd_server_start_tcp_socket -f $IMGFMT "$TEST_IMG" 2> "$TEST_DIR/server.log"
|
|
|
|
obj=tls-creds-x509,dir=${tls_dir}/client1,endpoint=client,id=tls0
|
|
$QEMU_IMG info --image-opts --object $obj \
|
|
driver=nbd,host=$nbd_tcp_addr,port=$nbd_tcp_port,tls-creds=tls0 \
|
|
2>&1 | sed "s/$nbd_tcp_port/PORT/g"
|
|
$QEMU_NBD_PROG -L -b $nbd_tcp_addr -p $nbd_tcp_port --object $obj \
|
|
--tls-creds=tls0
|
|
|
|
nbd_server_stop
|
|
|
|
echo
|
|
echo "== check plain client to TLS server fails =="
|
|
|
|
nbd_server_start_tcp_socket \
|
|
--object tls-creds-x509,dir=${tls_dir}/server1,endpoint=server,id=tls0,verify-peer=yes \
|
|
--tls-creds tls0 \
|
|
-f $IMGFMT "$TEST_IMG" 2>> "$TEST_DIR/server.log"
|
|
|
|
$QEMU_IMG info nbd://localhost:$nbd_tcp_port 2>&1 | sed "s/$nbd_tcp_port/PORT/g"
|
|
$QEMU_NBD_PROG -L -b $nbd_tcp_addr -p $nbd_tcp_port
|
|
|
|
echo
|
|
echo "== check TLS works =="
|
|
obj1=tls-creds-x509,dir=${tls_dir}/client1,endpoint=client,id=tls0
|
|
obj2=tls-creds-x509,dir=${tls_dir}/client3,endpoint=client,id=tls0
|
|
$QEMU_IMG info --image-opts --object $obj1 \
|
|
driver=nbd,host=$nbd_tcp_addr,port=$nbd_tcp_port,tls-creds=tls0 \
|
|
2>&1 | sed "s/$nbd_tcp_port/PORT/g"
|
|
$QEMU_IMG info --image-opts --object $obj2 \
|
|
driver=nbd,host=$nbd_tcp_addr,port=$nbd_tcp_port,tls-creds=tls0 \
|
|
2>&1 | sed "s/$nbd_tcp_port/PORT/g"
|
|
$QEMU_NBD_PROG -L -b $nbd_tcp_addr -p $nbd_tcp_port --object $obj1 \
|
|
--tls-creds=tls0
|
|
|
|
echo
|
|
echo "== check TLS with different CA fails =="
|
|
obj=tls-creds-x509,dir=${tls_dir}/client2,endpoint=client,id=tls0
|
|
$QEMU_IMG info --image-opts --object $obj \
|
|
driver=nbd,host=$nbd_tcp_addr,port=$nbd_tcp_port,tls-creds=tls0 \
|
|
2>&1 | sed "s/$nbd_tcp_port/PORT/g"
|
|
$QEMU_NBD_PROG -L -b $nbd_tcp_addr -p $nbd_tcp_port --object $obj \
|
|
--tls-creds=tls0
|
|
|
|
echo
|
|
echo "== perform I/O over TLS =="
|
|
QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
|
|
$QEMU_IO -c 'r -P 0x11 1m 1m' -c 'w -P 0x22 1m 1m' --image-opts \
|
|
--object tls-creds-x509,dir=${tls_dir}/client1,endpoint=client,id=tls0 \
|
|
driver=nbd,host=$nbd_tcp_addr,port=$nbd_tcp_port,tls-creds=tls0 \
|
|
2>&1 | _filter_qemu_io
|
|
|
|
$QEMU_IO -f $IMGFMT -r -U -c 'r -P 0x22 1m 1m' "$TEST_IMG" | _filter_qemu_io
|
|
|
|
echo
|
|
echo "== check TLS with authorization =="
|
|
|
|
nbd_server_stop
|
|
|
|
nbd_server_start_tcp_socket \
|
|
--object tls-creds-x509,dir=${tls_dir}/server1,endpoint=server,id=tls0,verify-peer=yes \
|
|
--object "authz-simple,id=authz0,identity=CN=localhost,, \
|
|
O=Cthulu Dark Lord Enterprises client1,,L=R'lyeh,,C=South Pacific" \
|
|
--tls-authz authz0 \
|
|
--tls-creds tls0 \
|
|
-f $IMGFMT "$TEST_IMG" 2>> "$TEST_DIR/server.log"
|
|
|
|
$QEMU_IMG info --image-opts \
|
|
--object tls-creds-x509,dir=${tls_dir}/client1,endpoint=client,id=tls0 \
|
|
driver=nbd,host=$nbd_tcp_addr,port=$nbd_tcp_port,tls-creds=tls0 \
|
|
2>&1 | sed "s/$nbd_tcp_port/PORT/g"
|
|
|
|
$QEMU_IMG info --image-opts \
|
|
--object tls-creds-x509,dir=${tls_dir}/client3,endpoint=client,id=tls0 \
|
|
driver=nbd,host=$nbd_tcp_addr,port=$nbd_tcp_port,tls-creds=tls0 \
|
|
2>&1 | sed "s/$nbd_tcp_port/PORT/g"
|
|
|
|
echo
|
|
echo "== final server log =="
|
|
cat "$TEST_DIR/server.log"
|
|
rm -f "$TEST_DIR/server.log"
|
|
|
|
# success, all done
|
|
echo "*** done"
|
|
rm -f $seq.full
|
|
status=0
|