Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ examples/sftpclient/wolfsftp
examples/scpclient/wolfscp

# applications
apps/wolfssh-options
apps/wolfssh/wolfssh
apps/wolfsshd/wolfsshd
apps/wolfsshd/test/test_configuration
Expand Down
4 changes: 4 additions & 0 deletions apps/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@

include apps/wolfssh/include.am
include apps/wolfsshd/include.am

noinst_PROGRAMS += apps/wolfssh-options
apps_wolfssh_options_SOURCES = apps/wolfssh-options.c
apps_wolfssh_options_DEPENDENCIES = src/libwolfssh.la
175 changes: 175 additions & 0 deletions apps/wolfssh-options.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/* wolfssh-options.c
*
* Copyright (C) 2014-2026 wolfSSL Inc.
*
* This file is part of wolfSSH.
*
* wolfSSH 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 3 of the License, or
* (at your option) any later version.
*
* wolfSSH 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 wolfSSH. If not, see <http://www.gnu.org/licenses/>.
*/


/*
* Build option probe for the test scripts. Prints each enabled build option,
* one per line. Not installed; a build tree artifact only.
*
* OPTIONS=$(./apps/wolfssh-options) || exit 1
* if ! echo "$OPTIONS" | grep -qx "FPKI"; then
* echo "built without FPKI, skipping"
* exit 77
* fi
*
* scripts/ runs from the build root and calls "./apps/wolfssh-options"; the
* wolfSSHd tests source ./wolfssh_options.sh for it. Match whole lines, so one
* option name cannot match another that has it as a prefix. A probe that will
* not run is a build problem, not an option being off.
*
* Each option prints under the same guard the library uses, so the output is
* the preprocessor's answer for this build. Covers every configure
* --enable/--disable that sets a macro, plus a few facts from the wolfSSL
* build; not --enable-examples, which defines nothing to test.
*
* To add an option, add a guard and a printf() below.
*/


#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef WOLFSSL_USER_SETTINGS
#include <wolfssl/wolfcrypt/settings.h>
#else
#include <wolfssl/options.h>
#endif
#include <wolfssh/ssh.h>
#include <wolfssh/internal.h>
#include <stdio.h>

/* internal.h derives the WOLFSSH_NO_* options from the wolfSSL build. */
#ifndef _WOLFSSH_INTERNAL_H_
#error "wolfssh-options.c requires wolfssh/internal.h"
Comment thread
ejohnstown marked this conversation as resolved.
#endif


