Skip to content
Open
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
13 changes: 7 additions & 6 deletions .github/workflows/windows-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,13 @@ jobs:
run: nuget restore ${{env.WOLFSSL_SOLUTION_FILE_PATH}}

# These env paths already include the wolfssh/ and wolfssl/ checkout
# prefixes, so they must run from the workspace root (as the build job does).
- name: updated user_settings.h for sshd and x509
run: cp ${{env.USER_SETTINGS_H_NEW}} ${{env.USER_SETTINGS_H}}

- name: replace wolfSSL user_settings.h with wolfSSH user_settings.h
run: get-content ${{env.USER_SETTINGS_H_NEW}} | %{$_ -replace "if 0","if 1"}
# prefixes, so this runs from the default working directory, the workspace
# root.
- name: Enable wolfSSH options (sshd, sftp, x509) in user_settings.h
shell: bash
run: |
sed -i 's/#if 0/#if 1/g' ${{env.USER_SETTINGS_H_NEW}}
cp ${{env.USER_SETTINGS_H_NEW}} ${{env.USER_SETTINGS_H}}

# WholeProgramOptimization=false disables /GL so the v142-independent objects
# link without a cross-version code-generation requirement (C1047).
Expand Down
24 changes: 23 additions & 1 deletion examples/echoserver/echoserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -2260,6 +2260,11 @@ static int LoadPasswdList(StrList* strList, PwMapList* mapList)
int count = 0;

