Skip to content

Commit 3ef3cb6

Browse files
Run threaded api-test SFTP/SCP tests on Windows
1 parent 281e4bc commit 3ef3cb6

7 files changed

Lines changed: 111 additions & 33 deletions

File tree

.github/workflows/windows-check.yml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,12 @@ jobs:
4343
working-directory: ${{env.GITHUB_WORKSPACE}}wolfssl
4444
run: nuget restore ${{env.WOLFSSL_SOLUTION_FILE_PATH}}
4545

46-
- name: updated user_settings.h for sshd and x509
46+
- name: Update user_settings.h for sshd and x509
4747
working-directory: ${{env.GITHUB_WORKSPACE}}
48-
run: cp ${{env.USER_SETTINGS_H_NEW}} ${{env.USER_SETTINGS_H}}
49-
50-
- name: replace wolfSSL user_settings.h with wolfSSH user_settings.h
51-
working-directory: ${{env.GITHUB_WORKSPACE}}
52-
run: get-content ${{env.USER_SETTINGS_H_NEW}} | %{$_ -replace "if 0","if 1"}
48+
shell: bash
49+
run: |
50+
sed -i 's/#if 0/#if 1/g' ${{env.USER_SETTINGS_H_NEW}}
51+
cp ${{env.USER_SETTINGS_H_NEW}} ${{env.USER_SETTINGS_H}}
5352
5453
- name: Build wolfssl library
5554
working-directory: ${{env.GITHUB_WORKSPACE}}wolfssl
@@ -117,11 +116,12 @@ jobs:
117116

118117
# These env paths already include the wolfssh/ and wolfssl/ checkout
119118
# prefixes, so they must run from the workspace root (as the build job does).
120-
- name: updated user_settings.h for sshd and x509
121-
run: cp ${{env.USER_SETTINGS_H_NEW}} ${{env.USER_SETTINGS_H}}
122-
123-
- name: replace wolfSSL user_settings.h with wolfSSH user_settings.h
124-
run: get-content ${{env.USER_SETTINGS_H_NEW}} | %{$_ -replace "if 0","if 1"}
119+
- name: Update user_settings.h for sshd and x509
120+
working-directory: ${{env.GITHUB_WORKSPACE}}
121+
shell: bash
122+
run: |
123+
sed -i 's/#if 0/#if 1/g' ${{env.USER_SETTINGS_H_NEW}}
124+
cp ${{env.USER_SETTINGS_H_NEW}} ${{env.USER_SETTINGS_H}}
125125
126126
# WholeProgramOptimization=false disables /GL so the v142-independent objects
127127
# link without a cross-version code-generation requirement (C1047).

examples/echoserver/echoserver.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2114,6 +2114,11 @@ static int LoadPasswdList(StrList* strList, PwMapList* mapList)
21142114
int count = 0;
21152115