int main(void)
{
/* Library features. NO_INLINE is shared with wolfSSL's --disable-inline,
* so INLINE is the effective state, not wolfSSH's configure answer. */
#ifndef NO_INLINE
Comment thread
padelsbach marked this conversation as resolved.
printf("INLINE\n");
#endif
#ifndef NO_WOLFSSH_SERVER
printf("SERVER\n");
#endif
#ifndef NO_WOLFSSH_CLIENT
printf("CLIENT\n");
#endif
#ifdef WOLFSSH_KEYGEN
printf("KEYGEN\n");
#endif
#ifdef WOLFSSH_KEYBOARD_INTERACTIVE
printf("KEYBOARD_INTERACTIVE\n");
#endif
#ifdef WOLFSSH_SCP
printf("SCP\n");
#endif
#ifdef WOLFSSH_SFTP
printf("SFTP\n");
#endif
#if defined(WOLFSSH_SFTP) && !defined(WOLFSSH_NO_SFTP_BUFFER_ZERO)
printf("SFTP_ZEROIZE\n");
#endif
#ifdef WOLFSSH_FWD
printf("FWD\n");
#endif
#ifdef WOLFSSH_TERM
printf("TERM\n");
#endif
#ifdef WOLFSSH_SHELL
printf("SHELL\n");
#endif
#ifdef WOLFSSH_AGENT
printf("AGENT\n");
#endif
#ifdef WOLFSSH_TPM
printf("TPM\n");
#endif
#ifdef WOLFSSH_SMALL_STACK
printf("SMALL_STACK\n");
#endif
#ifdef WOLFSSH_ALLOW_NONE_CIPHER
printf("NONE_CIPHER\n");
#endif
/* Same guard as wIsSymlink in port.h. */
#if defined(WOLFSSH_HAVE_SYMLINK) && \
(defined(WOLFSSH_SFTP) || defined(WOLFSSH_SCP))
printf("SYMLINK_CHECK\n");
#endif

/* Certificates. */
#ifdef WOLFSSH_CERTS
printf("CERTS\n");
#endif
#ifdef WOLFSSH_OSSH_CERTS
printf("OSSH_CERTS\n");
#endif
/* Gates wolfSSHd's AuthorizedUPNDomains check, the same guard auth.c
* uses, plus cert support, without which no cert reaches it. Not
* WOLFSSH_NO_FPKI: that only turns off certman.c's profile enforcement,
* which most CI workflows do. */
#if defined(WOLFSSL_FPKI) && defined(WOLFSSH_CERTS)
printf("FPKI\n");
Comment thread
padelsbach marked this conversation as resolved.
#endif

/* PQC Options */
#ifndef WOLFSSH_NO_MLDSA
printf("MLDSA\n");
#endif
/* Same guard as cannedKeyAlgoNamesHostKey in src/internal.c: the
* composite needs the ECDSA half too. */
#if !defined(WOLFSSH_NO_MLDSA87) && \
!defined(WOLFSSH_NO_ECDSA_SHA2_NISTP384) && !defined(NO_SHA512)
printf("MLDSA87_ES384\n");
#endif

/* Applications. */
#ifdef WOLFSSH_SSHCLIENT
printf("SSHCLIENT\n");
#endif
#ifdef WOLFSSH_SSHD
printf("SSHD\n");
#endif

/* wolfSSHd password check backends; with none, no password login. */
#ifdef WOLFSSH_USE_PAM
printf("PAM\n");
#endif
#ifdef WOLFSSH_HAVE_LIBCRYPT
printf("LIBCRYPT\n");
#endif
#ifdef WOLFSSH_HAVE_LIBLOGIN
printf("LIBLOGIN\n");
#endif

/* --enable-debug, so there is WLOG() output to inspect. */
#ifdef DEBUG_WOLFSSH
printf("DEBUG\n");
#endif

/* Fault injected non-blocking IO, so the examples need -N. */
#ifdef WOLFSSH_TEST_BLOCK
printf("TEST_BLOCK\n");
#endif

return 0;
}
19 changes: 10 additions & 9 deletions apps/wolfsshd/test/run_all_sshd_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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=""
Expand Down Expand Up @@ -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"
Expand Down
19 changes: 10 additions & 9 deletions apps/wolfsshd/test/ssh_kex_algos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# sshd local test

ROOT_PWD=$(pwd)
. ./wolfssh_options.sh
cd ../../..

TEST_CLIENT="./apps/wolfssh/wolfssh"
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions apps/wolfsshd/test/sshd_bad_sftp_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# sshd local test

PWD=`pwd`
. ./wolfssh_options.sh
cd ../../..

TEST_SFTP_CLIENT="./examples/sftpclient/wolfsftp"
Expand All @@ -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

Expand Down
12 changes: 7 additions & 5 deletions apps/wolfsshd/test/sshd_empty_password_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 -----"
Expand Down
6 changes: 6 additions & 0 deletions apps/wolfsshd/test/sshd_large_sftp_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# sshd local test

PWD=`pwd`
. ./wolfssh_options.sh
cd ../../..

TEST_SFTP_CLIENT="./examples/sftpclient/wolfsftp"
Expand All @@ -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.
Expand Down
3 changes: 2 additions & 1 deletion apps/wolfsshd/test/sshd_ossh_cert_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
6 changes: 6 additions & 0 deletions apps/wolfsshd/test/sshd_scp_fail.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# sshd local test

PWD=`pwd`
. ./wolfssh_options.sh
cd ../../..

TEST_SCP_CLIENT="./examples/scpclient/wolfscp"
Expand All @@ -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-$$"
Expand Down
7 changes: 3 additions & 4 deletions apps/wolfsshd/test/sshd_x509_upn_fail.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading
Loading