From 7e998674d8e8a818abf66d30675d617ec30c6bbd Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 14 Sep 2026 16:25:22 -0700 Subject: [PATCH 1/3] Build the terminal code without a filesystem The terminal code is compiled for any WOLFSSH_TERM build. The window dimensions come from an ioctl or the console API and the terminal modes from termios, each already guarded on its own, so a client on a target without a filesystem can request a PTY and send its modes. - is included beside and , since port.h only pulls it in for a filesystem build --- src/internal.c | 3 ++- src/ssh.c | 4 ++-- wolfssh/port.h | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/internal.c b/src/internal.c index c721b7156..50620fcca 100644 --- a/src/internal.c +++ b/src/internal.c @@ -23546,7 +23546,7 @@ int SendChannelRequest(WOLFSSH* ssh, byte* name, word32 nameSz) } -#if defined(WOLFSSH_TERM) && !defined(NO_FILESYSTEM) +#ifdef WOLFSSH_TERM /* out is always a TERMINAL_MODES_MAX_SZ buffer, and one byte is held back * for the terminator CreateMode() appends */ @@ -23804,6 +23804,7 @@ int SendChannelTerminalResize(WOLFSSH* ssh, word32 columns, word32 rows, #ifdef HAVE_SYS_IOCTL_H #include + #include #endif static void GetTerminalInfo(word32* width, word32* height, diff --git a/src/ssh.c b/src/ssh.c index fa75c4177..80777cfec 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -1143,7 +1143,7 @@ int wolfSSH_connect(WOLFSSH* ssh) FALL_THROUGH; case CONNECT_CLIENT_CHANNEL_AGENT_REQUEST_SENT: - #if defined(WOLFSSH_TERM) && !defined(NO_FILESYSTEM) + #ifdef WOLFSSH_TERM if (ssh->sendTerminalRequest) { if ( (ssh->error = SendChannelTerminalRequest(ssh)) < WS_SUCCESS) { @@ -1939,7 +1939,7 @@ void* wolfSSH_GetPublicKeyCheckCtx(WOLFSSH* ssh) } -#if defined(WOLFSSH_TERM) && !defined(NO_FILESYSTEM) +#ifdef WOLFSSH_TERM /* Used to resize terminal window with shell connections * returns WS_SUCCESS on success */ int wolfSSH_ChangeTerminalSize(WOLFSSH* ssh, word32 columns, word32 rows, diff --git a/wolfssh/port.h b/wolfssh/port.h index e83833813..8e0616838 100644 --- a/wolfssh/port.h +++ b/wolfssh/port.h @@ -1799,6 +1799,7 @@ extern "C" { #if !defined(NO_TERMIOS) && defined(WOLFSSH_TERM) #if !defined(USE_WINDOWS_API) && !defined(MICROCHIP_PIC32) #include + #include #define WOLFSSH_TERMIOS struct termios #elif defined(USE_WINDOWS_API) #define WOLFSSH_TERMIOS DWORD From b5d4bedd81dafb83c854b462ebe634614f975ded Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 14 Sep 2026 16:25:22 -0700 Subject: [PATCH 2/3] Let a client-only build use SCP wolfscp.c builds its server half in a client-only build too, and that code calls wolfSSH_CleanPath(). Compile it and wolfSSH_GetPath() whenever SFTP or SCP is enabled, not just for a server build. - SCP's client half is guarded on NO_WOLFSSH_CLIENT, so the settings.h error rejecting a client-only SCP build goes with it --- src/internal.c | 3 +-- wolfssh/internal.h | 3 +-- wolfssh/settings.h | 4 ---- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/internal.c b/src/internal.c index 50620fcca..3416a7871 100644 --- a/src/internal.c +++ b/src/internal.c @@ -24062,8 +24062,7 @@ int SendChannelSuccess(WOLFSSH* ssh, word32 channelId, int success) } -#if (defined(WOLFSSH_SFTP) || defined(WOLFSSH_SCP)) && \ - !defined(NO_WOLFSSH_SERVER) +#if defined(WOLFSSH_SFTP) || defined(WOLFSSH_SCP) /* Checks if 'in' is absolute path, if not the returns the concat. of * 'defaultPath' | 'in'. This leaves 'in' as-is and does not handle * simplification of the path, such as removing ../ diff --git a/wolfssh/internal.h b/wolfssh/internal.h index c44bccf5a..d0b39c7ee 100644 --- a/wolfssh/internal.h +++ b/wolfssh/internal.h @@ -1045,8 +1045,7 @@ typedef struct HandshakeInfo { } privKey; } HandshakeInfo; -#if (defined(WOLFSSH_SFTP) || defined(WOLFSSH_SCP)) && \ - !defined(NO_WOLFSSH_SERVER) +#if defined(WOLFSSH_SFTP) || defined(WOLFSSH_SCP) WOLFSSH_LOCAL int wolfSSH_GetPath(const char* defaultPath, byte* in, word32 inSz, char* out, word32* outSz); #endif diff --git a/wolfssh/settings.h b/wolfssh/settings.h index e31560bd9..d161db1bd 100644 --- a/wolfssh/settings.h +++ b/wolfssh/settings.h @@ -65,10 +65,6 @@ extern "C" { #endif #endif -#if defined(WOLFSSH_SCP) && defined(NO_WOLFSSH_SERVER) - #error only SCP server side supported -#endif - /* Detect if ECC needs RNG */ #if !defined(HAVE_WC_ECC_SET_RNG) && \ defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \ From bca8449b519540a003e971ae6b235fb4453d5ec0 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 22 Sep 2026 17:40:44 -0700 Subject: [PATCH 3/3] tests: build regress.c in both one-sided configs regress.c compiles in a client-only build with keyboard-interactive and in a server-only build with SFTP. - the TestKb*() calls are gated on NO_WOLFSSH_SERVER like their definitions - the #endif lines after TestOct2DecRejectsInvalidNonLeadingDigit() close both of its guards, and the attribute test has its own WOLFSSH_SFTP block --- tests/regress.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/regress.c b/tests/regress.c index bb6de33d0..cbbe6b826 100644 --- a/tests/regress.c +++ b/tests/regress.c @@ -11880,8 +11880,7 @@ static void TestTerminalResizeBlockedAfterDisconnect(void) #endif /* WOLFSSH_TERM && !NO_FILESYSTEM */ #endif /* !NO_WOLFSSH_CLIENT */ -#ifdef WOLFSSH_SFTP -#ifndef NO_WOLFSSH_CLIENT +#if defined(WOLFSSH_SFTP) && !defined(NO_WOLFSSH_CLIENT) static void TestOct2DecRejectsInvalidNonLeadingDigit(void) { WOLFSSH_CTX* ctx; @@ -11901,9 +11900,10 @@ static void TestOct2DecRejectsInvalidNonLeadingDigit(void) wolfSSH_free(ssh); wolfSSH_CTX_free(ctx); } -#endif /* !NO_WOLFSSH_CLIENT */ +#endif /* WOLFSSH_SFTP && !NO_WOLFSSH_CLIENT */ +#ifdef WOLFSSH_SFTP /* fenrir 2479: the attribute encoder and decoder must agree. Extensions are * unimplemented, so an encode of WOLFSSH_FILEATRB_EXT writes a zero count and * the peer's decoder consumes the block instead of reading past it looking for @@ -16617,8 +16617,10 @@ int main(int argc, char** argv) TestKeyboardResponseNoUserAuthCallback(ssh, ctx); TestKeyboardResponseNullSsh(); TestKeyboardResponseNullCtx(ssh); + #ifndef NO_WOLFSSH_SERVER TestKbUsernameChangeDisconnects(); TestKbSameUserResponseSucceeds(); + #endif #endif /* TODO: add app-level regressions that simulate stdin EOF/password