21162116
while (strList) {
2117+
if (WSTRLEN(strList->str) >= sizeof names - 1) {
2118+
fprintf(stderr, "Ignoring over-long entry\n");
2119+
strList = strList->next;
2120+
continue;
2121+
}
21172122
WSTRNCPY(names, strList->str, sizeof names - 1);
21182123
passwd = WSTRCHR(names, ':');
21192124
if (passwd != NULL) {
@@ -2143,6 +2148,11 @@ static int LoadKeyboardList(StrList* strList, PwMapList* mapList,
21432148
int count = 0;
21442149

21452150
while (strList) {
2151+
if (WSTRLEN(strList->str) >= sizeof names - 1) {
2152+
fprintf(stderr, "Ignoring over-long entry\n");
2153+
strList = strList->next;
2154+
continue;
2155+
}
21462156
WSTRNCPY(names, strList->str, sizeof names - 1);
21472157
passwd = WSTRCHR(names, ':');
21482158
if (passwd != NULL) {
@@ -2179,6 +2189,11 @@ static int LoadPubKeyList(StrList* strList, int format, PwMapList* mapList)
21792189
buf = NULL;
21802190
bufSz = 0;
21812191

2192+
if (WSTRLEN(strList->str) >= sizeof names - 1) {
2193+
fprintf(stderr, "Ignoring over-long entry\n");
2194+
strList = strList->next;
2195+
continue;
2196+
}
21822197
WSTRNCPY(names, strList->str, sizeof names - 1);
21832198
fileName = WSTRCHR(names, ':');
21842199
if (fileName != NULL) {
@@ -2695,6 +2710,13 @@ static INLINE void SignalTcpReady(tcp_ready* ready, word16 port)
26952710
ready->port = port;
26962711
pthread_cond_signal(&ready->cond);
26972712
pthread_mutex_unlock(&ready->mutex);
2713+
#elif defined(USE_WINDOWS_API) && defined(NO_MAIN_DRIVER) && \
2714+
!defined(SINGLE_THREADED)
2715+
EnterCriticalSection(&ready->cs);
2716+
ready->ready = 1;
2717+
ready->port = port;
2718+
LeaveCriticalSection(&ready->cs);
2719+
SetEvent(ready->readyEvent);
26982720
#else
26992721
WOLFSSH_UNUSED(ready);
27002722
WOLFSSH_UNUSED(port);
@@ -2840,7 +2862,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
28402862
}
28412863
else {
28422864
port = (word16)atoi(myoptarg);
2843-
#if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
2865+
#if !defined(NO_MAIN_DRIVER)
28442866
if (port == 0) {
28452867
ES_ERROR("port number cannot be 0");
28462868
}

examples/sftpclient/sftpclient.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ static void myStatusCb(WOLFSSH* sshIn, word32* bytes, char* name)
182182
lastPrintedBytes[0] = 0;
183183
lastPrintedBytes[1] = 0;
184184
WMEMSET(currentFile, 0, WOLFSSH_MAX_FILENAME);
185+
if (WSTRLEN(name) >= WOLFSSH_MAX_FILENAME)
186+
return;
185187
WSTRNCPY(currentFile, name, WOLFSSH_MAX_FILENAME);
186188
}
187189
elapsedTime = currentTime - startTime;
@@ -1462,6 +1464,8 @@ static int doAutopilot(int cmd, char* local, char* remote)
14621464

14631465
if (remoteAbsPath) {
14641466
/* use remote absolute path if provided */
1467+
if (WSTRLEN(remote) >= sizeof(fullpath) - 1)
1468+
return WS_BUFFER_E;
14651469
WMEMSET(fullpath, 0, sizeof(fullpath));
14661470
WSTRNCPY(fullpath, remote, sizeof(fullpath) - 1);
14671471
}

src/wolfscp.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1303,7 +1303,7 @@ static int ScpCheckForRename(WOLFSSH* ssh, int cmdSz)
13031303
return WS_BUFFER_E;
13041304
}
13051305

1306-
WSTRNCPY(buf, ssh->scpBasePath, cmdSz);
1306+
WSTRNCPY(buf, ssh->scpBasePath, sizeof(buf));
13071307
buf[sz] = '\0';
13081308
WSTRNCAT(buf, "/..", DEFAULT_SCP_MSG_SZ);
13091309

@@ -1904,7 +1904,11 @@ static char* MakeScpCmd(const char* name, char dir, void* heap)
19041904
char* cmd;
19051905
int sz;
19061906

1907+
#ifdef USE_WINDOWS_API
1908+
sz = WSCPRINTF("scp -%c %s", dir, name) + 1;
1909+
#else
19071910
sz = WSNPRINTF(NULL, 0, "scp -%c %s", dir, name) + 1;
1911+
#endif
19081912
if (sz <= 0) {
19091913
return NULL;
19101914
}
@@ -2587,6 +2591,9 @@ int ScpPushDir(void *fs, ScpSendCtx* ctx, const char* path, void* heap)
25872591
if (ctx == NULL || path == NULL)
25882592
return WS_BAD_ARGUMENT;
25892593

2594+
if (WSTRLEN(path) >= DEFAULT_SCP_FILE_NAME_SZ - 1)
2595+
return WS_BUFFER_E;
2596+
25902597
entry = ScpNewDir(fs, path, heap);
25912598
if (entry == NULL) {
25922599
return WS_FATAL_ERROR;

tests/api.c

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,10 +1524,8 @@ static void test_wolfSSH_SFTP_SendReadPacket(void)
15241524
argsCount = 0;
15251525
args[argsCount++] = ".";
15261526
args[argsCount++] = "-1";
1527-
#ifndef USE_WINDOWS_API
15281527
args[argsCount++] = "-p";
15291528
args[argsCount++] = "0";
1530-
#endif
15311529
ser.argv = (char**)args;
15321530
ser.argc = argsCount;
15331531
ser.signal = &ready;
@@ -1709,8 +1707,12 @@ static void test_wolfSSH_SFTP_SendReadPacket(void)
17091707
}
17101708

17111709
argsCount = wolfSSH_shutdown(ssh);
1712-
if (argsCount == WS_SOCKET_ERROR_E) {
1713-
/* If the socket is closed on shutdown, peer is gone, this is OK. */
1710+
if (argsCount == WS_SOCKET_ERROR_E ||
1711+
(argsCount == WS_ERROR &&
1712+
wolfSSH_get_error(ssh) == WS_SOCKET_ERROR_E)) {
1713+
/* If the socket is closed on shutdown, peer is gone, this is OK. On
1714+
* Windows the recv path returns generic WS_FATAL_ERROR with the specific
1715+
* code stashed in wolfSSH_get_error. */
17141716
argsCount = WS_SUCCESS;
17151717
}
17161718

@@ -1734,6 +1736,7 @@ static void test_wolfSSH_SFTP_SendReadPacket(void)
17341736
k_sleep(Z_TIMEOUT_TICKS(100));
17351737
#endif
17361738
ThreadJoin(serThread);
1739+
FreeTcpReady(&ready);
17371740
}
17381741

17391742

@@ -1794,10 +1797,8 @@ static void test_wolfSSH_SFTP_PartialSend(void)
17941797
argsCount = 0;
17951798
args[argsCount++] = ".";
17961799
args[argsCount++] = "-1";
1797-
#ifndef USE_WINDOWS_API
17981800
args[argsCount++] = "-p";
17991801
args[argsCount++] = "0";
1800-
#endif
18011802
ser.argv = (char**)args;
18021803
ser.argc = argsCount;
18031804
ser.signal = &ready;
@@ -1984,7 +1985,11 @@ static void test_wolfSSH_SFTP_PartialSend(void)
19841985
}
19851986

19861987
argsCount = wolfSSH_shutdown(ssh);
1987-
if (argsCount == WS_SOCKET_ERROR_E) {
1988+
/* Benign peer reset: WS_SOCKET_ERROR_E either as the return (send path) or in
1989+
* wolfSSH_get_error while shutdown returns generic WS_FATAL_ERROR (recv path). */
1990+
if (argsCount == WS_SOCKET_ERROR_E ||
1991+
(argsCount == WS_ERROR &&
1992+
wolfSSH_get_error(ssh) == WS_SOCKET_ERROR_E)) {
19881993
argsCount = WS_SUCCESS;
19891994
}
19901995
#if DEFAULT_HIGHWATER_MARK < 8000
@@ -2003,6 +2008,7 @@ static void test_wolfSSH_SFTP_PartialSend(void)
20032008
k_sleep(Z_TIMEOUT_TICKS(100));
20042009
#endif
20052010
ThreadJoin(serThread);
2011+
FreeTcpReady(&ready);
20062012
#endif /* WOLFSSH_TEST_INTERNAL */
20072013
}
20082014

@@ -2034,10 +2040,8 @@ static void sftp_rekey_test(int nonBlock)
20342040
argsCount = 0;
20352041
args[argsCount++] = ".";
20362042
args[argsCount++] = "-1";
2037-
#ifndef USE_WINDOWS_API
20382043
args[argsCount++] = "-p";
20392044
args[argsCount++] = "0";
2040-
#endif
20412045
ser.argv = (char**)args;
20422046
ser.argc = argsCount;
20432047
ser.signal = &ready;
@@ -2121,7 +2125,11 @@ static void sftp_rekey_test(int nonBlock)
21212125
* before the WS_REKEYING fixup below could otherwise mask it. The loop cap
21222126
* is one above the assert threshold to leave last-iteration headroom. */
21232127
AssertIntLE(tries, SFTP_REKEY_MAX_TRIES);
2124-
if (argsCount == WS_SOCKET_ERROR_E) {
2128+
/* Benign peer reset: WS_SOCKET_ERROR_E either as the return (send path) or in
2129+
* wolfSSH_get_error while shutdown returns generic WS_FATAL_ERROR (recv path). */
2130+
if (argsCount == WS_SOCKET_ERROR_E ||
2131+
(argsCount == WS_ERROR &&
2132+
wolfSSH_get_error(ssh) == WS_SOCKET_ERROR_E)) {
21252133
argsCount = WS_SUCCESS;
21262134
}
21272135
#if DEFAULT_HIGHWATER_MARK < 8000
@@ -2141,6 +2149,7 @@ static void sftp_rekey_test(int nonBlock)
21412149
k_sleep(Z_TIMEOUT_TICKS(100));
21422150
#endif
21432151
ThreadJoin(serThread);
2152+
FreeTcpReady(&ready);
21442153
}
21452154

21462155
static void test_wolfSSH_SFTP_ReKey(void)
@@ -2319,10 +2328,8 @@ static void test_wolfSSH_SFTP_Confinement(void)
23192328
argsCount = 0;
23202329
args[argsCount++] = ".";
23212330
args[argsCount++] = "-1";
2322-
#ifndef USE_WINDOWS_API
23232331
args[argsCount++] = "-p";
23242332
args[argsCount++] = "0";
2325-
#endif
23262333
ser.argv = (char**)args;
23272334
ser.argc = argsCount;
23282335
ser.signal = &ready;
@@ -2496,7 +2503,12 @@ static void test_wolfSSH_SFTP_Confinement(void)
24962503
wolfSSH_worker(ssh, NULL);
24972504

24982505
ret = wolfSSH_shutdown(ssh);
2499-
if (ret == WS_SOCKET_ERROR_E) {
2506+
if (ret == WS_SOCKET_ERROR_E ||
2507+
(ret == WS_ERROR &&
2508+
wolfSSH_get_error(ssh) == WS_SOCKET_ERROR_E)) {
2509+
/* If the socket is closed on shutdown, peer is gone, this is OK. On
2510+
* Windows the recv path returns generic WS_FATAL_ERROR with the specific
2511+
* code stashed in wolfSSH_get_error. */
25002512
ret = WS_SUCCESS;
25012513
}
25022514
#if DEFAULT_HIGHWATER_MARK < 8000
@@ -2513,6 +2525,7 @@ static void test_wolfSSH_SFTP_Confinement(void)
25132525
k_sleep(Z_TIMEOUT_TICKS(100));
25142526
#endif
25152527
ThreadJoin(serThread);
2528+
FreeTcpReady(&ready);
25162529

25172530
/* remove staged targets; escMkdir/escDest only exist if confinement
25182531
* leaked, and inJailDir only if the positive-case RMDIR did not run, so
@@ -2834,10 +2847,8 @@ static void scp_rekey_test(int nonBlock, int toServer)
28342847
argsCount = 0;
28352848
args[argsCount++] = ".";
28362849
args[argsCount++] = "-1";
2837-
#ifndef USE_WINDOWS_API
28382850
args[argsCount++] = "-p";
28392851
args[argsCount++] = "0";
2840-
#endif
28412852
ser.argv = (char**)args;
28422853
ser.argc = argsCount;
28432854
ser.signal = &ready;
@@ -2932,6 +2943,7 @@ static void scp_rekey_test(int nonBlock, int toServer)
29322943
wolfSSH_free(ssh);
29332944
wolfSSH_CTX_free(ctx);
29342945
ThreadJoin(serThread);
2946+
FreeTcpReady(&ready);
29352947

29362948
/* verify the transferred file matches the source once the server is done */
29372949
AssertIntEQ(scpFilesMatch(verifyName, fileData, SCP_REKEY_FILE_SZ), 0);
@@ -3648,10 +3660,8 @@ static void test_wolfSSH_KeyboardInteractive(void)
36483660
args[argsCount++] = "-1";
36493661
args[argsCount++] = "-i";
36503662
args[argsCount++] = "test:test";
3651-
#ifndef USE_WINDOWS_API
36523663
args[argsCount++] = "-p";
36533664
args[argsCount++] = "0";
3654-
#endif
36553665
ser.argv = (char**)args;
36563666
ser.argc = argsCount;
36573667
ser.signal = &ready;
@@ -3665,8 +3675,12 @@ static void test_wolfSSH_KeyboardInteractive(void)
36653675

36663676

36673677
argsCount = wolfSSH_shutdown(ssh);
3668-
if (argsCount == WS_SOCKET_ERROR_E) {
3669-
/* If the socket is closed on shutdown, peer is gone, this is OK. */
3678+
if (argsCount == WS_SOCKET_ERROR_E ||
3679+
(argsCount == WS_ERROR &&
3680+
wolfSSH_get_error(ssh) == WS_SOCKET_ERROR_E)) {
3681+
/* If the socket is closed on shutdown, peer is gone, this is OK. On
3682+
* Windows the recv path returns generic WS_FATAL_ERROR with the specific
3683+
* code stashed in wolfSSH_get_error. */
36703684
argsCount = WS_SUCCESS;
36713685
}
36723686

@@ -3690,6 +3704,7 @@ static void test_wolfSSH_KeyboardInteractive(void)
36903704
k_sleep(Z_TIMEOUT_TICKS(100));
36913705
#endif
36923706
ThreadJoin(serThread);
3707+
FreeTcpReady(&ready);
36933708
}
36943709

36953710
#else /* WOLFSSH_SFTP && !NO_WOLFSSH_CLIENT && !SINGLE_THREADED */
@@ -3708,6 +3723,8 @@ int wolfSSH_ApiTest(int argc, char** argv)
37083723
#ifdef WOLFSSH_TEST_BLOCK
37093724
return 77;
37103725
#else
3726+
WSTARTTCP();
3727+
37113728
AssertIntEQ(wolfSSH_Init(), WS_SUCCESS);
37123729

37133730
#if defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,2)

wolfssh/port.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ extern "C" {
551551
#define WSTRNCASECMP(s1,s2,n) _strnicmp((s1),(s2),(n))
552552
#define WSNPRINTF(s,n,f,...) _snprintf_s((s),(n),_TRUNCATE,(f),##__VA_ARGS__)
553553
#define WVSNPRINTF(s,n,f,...) _vsnprintf_s((s),(n),_TRUNCATE,(f),##__VA_ARGS__)
554+
#define WSCPRINTF(f,...) _scprintf((f),##__VA_ARGS__)
554555
#define WSTRTOK(s1,s2,s3) strtok_s((s1),(s2),(s3))
555556
#elif defined(MICROCHIP_MPLAB_HARMONY) || defined(MICROCHIP_PIC32)
556557
#include <stdio.h>

0 commit comments

Comments
 (0)