diff --git a/apps/wolfsshd/test/run_all_sshd_tests.sh b/apps/wolfsshd/test/run_all_sshd_tests.sh index 7f34ee00..f1ee3e33 100755 --- a/apps/wolfsshd/test/run_all_sshd_tests.sh +++ b/apps/wolfsshd/test/run_all_sshd_tests.sh @@ -16,6 +16,9 @@ test_cases=( # Set defaults USER=$USER +# Build options for this tree; defines WOLFSSH_OPTIONS and wolfssh_has. +. ./wolfssh_options.sh + # Parse arguments MATCH="" EXCLUDE="" @@ -424,16 +427,14 @@ else stop_wolfsshd fi - # ML-DSA composite host key test. Runs when we control the local daemon. - # The client side uses an ECC key since we only test the host key here. - # sshd_config_test_mldsa has no other host key, so a build without ML-DSA - # cannot start the daemon at all; check for support out here rather than - # letting the test script skip, which would come too late. ML-DSA comes from - # wolfSSL (HAVE_DILITHIUM) and has no wolfSSH configure option, so probe the - # client's algorithm list. The closed port keeps the probe from connecting. + # ML-DSA composite host key test. Runs when we control the local daemon; + # the client uses an ECC key since only the host key is under test. + # sshd_config_test_mldsa has no other host key, so an ML-DSA-less build + # cannot start the daemon; check out here, not in the test script. The + # check is the composite, not the umbrella: the ECDSA half can be missing + # on its own. if [ "$USING_LOCAL_HOST" == 1 ]; then - if ../../../examples/client/client -E -u "$USER" -h 127.0.0.1 -p 1 \ - 2>/dev/null | grep -q "ssh-mldsa87-es384@wolfssl.com"; then + if wolfssh_has MLDSA87_ES384; then start_wolfsshd "sshd_config_test_mldsa" run_test "sshd_mldsa_composite_test.sh" printf "Shutting down test wolfSSHd\n" diff --git a/apps/wolfsshd/test/ssh_kex_algos.sh b/apps/wolfsshd/test/ssh_kex_algos.sh index f6ec9d0f..74b2ec52 100755 --- a/apps/wolfsshd/test/ssh_kex_algos.sh +++ b/apps/wolfsshd/test/ssh_kex_algos.sh @@ -3,6 +3,7 @@ # sshd local test ROOT_PWD=$(pwd) +. ./wolfssh_options.sh cd ../../.. TEST_CLIENT="./apps/wolfssh/wolfssh" @@ -18,18 +19,18 @@ HOST_IP="$1" HOST_PORT="$2" USER_SET="$3" -# check if wolfssh app was compiled -OUTPUT=$("$TEST_CLIENT" -V) -RESULT=$? -if [ "$RESULT" != 0 ]; then +# check if wolfssh app was compiled. test_if_supported also drives the example +# client, and libtool can leave a script behind, so run each rather than -x. +if ! wolfssh_has SSHCLIENT || [ ! -x "$TEST_CLIENT" ] \ + || [ ! -x ./examples/client/client ] \ + || "$TEST_CLIENT" -V 2>&1 | grep -q "does not exist" \ + || ./examples/client/client "-?" 2>&1 | grep -q "does not exist"; then echo "wolfSSH app not compiled in"; exit 77 fi # Debug mode needs to be on to inspect the debug output -printf "$OUTPUT" | grep "DEBUG" -RESULT=$? -if [ "$RESULT" != 0 ]; then +if ! wolfssh_has DEBUG; then echo "wolfSSH app not compiled with debug mode"; exit 77 fi @@ -59,8 +60,8 @@ printf "\n" # host key algorithms sent. find_substring_of_algos() { # Extract the substring between start and end lines - SUBSTRING=$(printf "$OUTPUT" | grep -A100 "Server Host Key Algorithms") - SUBSTRING=$(printf "$SUBSTRING" | grep -v -A95 "DKI: Enc Algorithms") + SUBSTRING=$(printf '%s\n' "$OUTPUT" | grep -A100 "Server Host Key Algorithms") + SUBSTRING=$(printf '%s\n' "$SUBSTRING" | grep -v -A95 "DKI: Enc Algorithms") } # take input argument $1 and checks if it is in the SUBSTRING diff --git a/apps/wolfsshd/test/sshd_bad_sftp_test.sh b/apps/wolfsshd/test/sshd_bad_sftp_test.sh index c5a74a39..362de3bf 100755 --- a/apps/wolfsshd/test/sshd_bad_sftp_test.sh +++ b/apps/wolfsshd/test/sshd_bad_sftp_test.sh @@ -3,6 +3,7 @@ # sshd local test PWD=`pwd` +. ./wolfssh_options.sh cd ../../.. TEST_SFTP_CLIENT="./examples/sftpclient/wolfsftp" @@ -16,6 +17,11 @@ if [ -z "$1" ] || [ -z "$2" ]; then exit 1 fi +if ! wolfssh_has SFTP || [ ! -x "$TEST_SFTP_CLIENT" ]; then + echo "SFTP client not available in this build, skipping" + exit 77 +fi + mkdir test-$$ mkdir test-$$/subfolder diff --git a/apps/wolfsshd/test/sshd_empty_password_test.sh b/apps/wolfsshd/test/sshd_empty_password_test.sh index 614c438a..c5474290 100755 --- a/apps/wolfsshd/test/sshd_empty_password_test.sh +++ b/apps/wolfsshd/test/sshd_empty_password_test.sh @@ -8,6 +8,13 @@ if [ -z "$1" ] || [ -z "$2" ]; then exit 1 fi +# A password login can only be checked when a backend was compiled in. +. ./wolfssh_options.sh +if ! wolfssh_has PAM && ! wolfssh_has LIBCRYPT && ! wolfssh_has LIBLOGIN; then + echo "SKIP: wolfsshd built without a password check backend" + exit 77 +fi + TEST_HOST="$1" TEST_PORT="$2" if [ ! -z "$3" ]; then @@ -51,11 +58,6 @@ sleep 1 stop_wolfsshd # log.txt is owned by root (wolfsshd ran via sudo); use sudo to read it. -if sudo grep -q "No compiled in password check" ./log.txt; then - echo "SKIP: wolfsshd built without libcrypt/liblogin support" - exit 77 -fi - if sudo grep -q "Error checking password" ./log.txt; then echo "FAIL: empty-password NULL-guard regression detected" echo "----- log.txt -----" diff --git a/apps/wolfsshd/test/sshd_large_sftp_test.sh b/apps/wolfsshd/test/sshd_large_sftp_test.sh index 71be8368..6699eae2 100755 --- a/apps/wolfsshd/test/sshd_large_sftp_test.sh +++ b/apps/wolfsshd/test/sshd_large_sftp_test.sh @@ -3,6 +3,7 @@ # sshd local test PWD=`pwd` +. ./wolfssh_options.sh cd ../../.. TEST_SFTP_CLIENT="./examples/sftpclient/wolfsftp" @@ -16,6 +17,11 @@ if [ -z "$1" ] || [ -z "$2" ]; then exit 1 fi +if ! wolfssh_has SFTP || [ ! -x "$TEST_SFTP_CLIENT" ]; then + echo "SFTP client not available in this build, skipping" + exit 77 +fi + # wolfSSHd confines SFTP access to the user's home directory, so the remote # file must live under it. Resolve the same home directory wolfSSHd uses # (the passwd entry), falling back to $HOME. diff --git a/apps/wolfsshd/test/sshd_ossh_cert_test.sh b/apps/wolfsshd/test/sshd_ossh_cert_test.sh index f78a2960..5fce73c2 100755 --- a/apps/wolfsshd/test/sshd_ossh_cert_test.sh +++ b/apps/wolfsshd/test/sshd_ossh_cert_test.sh @@ -28,13 +28,14 @@ set +m # quiet job-control "Terminated" notices when stopping the daemon PWD0=$(pwd) +. ./wolfssh_options.sh cd ../../.. ROOT=$(pwd) skip() { echo "$1"; cd "$PWD0"; exit 77; } # Only meaningful when wolfSSHd was built with OpenSSH certificate support. -grep -q "WOLFSSH_OSSH_CERTS" config.log 2>/dev/null || \ +wolfssh_has OSSH_CERTS || \ skip "wolfSSHd not built with --enable-ossh-certs, skipping" WOLFSSHD="$ROOT/apps/wolfsshd/wolfsshd" diff --git a/apps/wolfsshd/test/sshd_scp_fail.sh b/apps/wolfsshd/test/sshd_scp_fail.sh index 05797257..02569853 100755 --- a/apps/wolfsshd/test/sshd_scp_fail.sh +++ b/apps/wolfsshd/test/sshd_scp_fail.sh @@ -3,6 +3,7 @@ # sshd local test PWD=`pwd` +. ./wolfssh_options.sh cd ../../.. TEST_SCP_CLIENT="./examples/scpclient/wolfscp" @@ -16,6 +17,11 @@ if [ -z "$1" ] || [ -z "$2" ]; then exit 1 fi +if ! wolfssh_has SCP || [ ! -x "$TEST_SCP_CLIENT" ]; then + echo "SCP client not available in this build, skipping" + exit 77 +fi + mkdir test-$$ OUTDIR="`pwd`/test-$$" diff --git a/apps/wolfsshd/test/sshd_x509_upn_fail.sh b/apps/wolfsshd/test/sshd_x509_upn_fail.sh index 559356dd..0a19dcdb 100755 --- a/apps/wolfsshd/test/sshd_x509_upn_fail.sh +++ b/apps/wolfsshd/test/sshd_x509_upn_fail.sh @@ -6,11 +6,10 @@ # "example". The wolfSSHd UPN domain check must therefore reject the cert. PWD=`pwd` +. ./wolfssh_options.sh -# The UPN domain check is compiled only when wolfSSL is built with FPKI. Probe -# the daemon binary's help output, which prints an FPKI marker under the same -# build guard, and skip when the check is not present. -if ! ../wolfsshd "-?" 2>&1 | grep -q "FPKI"; then +# The UPN domain check is compiled only when wolfSSL is built with FPKI. +if ! wolfssh_has FPKI; then echo "wolfSSHd built without FPKI; UPN domain check not compiled in, skipping" exit 77 fi diff --git a/apps/wolfsshd/test/wolfssh_options.sh b/apps/wolfsshd/test/wolfssh_options.sh new file mode 100755 index 00000000..0c99fafb --- /dev/null +++ b/apps/wolfsshd/test/wolfssh_options.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +# Build option probe for the wolfSSHd test scripts. Source it before any cd, +# since it resolves the tree from the script's own location: +# +# . ./wolfssh_options.sh +# if ! wolfssh_has SFTP; then +# echo "built without SFTP, skipping" +# exit 77 +# fi +# +# The tests run from this directory, so the one path to the build tree lives +# here. WOLFSSH_ROOT is absolute, so it survives their cd ../../.. . A probe +# that will not run is a build problem, not an option being off. + +WOLFSSH_ROOT=$(cd "$(dirname "$0")/../../.." && pwd) || exit 1 +WOLFSSH_OPTIONS=$("$WOLFSSH_ROOT/apps/wolfssh-options") || { + echo "fail: could not run $WOLFSSH_ROOT/apps/wolfssh-options" + exit 1 +} + +# Whole line match, so one option name cannot match another that has it as a +# prefix. +wolfssh_has() { + echo "$WOLFSSH_OPTIONS" | grep -qx "$1" +} diff --git a/apps/wolfsshd/wolfsshd.c b/apps/wolfsshd/wolfsshd.c index 5b023955..a294661a 100644 --- a/apps/wolfsshd/wolfsshd.c +++ b/apps/wolfsshd/wolfsshd.c @@ -195,19 +195,13 @@ static void ShowUsage(void) printf("wolfSSHd %s linked with wolfSSL %s\n", LIBWOLFSSH_VERSION_STRING, LIBWOLFSSL_VERSION_STRING); printf(" -? display this help and exit\n"); - printf(" -f Configuration file to use, default is " - "/etc/ssh/sshd_config\n"); + printf(" -f Configuration file to use, default is:\n" + " /etc/ssh/sshd_config\n"); printf(" -p Port number to listen on\n"); printf(" -d Turn on debug mode\n"); printf(" -D Run in foreground (do not detach)\n"); printf(" -h host private key file to use\n"); printf(" -E append to log file\n"); -#ifdef WOLFSSL_FPKI - /* build-capability note, separated from the option list; also greppable by - * test scripts, for the cert UPN domain check (AuthorizedUPNDomains) */ - printf("\n"); - printf("Build features: FPKI certificate UPN domain checking\n"); -#endif } diff --git a/examples/client/client.c b/examples/client/client.c index f9321bda..b397075e 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -101,8 +101,8 @@ static void ShowUsage(void) printf(" -x exit after successful connection without doing\n" " read/write\n"); #ifdef WOLFSSH_TEST_BLOCK - printf("-N non-blocking sockets required when compiled with " - "WOLFSSH_TEST_BLOCK\n"); + printf(" -N non-blocking sockets, required when compiled with\n" + " WOLFSSH_TEST_BLOCK\n"); #else printf(" -N use non-blocking sockets\n"); #endif @@ -129,11 +129,6 @@ static void ShowUsage(void) printf(" -k set the list of key algos\n"); printf(" -C set the list of encrypt algos\n"); printf(" -q turn off debugging output\n"); -#ifndef WOLFSSH_HAVE_SYMLINK - /* report disabled symlink checking so test scripts can skip the - * symlink-rejection cases the server would otherwise follow */ - printf(" symlink checking off (e.g. WOLFSSH_NO_SYMLINK_CHECK)\n"); -#endif } diff --git a/scripts/external.test b/scripts/external.test index d7c50752..7dbc2e78 100755 --- a/scripts/external.test +++ b/scripts/external.test @@ -13,10 +13,14 @@ else fi # test for nonblocking only -./examples/client/client -h | grep WOLFSSH_TEST_BLOCK -if [ $? -eq 0 ] +WOLFSSH_OPTIONS=$(./apps/wolfssh-options) || { + echo "fail: could not run ./apps/wolfssh-options" + exit 1 +} + +if echo "$WOLFSSH_OPTIONS" | grep -qx "TEST_BLOCK" then - echo "macro NO_WOLFSSH_CLIENT was used" + echo "macro WOLFSSH_TEST_BLOCK was used" echo "skipping for now" exit 77 fi diff --git a/scripts/fwd.test b/scripts/fwd.test index 1b1c9eb8..fb094955 100755 --- a/scripts/fwd.test +++ b/scripts/fwd.test @@ -42,7 +42,12 @@ then fi ## test for nonblocking only -if ./examples/client/client "-?" 2>&1 | grep WOLFSSH_TEST_BLOCK >/dev/null 2>&1 +WOLFSSH_OPTIONS=$(./apps/wolfssh-options) || { + echo "fail: could not run ./apps/wolfssh-options" + exit 1 +} + +if echo "$WOLFSSH_OPTIONS" | grep -qx "TEST_BLOCK" then echo "skipping: non-blocking test" exit 77 diff --git a/scripts/get-put.test b/scripts/get-put.test index 9fedb6a7..10a30561 100755 --- a/scripts/get-put.test +++ b/scripts/get-put.test @@ -6,25 +6,28 @@ then exit 1 fi +WOLFSSH_OPTIONS=$(./apps/wolfssh-options) || { + echo "fail: could not run ./apps/wolfssh-options" + exit 1 +} + # test SFTP client is working (that NO_WOLFSSH_CLIENT was not used) +if ! echo "$WOLFSSH_OPTIONS" | grep -qx "CLIENT" +then + echo "macro NO_WOLFSSH_CLIENT was used" + echo "skipping test" + exit 77 +fi + ./examples/sftpclient/wolfsftp -h if [ $? -ne 0 ] then - ./examples/sftpclient/wolfsftp -h | grep NO_WOLFSSH_CLIENT - if [ $? -eq 0 ] - then - echo "macro NO_WOLFSSH_CLIENT was used" - echo "skipping test" - exit 77 - else - echo "wolfSFTP client not compiled in or not working" - exit 1 - fi + echo "wolfSFTP client not compiled in or not working" + exit 1 fi # test for nonblocking only -./examples/client/client -h | grep WOLFSSH_TEST_BLOCK -if [ $? -eq 0 ] +if echo "$WOLFSSH_OPTIONS" | grep -qx "TEST_BLOCK" then echo "macro WOLFSSH_TEST_BLOCK was used" exit 77 diff --git a/scripts/scp.test b/scripts/scp.test index fe7efe1f..20f9737e 100755 --- a/scripts/scp.test +++ b/scripts/scp.test @@ -10,8 +10,12 @@ ready_file=`pwd`/wolfssh_scp_ready$$ # test for nonblocking only - wolfscp does not support -N flag for non-blocking # mode, so we must skip when TEST_BLOCK is enabled -./examples/client/client -h | grep WOLFSSH_TEST_BLOCK -if [ $? -eq 0 ] +WOLFSSH_OPTIONS=$(./apps/wolfssh-options) || { + echo "fail: could not run ./apps/wolfssh-options" + exit 1 +} + +if echo "$WOLFSSH_OPTIONS" | grep -qx "TEST_BLOCK" then echo "WOLFSSH_TEST_BLOCK detected" echo "wolfscp client does not support non-blocking mode, skipping test" @@ -192,12 +196,9 @@ if test $RESULT -eq 0; then exit 1 fi -# The symlink-rejection guard is compiled out by WOLFSSH_NO_SYMLINK_CHECK, which -# the example client reports in its usage output (-?). Skip this test when it is -# set: the server then follows symlinks by design and the check below would -# false-fail. -./examples/client/client '-?' | grep WOLFSSH_NO_SYMLINK_CHECK -if [ $? -eq 0 ]; then +# Without the symlink-rejection guard the server follows symlinks by design, +# so the check below would false-fail. +if ! echo "$WOLFSSH_OPTIONS" | grep -qx "SYMLINK_CHECK"; then echo "symlink checking disabled, skipping symlink test" else echo "Test that the server refuses to follow a symlink (server to local)" diff --git a/scripts/sftp.test b/scripts/sftp.test index 261810ac..4e6a5763 100755 --- a/scripts/sftp.test +++ b/scripts/sftp.test @@ -10,9 +10,13 @@ nonblockingOnly=0 [ ! -x ./examples/sftpclient/wolfsftp ] && echo -e "\n\nwolfSFTP client doesn't exist" && exit 1 +WOLFSSH_OPTIONS=$(./apps/wolfssh-options) || { + echo "fail: could not run ./apps/wolfssh-options" + exit 1 +} + # test for if the SFTP client works -./examples/sftpclient/wolfsftp -h | grep NO_WOLFSSH_CLIENT -if [ $? -eq 0 ] +if ! echo "$WOLFSSH_OPTIONS" | grep -qx "CLIENT" then echo "macro NO_WOLFSSH_CLIENT was used" echo "skipping test" @@ -20,10 +24,9 @@ then fi # test for nonblocking only -./examples/client/client -h | grep WOLFSSH_TEST_BLOCK -if [ $? -eq 0 ] +if echo "$WOLFSSH_OPTIONS" | grep -qx "TEST_BLOCK" then - echo "macro NO_WOLFSSH_CLIENT was used" + echo "macro WOLFSSH_TEST_BLOCK was used" nonblockingOnly=1 fi