while (strList) {
if (WSTRLEN(strList->str) >= sizeof names - 1) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 [Low] Over-long entry guard copy-pasted three times with a non-identifying message · Maintainability

Verified against the tree — the same five-line guard appears verbatim at lines 2263, 2297 and 2338. The bound is correct: names[256], guard rejects len >= 255, and WSTRNCPY(names, strList->str, sizeof names - 1) maps to strncpy_s(names, 255, src, 255), which __fastfails exactly when strlen(src) >= 255, so the guard covers precisely the crashing set. Two small polish points: the message "Ignoring over-long entry\n" does not say which entry, unlike the adjacent fprintf(stderr, "Ignoring password: %s\n", names) a few lines down; and the guard's sizeof names - 1 must stay in lockstep with the WSTRNCPY count argument or the protection silently lapses. (The skipped entries also no longer bump count, but every caller at lines 3204-3249 discards the return value, so that is a non-issue.)

Fix: Print a truncated prefix of the offending entry so the operator can identify it. Optionally factor the guard into a small CopyListEntry(names, sizeof names, strList->str) helper shared by the three loaders.

fprintf(stderr, "Ignoring over-long entry\n");
strList = strList->next;
continue;
}
WSTRNCPY(names, strList->str, sizeof names - 1);
passwd = WSTRCHR(names, ':');
if (passwd != NULL) {
Expand Down Expand Up @@ -2289,6 +2294,11 @@ static int LoadKeyboardList(StrList* strList, PwMapList* mapList,
int count = 0;

while (strList) {
if (WSTRLEN(strList->str) >= sizeof names - 1) {
fprintf(stderr, "Ignoring over-long entry\n");
strList = strList->next;
continue;
}
WSTRNCPY(names, strList->str, sizeof names - 1);
passwd = WSTRCHR(names, ':');
if (passwd != NULL) {
Expand Down Expand Up @@ -2325,6 +2335,11 @@ static int LoadPubKeyList(StrList* strList, int format, PwMapList* mapList)
buf = NULL;
bufSz = 0;

if (WSTRLEN(strList->str) >= sizeof names - 1) {
fprintf(stderr, "Ignoring over-long entry\n");
strList = strList->next;
continue;
}
WSTRNCPY(names, strList->str, sizeof names - 1);
fileName = WSTRCHR(names, ':');
if (fileName != NULL) {
Expand Down Expand Up @@ -2841,6 +2856,13 @@ static INLINE void SignalTcpReady(tcp_ready* ready, word16 port)
ready->port = port;
pthread_cond_signal(&ready->cond);
pthread_mutex_unlock(&ready->mutex);
#elif defined(USE_WINDOWS_API) && defined(NO_MAIN_DRIVER) && \
!defined(SINGLE_THREADED)
EnterCriticalSection(&ready->cs);
ready->ready = 1;
ready->port = port;
LeaveCriticalSection(&ready->cs);
SetEvent(ready->readyEvent);
#else
WOLFSSH_UNUSED(ready);
WOLFSSH_UNUSED(port);
Expand Down Expand Up @@ -2986,7 +3008,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
}
else {
port = (word16)atoi(myoptarg);
#if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
#if !defined(NO_MAIN_DRIVER)
if (port == 0) {
ES_ERROR("port number cannot be 0");
}
Expand Down
14 changes: 11 additions & 3 deletions examples/sftpclient/sftpclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ static void myStatusCb(WOLFSSH* sshIn, word32* bytes, char* name)
static word32 lastOutputTime = 0;
static word32 lastPrintedBytes[2] = {0, 0};
word32 elapsedTime;
word32 nameSz;
#endif
char buf[80];
word64 longBytes = ((word64)bytes[1] << 32) | bytes[0];
Expand All @@ -181,8 +182,11 @@ static void myStatusCb(WOLFSSH* sshIn, word32* bytes, char* name)
lastOutputTime = 0; /* Reset timer for new file transfer */
lastPrintedBytes[0] = 0;
lastPrintedBytes[1] = 0;
WMEMSET(currentFile, 0, WOLFSSH_MAX_FILENAME);
WSTRNCPY(currentFile, name, WOLFSSH_MAX_FILENAME);
WMEMSET(currentFile, 0, sizeof(currentFile));
nameSz = (word32)WSTRLEN(name);
if (nameSz >= sizeof(currentFile))
return;
WMEMCPY(currentFile, name, nameSz + 1);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 [Low] myStatusCb early return permanently suppresses all progress output for over-long file names · Logic

All three scan modes independently confirmed this against the tree. The new length guard sits AFTER the state reset, so when nameSz >= sizeof(currentFile) (257, since currentFile is static char currentFile[WOLFSSH_MAX_FILENAME + 1] at sftpclient.c:104 and WOLFSSH_MAX_FILENAME is 256 per wolfssh/ssh.h:572) the callback has already zeroed currentFile and reset startTime/lastOutputTime/lastPrintedBytes before it bails. Because currentFile is left empty, the next call's WSTRNCMP(currentFile, name, WSTRLEN(name)) still mismatches, so every subsequent call re-enters the reset branch and returns again — progress reporting is permanently suppressed for the entire transfer, and the WSNPRINTF/WFPUTS print at lines 192-207 is never reached. Previously on POSIX WSTRNCPY(currentFile, name, WOLFSSH_MAX_FILENAME) truncated the name into the buffer and fell through to print, so this is a regression on POSIX. On Windows the old WSTRNCPY expanded to strncpy_s(currentFile, 256, name, 256), a constraint violation that __fastfails for strlen(name) >= 256 — the guard genuinely fixes that crash, so the direction is right; the issue is that it trades a crash for silence rather than clamping. The guard itself is buffer-correct: nameSz == 256 copies 257 bytes and fits exactly, no off-by-one. Triggering input is ordinary: statusCb receives the caller-supplied local path from wolfSSH_SFTP_Get/wolfSSH_SFTP_Put, and POSIX PATH_MAX is 4096. Severity views differed — the review mode rated this Medium/SUGGEST, review-security and bugs rated it Low; the…

Fix: Clamp nameSz to sizeof(currentFile) - 1 and fall through instead of returning. This keeps the strncpy_s-safe property the PR is after, populates currentFile so the name-change branch stops re-triggering, and preserves the pre-existing truncate-and-print behavior on POSIX. It does not address the pre-existing dead timeout for long names — to fix that too, compare over the stored length (e.g. WSTRNCMP(currentFile, name, WSTRLEN(currentFile))) or track nameSz in a static alongside currentFile.

elapsedTime = currentTime - startTime;
WSNPRINTF(buf, sizeof(buf), "Processed %8llu\t bytes in %d seconds\r",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 [Low] Leftover WOLFSSH_MAX_FILENAME memsets inconsistent with new sizeof(currentFile) · Consistency

Verified against the tree. Line 185 was updated to WMEMSET(currentFile, 0, sizeof(currentFile)), but lines 198, 674 and 785 still use WMEMSET(currentFile, 0, WOLFSSH_MAX_FILENAME). currentFile is declared char currentFile[WOLFSSH_MAX_FILENAME + 1] (line 102), so those three leave the final byte untouched. This is harmless today — after the new WMEMCPY(currentFile, name, nameSz + 1) with nameSz == 256, byte [256] is the NUL, so a 256-byte memset still yields an empty string — but the mismatch is precisely the off-by-one class this PR set out to eliminate, and it now reads as an oversight next to the updated line 185.

Fix: Switch lines 198, 674 and 785 to sizeof(currentFile) for consistency with line 185.


Note: Referenced line (examples/sftpclient/sftpclient.c:198) is outside the diff hunk. Comment anchored to nearest changed region.

Expand Down Expand Up @@ -1445,6 +1449,7 @@ static int doAutopilot(int cmd, char* local, char* remote)
int ret = WS_SUCCESS;
char fullpath[128] = ".";
WS_SFTPNAME* name = NULL;
word32 remoteSz;
byte remoteAbsPath = 0;

/* check if is absolute path before making it one */
Expand All @@ -1462,8 +1467,11 @@ static int doAutopilot(int cmd, char* local, char* remote)

if (remoteAbsPath) {
/* use remote absolute path if provided */
remoteSz = (word32)WSTRLEN(remote);
if (remoteSz >= sizeof(fullpath))
return WS_BUFFER_E;
WMEMSET(fullpath, 0, sizeof(fullpath));
WSTRNCPY(fullpath, remote, sizeof(fullpath) - 1);
WMEMCPY(fullpath, remote, remoteSz + 1);
}
else {
err = doBuildRemotePath(remote, fullpath, sizeof(fullpath), &name);
Expand Down
15 changes: 12 additions & 3 deletions src/wolfscp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1908,7 +1908,11 @@ static char* MakeScpCmd(const char* name, char dir, void* heap)
char* cmd;
int sz;

#ifdef USE_WINDOWS_API

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 [Low] MakeScpCmd now repeats the "scp -%c %s" format string three times · Maintainability

Verified against the tree. Adding the Windows WSCPRINTF branch brings the format-string count in this one function to three: the Windows length probe, the POSIX length probe, and the actual write. The probe result sizes the WMALLOC, so any future divergence between a probe copy and the write copy silently becomes either a heap overflow or a truncated command. The two probes are also mutually exclusive at compile time, so no build ever cross-checks them against each other. The current logic is correct — _scprintf returns chars-excluding-NUL (-1 on error, caught by sz <= 0), and the subsequent _snprintf_s(cmd, sz, _TRUNCATE, ...) writes at most sz-1 chars plus NUL, which fits exactly — but the duplication is the fragile part.

Fix: Hoist the format into a file-local #define so the probe and the write cannot drift. Use a macro rather than a const char* local — MSVC emits C4774 for non-literal format strings passed to the CRT _s/_scprintf family.

sz = WSCPRINTF("scp -%c %s", dir, name) + 1;
Comment thread
aidangarske marked this conversation as resolved.
Comment thread
aidangarske marked this conversation as resolved.
#else
sz = WSNPRINTF(NULL, 0, "scp -%c %s", dir, name) + 1;
#endif
if (sz <= 0) {
return NULL;
}
Expand Down Expand Up @@ -2663,10 +2667,15 @@ static ScpDir* ScpNewDir(void *fs, const char* path, void* heap)
int ScpPushDir(void *fs, ScpSendCtx* ctx, const char* path, void* heap)
{
ScpDir* entry;
word32 pathSz;

if (ctx == NULL || path == NULL)
return WS_BAD_ARGUMENT;

pathSz = (word32)WSTRLEN(path);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 [Medium] No test coverage for the new input-validation reject paths · Test Coverage

Verified against the tree. The PR adds four new bounds rejects — ScpPushDir -> WS_BUFFER_E (wolfscp.c:2676), doAutopilot -> WS_BUFFER_E (sftpclient.c:1471), the three echoserver LoadPasswdList/LoadKeyboardList/LoadPubKeyList skip-and-continue guards (echoserver.c:2263, 2297, 2338), and the myStatusCb name guard — and none of them gain a test. The stated verification is that the pre-existing Windows suite stops crashing, which exercises only the under-limit path in every case; the new over-limit branches are entirely uncovered on both POSIX and Windows. ScpPushDir is the one worth covering: it is a genuine behavior change (was silently truncating at DEFAULT_SCP_FILE_NAME_SZ - 1 and returning WS_SUCCESS, now rejects at >= 1024 — confirmed dirName[DEFAULT_SCP_FILE_NAME_SZ] at wolfscp.h:95 and the 1024 define at wolfscp.h:47), and its three callers map the failure to three different outcomes — WS_INVALID_PATH_E/WS_FATAL_ERROR (wolfscp.c:1383), WS_SCP_ABORT (wolfscp.c:2965), and a bare log (wolfscp.c:3243). Confirmed ScpPushDir is forward-declared static at wolfscp.c:56 (the definition at line 2667 omits static, but the prior internal-linkage declaration is visible, so linkage stays internal) — it cannot be unit-tested directly, and coverage would need an integration case driving a >1023-char base path through wolfSSH_SCP_to.

Fix: At minimum cover the ScpPushDir over-long-path reject, since it changes library behavior for all three callers. The example-program guards (echoserver/sftpclient) are lower value and can reasonably be left uncovered.

if (pathSz >= sizeof(ctx->dirName))
return WS_BUFFER_E;

entry = ScpNewDir(fs, path, heap);
if (entry == NULL) {
return WS_FATAL_ERROR;
Expand All @@ -2680,9 +2689,9 @@ int ScpPushDir(void *fs, ScpSendCtx* ctx, const char* path, void* heap)
ctx->currentDir = entry;
}

/* append directory name to ctx->dirName */
WSTRNCPY(ctx->dirName, path, DEFAULT_SCP_FILE_NAME_SZ-1);
ctx->dirName[DEFAULT_SCP_FILE_NAME_SZ-1] = '\0';
/* append directory name to ctx->dirName, terminator included; the guard
* above bounds pathSz so the copy always fits */
WMEMCPY(ctx->dirName, path, pathSz + 1);

return WS_SUCCESS;
}
Expand Down
60 changes: 27 additions & 33 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1502,6 +1502,20 @@ static void test_wolfSSH_agent_signrequest_success(void)
#if defined(WOLFSSH_SFTP) && !defined(NO_WOLFSSH_CLIENT) && \
!defined(SINGLE_THREADED)

/* A peer that is already gone at shutdown is not a test failure. The send path
* reports the reset as the return value; the recv path returns the generic
* WS_ERROR and stashes the specific code in wolfSSH_get_error. */
static int AbsorbBenignReset(WOLFSSH* ssh, int ret)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 [Medium] AbsorbBenignReset widens shutdown tolerance beyond peer-reset · Test Quality

Verified against the tree. The helper absorbs ret == WS_ERROR && wolfSSH_get_error(ssh) == WS_SOCKET_ERROR_E in addition to the direct WS_SOCKET_ERROR_E return the old code handled. Confirmed that WS_ERROR and WS_FATAL_ERROR are the same value (-1001, wolfssh/error.h:42-43), so the ret == WS_ERROR gate matches every generic wolfSSH failure return, not just the recv path. WS_SOCKET_ERROR_E (-1009) is wolfSSH's generic socket-layer failure code — it is not specific to "peer sent RST". So a server that dies mid-shutdown for a genuine reason (rather than the benign post-transfer race this targets) now also reports WS_SUCCESS across all five call sites. This is a deliberate and reasonable trade (the old code already absorbed the send-path form, and the PR documents the ~30-40% flake it fixes), but the tests can no longer distinguish a benign reset from a real socket failure at shutdown, and the widening applies uniformly to SendReadPacket / PartialSend / rekey / Confinement / KeyboardInteractive.

Fix: Consider gating on the underlying WSAGetLastError() == WSAECONNRESET / errno == ECONNRESET so a genuine socket failure at shutdown still fails the test. If that proves too brittle across the platforms api-test runs on, keep the current form but note the limitation in the helper comment.

{
if (ret == WS_SOCKET_ERROR_E ||
(ret == WS_ERROR &&
wolfSSH_get_error(ssh) == WS_SOCKET_ERROR_E)) {
ret = WS_SUCCESS;
}

return ret;
}

byte userPassword[256];

static int sftpUserAuth(byte authType, WS_UserAuthData* authData, void* ctx)
Expand Down Expand Up @@ -1635,10 +1649,8 @@ static void test_wolfSSH_SFTP_SendReadPacket(void)
argsCount = 0;
args[argsCount++] = ".";
args[argsCount++] = "-1";
#ifndef USE_WINDOWS_API
args[argsCount++] = "-p";
args[argsCount++] = "0";
#endif
ser.argv = (char**)args;
ser.argc = argsCount;
ser.signal = &ready;
Expand Down Expand Up @@ -1819,11 +1831,7 @@ static void test_wolfSSH_SFTP_SendReadPacket(void)
wolfSSH_worker(ssh, NULL);
}

argsCount = wolfSSH_shutdown(ssh);
if (argsCount == WS_SOCKET_ERROR_E) {
/* If the socket is closed on shutdown, peer is gone, this is OK. */
argsCount = WS_SUCCESS;
}
argsCount = AbsorbBenignReset(ssh, wolfSSH_shutdown(ssh));

#if DEFAULT_HIGHWATER_MARK < 8000
if (argsCount == WS_REKEYING) {
Expand All @@ -1845,6 +1853,7 @@ static void test_wolfSSH_SFTP_SendReadPacket(void)
k_sleep(Z_TIMEOUT_TICKS(100));
#endif
ThreadJoin(serThread);
FreeTcpReady(&ready);
}


Expand Down Expand Up @@ -1905,10 +1914,8 @@ static void test_wolfSSH_SFTP_PartialSend(void)
argsCount = 0;
args[argsCount++] = ".";
args[argsCount++] = "-1";
#ifndef USE_WINDOWS_API
args[argsCount++] = "-p";
args[argsCount++] = "0";
#endif
ser.argv = (char**)args;
ser.argc = argsCount;
ser.signal = &ready;
Expand Down Expand Up @@ -2094,10 +2101,7 @@ static void test_wolfSSH_SFTP_PartialSend(void)
wolfSSH_worker(ssh, NULL);
}

argsCount = wolfSSH_shutdown(ssh);
if (argsCount == WS_SOCKET_ERROR_E) {
argsCount = WS_SUCCESS;
}
argsCount = AbsorbBenignReset(ssh, wolfSSH_shutdown(ssh));
#if DEFAULT_HIGHWATER_MARK < 8000
if (argsCount == WS_REKEYING) {
argsCount = WS_SUCCESS;
Expand All @@ -2114,6 +2118,7 @@ static void test_wolfSSH_SFTP_PartialSend(void)
k_sleep(Z_TIMEOUT_TICKS(100));
#endif
ThreadJoin(serThread);
FreeTcpReady(&ready);
#endif /* WOLFSSH_TEST_INTERNAL */
}

Expand Down Expand Up @@ -2145,10 +2150,8 @@ static void sftp_rekey_test(int nonBlock)
argsCount = 0;
args[argsCount++] = ".";
args[argsCount++] = "-1";
#ifndef USE_WINDOWS_API
args[argsCount++] = "-p";
args[argsCount++] = "0";
#endif
ser.argv = (char**)args;
ser.argc = argsCount;
ser.signal = &ready;
Expand Down Expand Up @@ -2232,9 +2235,7 @@ static void sftp_rekey_test(int nonBlock)
* before the WS_REKEYING fixup below could otherwise mask it. The loop cap
* is one above the assert threshold to leave last-iteration headroom. */
AssertIntLE(tries, SFTP_REKEY_MAX_TRIES);
if (argsCount == WS_SOCKET_ERROR_E) {
argsCount = WS_SUCCESS;
}
argsCount = AbsorbBenignReset(ssh, argsCount);
#if DEFAULT_HIGHWATER_MARK < 8000
if (argsCount == WS_REKEYING) {
/* in cases where highwater mark is really small a re-key could happen */
Expand All @@ -2252,6 +2253,7 @@ static void sftp_rekey_test(int nonBlock)
k_sleep(Z_TIMEOUT_TICKS(100));
#endif
ThreadJoin(serThread);
FreeTcpReady(&ready);
}

static void test_wolfSSH_SFTP_ReKey(void)
Expand Down Expand Up @@ -2430,10 +2432,8 @@ static void test_wolfSSH_SFTP_Confinement(void)
argsCount = 0;
args[argsCount++] = ".";
args[argsCount++] = "-1";
#ifndef USE_WINDOWS_API
args[argsCount++] = "-p";
args[argsCount++] = "0";
#endif
ser.argv = (char**)args;
ser.argc = argsCount;
ser.signal = &ready;
Expand Down Expand Up @@ -2606,10 +2606,7 @@ static void test_wolfSSH_SFTP_Confinement(void)
while (wolfSSH_get_error(ssh) == WS_REKEYING)
wolfSSH_worker(ssh, NULL);

ret = wolfSSH_shutdown(ssh);
if (ret == WS_SOCKET_ERROR_E) {
ret = WS_SUCCESS;
}
ret = AbsorbBenignReset(ssh, wolfSSH_shutdown(ssh));
#if DEFAULT_HIGHWATER_MARK < 8000
if (ret == WS_REKEYING) {
ret = WS_SUCCESS;
Expand All @@ -2624,6 +2621,7 @@ static void test_wolfSSH_SFTP_Confinement(void)
k_sleep(Z_TIMEOUT_TICKS(100));
#endif
ThreadJoin(serThread);
FreeTcpReady(&ready);

/* remove staged targets; escMkdir/escDest only exist if confinement
* leaked, and inJailDir only if the positive-case RMDIR did not run, so
Expand Down Expand Up @@ -2945,10 +2943,8 @@ static void scp_rekey_test(int nonBlock, int toServer)
argsCount = 0;
args[argsCount++] = ".";
args[argsCount++] = "-1";
#ifndef USE_WINDOWS_API
args[argsCount++] = "-p";
args[argsCount++] = "0";
#endif
ser.argv = (char**)args;
ser.argc = argsCount;
ser.signal = &ready;
Expand Down Expand Up @@ -3043,6 +3039,7 @@ static void scp_rekey_test(int nonBlock, int toServer)
wolfSSH_free(ssh);
wolfSSH_CTX_free(ctx);
ThreadJoin(serThread);
FreeTcpReady(&ready);

/* verify the transferred file matches the source once the server is done */
AssertIntEQ(scpFilesMatch(verifyName, fileData, SCP_REKEY_FILE_SZ), 0);
Expand Down Expand Up @@ -3759,10 +3756,8 @@ static void test_wolfSSH_KeyboardInteractive(void)
args[argsCount++] = "-1";
args[argsCount++] = "-i";
args[argsCount++] = "test:test";
#ifndef USE_WINDOWS_API
args[argsCount++] = "-p";
args[argsCount++] = "0";
#endif
ser.argv = (char**)args;
ser.argc = argsCount;
ser.signal = &ready;
Expand All @@ -3775,11 +3770,7 @@ static void test_wolfSSH_KeyboardInteractive(void)
AssertNotNull(ssh);


argsCount = wolfSSH_shutdown(ssh);
if (argsCount == WS_SOCKET_ERROR_E) {
/* If the socket is closed on shutdown, peer is gone, this is OK. */
argsCount = WS_SUCCESS;
}
argsCount = AbsorbBenignReset(ssh, wolfSSH_shutdown(ssh));

#if DEFAULT_HIGHWATER_MARK < 8000
if (argsCount == WS_REKEYING) {
Expand All @@ -3801,6 +3792,7 @@ static void test_wolfSSH_KeyboardInteractive(void)
k_sleep(Z_TIMEOUT_TICKS(100));
#endif
ThreadJoin(serThread);
FreeTcpReady(&ready);
}

#else /* WOLFSSH_SFTP && !NO_WOLFSSH_CLIENT && !SINGLE_THREADED */
Expand All @@ -3819,6 +3811,8 @@ int wolfSSH_ApiTest(int argc, char** argv)
#ifdef WOLFSSH_TEST_BLOCK
return 77;
#else
WSTARTTCP();

AssertIntEQ(wolfSSH_Init(), WS_SUCCESS);

#if defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,2)
Expand Down
8 changes: 8 additions & 0 deletions wolfssh/port.h
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,14 @@ extern "C" {
#endif
#endif /* WSTRING_USER */

/* Measures a formatted string's length; _snprintf_s rejects the NULL/0 probe
* form that WSNPRINTF maps to on Windows. Defined outside WSTRING_USER so
* custom string ports need not supply it, and left overridable. */
#if defined(USE_WINDOWS_API) && !defined(WSCPRINTF)
#include <stdio.h>
#define WSCPRINTF(f,...) _scprintf((f),##__VA_ARGS__)
#endif

/* get local time for debug print out */
#if defined(USE_WINDOWS_API) || defined(__MINGW32__)
#define WTIME time
Expand Down
Loading
Loading