diff --git a/ChangeLog.md b/ChangeLog.md index ea4febaa..bb706f8c 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,3 +1,65 @@ +# wolfSSH v1.4.18 (July 20, 2024) + +## New Features + +- Add wolfSSL style static memory pool allocation support. +- Add Ed25519 public key support. +- Add Banner option to wolfSSHd configuration. +- Add non-blocking socket support to the example SCP client. + +## Improvements + +- Documentation updates. +- Update the Zephyr test action. +- Add a no-filesystem build to the Zephyr port. +- Update the macOS test action. +- Refactor certificate processing. Only verify certificates when a signature + is present. +- Update the Kyber test action. +- Refactor the Curve25519 Key Agreement support. +- Update the STM32Cube Pack. +- Increase the memory that Zephyr uses for a heap for testing. +- Add a macro wrapper to replace the ReadDir function. +- Add callback hook for keying completion. +- Add function to return strings for the names of algorithms. +- Add asynchronous server side user authentication. +- Add ssh-rsa (SHA-1) to the default user auth algorithm list when + sha1-soft-disable is disabled. +- Update Espressif examples using Managed Components. +- Add SCP test case. +- Refactor RSA sign and verify. +- Refresh the example echoserver with updates from wolfSSHd. +- Add callback hooks for most channel messages including open, close, success, + fail, and requests. +- Reduce the number of memory allocations SCP makes. +- Improve wolfSSHd’s behavior on closing a connection. It closes channels and + waits for the peer to close the channels. + +## Fixes + +- Refactor wolfSSHd service support for Windows to fix PowerShell + Write-Progress. +- Fix partial success case with public key user authentication. +- Fix the build guards with respect to cannedKeyAlgoNames. +- Error if unable to open the local file when doing a SCP send. +- Fix some IPv6 related build issues. +- Add better checks for SCP error returns for closed channels. +- In the example SCP client, move the public key check context after the + WOLFSSH object is created. +- Fix error reporting for wolfSSH_SFTP_STAT. +- In the example SCP client, fix error code checking on shutdown. +- Change return from wolfSSH_shutdown() to WS_CHANNEL_CLOSED. +- Fix SFTP symlink handling. +- Fix variable initialization warnings for Zephyr builds. +- Fix wolfSSHd case of non-console output handles. +- Fix testsuite for single threaded builds. Add single threaded test action. +- Fix wolfSSHd shutting down on fcntl() failure. +- Fix wolfSSHd on Windows handling virtual terminal sequences using exec + commands. +- Fix possible null dereference when matching MAC algos during key exchange. + +--- + # wolfSSH v1.4.17 (March 25, 2024) ## Vulnerabilities diff --git a/apps/wolfsshd/wolfsshd.c b/apps/wolfsshd/wolfsshd.c index c2656a91..ce056759 100644 --- a/apps/wolfsshd/wolfsshd.c +++ b/apps/wolfsshd/wolfsshd.c @@ -110,7 +110,7 @@ typedef struct WOLFSSHD_CONNECTION { WOLFSSHD_AUTH* auth; int fd; int listenFd; - char ip[INET_ADDRSTRLEN]; + char ip[INET6_ADDRSTRLEN]; byte isThreaded; } WOLFSSHD_CONNECTION; @@ -151,6 +151,7 @@ static void SyslogCb(enum wolfSSH_LogLevel level, const char *const msgStr) #ifdef _WIN32 static void ServiceDebugCb(enum wolfSSH_LogLevel level, const char* const msgStr) +#ifdef UNICODE { WCHAR* wc; size_t szWord = WSTRLEN(msgStr) + 3; /* + 3 for null terminator and new @@ -170,7 +171,13 @@ static void ServiceDebugCb(enum wolfSSH_LogLevel level, const char* const msgStr } WOLFSSH_UNUSED(level); } +#else +{ + OutputDebugString(msgStr); + WOLFSSH_UNUSED(level); +} #endif +#endif /* _WIN32 */ static void ShowUsage(void) { @@ -674,7 +681,6 @@ static int SFTP_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, } if (ret == WS_SUCCESS) { - r[rSz] = '\0'; wolfSSH_Log(WS_LOG_INFO, "[SSHD] Using directory %s for SFTP connection", r); if (wolfSSH_SFTP_SetDefaultPath(ssh, r) != WS_SUCCESS) { @@ -832,7 +838,6 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, /* @TODO check for conpty support LoadLibrary()and GetProcAddress(). */ - if (forcedCmd != NULL && WSTRCMP(forcedCmd, "internal-sftp") == 0) { wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Only SFTP connections allowed for user " @@ -912,6 +917,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, if (ret == WS_SUCCESS) { SECURITY_ATTRIBUTES saAttr; + ZeroMemory(&saAttr, sizeof(saAttr)); saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; @@ -926,28 +932,30 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, } if (ret == WS_SUCCESS) { - STARTUPINFO si; + STARTUPINFOW si; PCWSTR conCmd = L"wolfsshd.exe -r "; PWSTR conCmdPtr; - int conCmdSz; + size_t conCmdSz; SetHandleInformation(ptyIn, HANDLE_FLAG_INHERIT, 0); SetHandleInformation(ptyOut, HANDLE_FLAG_INHERIT, 0); wolfSSH_SetTerminalResizeCtx(ssh, (void*)&ptyIn); - conCmdSz = (int)(wcslen(conCmd) + cmdSz + 2); /* +1 for terminator */ - conCmdPtr = (PWSTR)WMALLOC(sizeof(wchar_t) * conCmdSz, NULL, DYNTYPE_SSHD); + conCmdSz = wcslen(conCmd) + cmdSz + 3; + /* +1 for terminator, +2 for quotes */ + conCmdPtr = (PWSTR)WMALLOC(sizeof(wchar_t) * conCmdSz, + NULL, DYNTYPE_SSHD); if (conCmdPtr == NULL) { ret = WS_MEMORY_E; } else { - memset(conCmdPtr, 0, conCmdSz * sizeof(wchar_t)); - _snwprintf(conCmdPtr, conCmdSz * sizeof(wchar_t), L"wolfsshd.exe -r \"%s\"", cmd); + _snwprintf_s(conCmdPtr, conCmdSz, conCmdSz, + L"wolfsshd.exe -r \"%s\"", cmd); } - ZeroMemory(&si, sizeof(STARTUPINFO)); - si.cb = sizeof(STARTUPINFO); + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); si.hStdInput = cnslIn; si.hStdOutput = cnslOut; @@ -967,7 +975,6 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, CloseHandle(cnslOut); WFREE(conCmdPtr, NULL, DYNTYPE_SSHD); - CloseHandle(processInfo.hThread); } if (ret == WS_SUCCESS) { @@ -2374,21 +2381,21 @@ static int StartSSHD(int argc, char** argv) wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Issue updating service status"); } } + if (ret == WS_SUCCESS) { + /* Create a stop event to watch on */ + serviceStop = CreateEvent(NULL, TRUE, FALSE, NULL); + if (serviceStop == NULL) { + serviceStatus.dwControlsAccepted = 0; + serviceStatus.dwCurrentState = SERVICE_STOPPED; + serviceStatus.dwWin32ExitCode = GetLastError(); + serviceStatus.dwCheckPoint = 1; - /* Create a stop event to watch on */ - serviceStop = CreateEvent(NULL, TRUE, FALSE, NULL); - if (serviceStop == NULL) { - serviceStatus.dwControlsAccepted = 0; - serviceStatus.dwCurrentState = SERVICE_STOPPED; - serviceStatus.dwWin32ExitCode = GetLastError(); - serviceStatus.dwCheckPoint = 1; - - if (SetServiceStatus(serviceStatusHandle, &serviceStatus) == FALSE) { - wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Issue updating service status"); + if (SetServiceStatus(serviceStatusHandle, &serviceStatus) == FALSE) { + wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Issue updating service status"); + } + return; } - return; } - if (cmdArgs != NULL) { LocalFree(cmdArgs); } @@ -2550,8 +2557,8 @@ static int SetupConsole(char* inCmd) HANDLE sOut; HANDLE sIn; HPCON pCon = 0; - COORD cord; - STARTUPINFOEX ext; + COORD cord = { 80,24 }; /* Default to 80x24. Updated later. */ + STARTUPINFOEXW ext; int ret = WS_SUCCESS; PWSTR cmd = NULL; size_t cmdSz = 0; @@ -2564,10 +2571,6 @@ static int SetupConsole(char* inCmd) return -1; } - /* defautl 80x24 with setup, screen size will get set by VT command after started */ - cord.X = 80; - cord.Y = 24; - sIn = GetStdHandle(STD_INPUT_HANDLE); if (WSTRCMP(shellCmd, inCmd) != 0) { diff --git a/configure.ac b/configure.ac index ba533a75..617ff052 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ # All right reserved. AC_COPYRIGHT([Copyright (C) 2014-2024 wolfSSL Inc.]) -AC_INIT([wolfssh],[1.4.17],[support@wolfssl.com],[wolfssh],[https://www.wolfssl.com]) +AC_INIT([wolfssh],[1.4.18],[support@wolfssl.com],[wolfssh],[https://www.wolfssl.com]) AC_PREREQ([2.63]) AC_CONFIG_AUX_DIR([build-aux]) @@ -18,7 +18,7 @@ AC_ARG_PROGRAM AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_HEADERS([config.h]) -WOLFSSH_LIBRARY_VERSION=16:0:9 +WOLFSSH_LIBRARY_VERSION=17:0:10 # | | | # +-----+ | +----+ # | | | @@ -313,7 +313,7 @@ AM_CONDITIONAL([BUILD_KEYGEN],[test "x$ENABLED_KEYGEN" = "xyes"]) AM_CONDITIONAL([BUILD_SCP],[test "x$ENABLED_SCP" = "xyes"]) AM_CONDITIONAL([BUILD_SFTP],[test "x$ENABLED_SFTP" = "xyes"]) AM_CONDITIONAL([BUILD_FWD],[test "x$ENABLED_FWD" = "xyes"]) -AM_CONDITIONAL([BUILD_TERM],[test "x$ENABLED_PTERM" = "xyes"]) +AM_CONDITIONAL([BUILD_TERM],[test "x$ENABLED_TERM" = "xyes"]) AM_CONDITIONAL([BUILD_SHELL],[test "x$ENABLED_SHELL" = "xyes"]) AM_CONDITIONAL([BUILD_AGENT],[test "x$ENABLED_AGENT" = "xyes"]) AM_CONDITIONAL([BUILD_SSHD],[test "x$ENABLED_SSHD" = "xyes"]) diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index e4371132..2075d485 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -1609,21 +1609,19 @@ static int load_file(const char* fileName, byte* buf, word32* bufSz) fileSz = (word32)WFTELL(NULL, file); WREWIND(NULL, file); - if (fileSz > *bufSz) { - if (buf == NULL) - *bufSz = fileSz; + if (buf == NULL || fileSz > *bufSz) { + *bufSz = fileSz; WFCLOSE(NULL, file); return 0; } readSz = (word32)WFREAD(NULL, buf, 1, fileSz, file); - if (readSz < fileSz) { - WFCLOSE(NULL, file); - return 0; - } - WFCLOSE(NULL, file); + if (readSz < fileSz) { + fileSz = 0; + } + return fileSz; } #endif /* NO_FILESYSTEM */ diff --git a/scripts/scp.test b/scripts/scp.test index e2104a7d..84e228fa 100755 --- a/scripts/scp.test +++ b/scripts/scp.test @@ -141,6 +141,7 @@ create_port ./examples/scpclient/wolfscp -u jill -P upthehill -p $port -L $PWD/does-not-exist:$PWD/empty RESULT=$? remove_ready_file +rm -f $PWD/scripts/empty if test $RESULT -eq 0; then echo -e "\n\nshould fail out sending a file that does not exist" diff --git a/src/wolfsftp.c b/src/wolfsftp.c index 7a16eca6..2638e15f 100644 --- a/src/wolfsftp.c +++ b/src/wolfsftp.c @@ -4538,9 +4538,9 @@ int SFTP_GetAttributes(void* fs, const char* fileName, WS_SFTP_FILEATRB* atr, atr->flags |= WOLFSSH_FILEATRB_PERM; atr->per = 0555 | - (stats.dwFileAttributes | FILE_ATTRIBUTE_READONLY ? 0 : 0200); - atr->per |= (stats.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? 0x4000: - FILEATRB_PER_FILE; + ((stats.dwFileAttributes | FILE_ATTRIBUTE_READONLY) ? 0 : 0200); + atr->per |= ((stats.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + ? FILEATRB_PER_DIR : FILEATRB_PER_FILE); #if 0 /* @TODO handle the constellation of possible Windows FILETIMEs */ diff --git a/tests/api.c b/tests/api.c index 69ce7b87..ce6a02ab 100644 --- a/tests/api.c +++ b/tests/api.c @@ -28,6 +28,7 @@ #include #endif #include +#include #include #include @@ -955,7 +956,7 @@ static void test_wolfSSH_SFTP_SendReadPacket(void) func_args ser; tcp_ready ready; int argsCount; - int clientFd; + WS_SOCKET_T clientFd; const char* args[10]; WOLFSSH_CTX* ctx = NULL; @@ -1066,7 +1067,7 @@ static void test_wolfSSH_SFTP_SendReadPacket(void) /* close client socket down */ clientFd = wolfSSH_get_fd(ssh); - close(clientFd); + WCLOSESOCKET(clientFd); wolfSSH_free(ssh); wolfSSH_CTX_free(ctx); diff --git a/tests/sftp.c b/tests/sftp.c index d292bd9b..b0aa3a75 100644 --- a/tests/sftp.c +++ b/tests/sftp.c @@ -186,7 +186,9 @@ int wolfSSH_SftpTest(int flag) int argsCount; const char* args[10]; +#ifndef USE_WINDOWS_API char portNumber[8]; +#endif THREAD_TYPE serThread; diff --git a/wolfssh/test.h b/wolfssh/test.h index 11e7b94e..0d1e129b 100644 --- a/wolfssh/test.h +++ b/wolfssh/test.h @@ -221,7 +221,7 @@ #ifdef USE_WINDOWS_API #define WCLOSESOCKET(s) closesocket(s) - #define WSTARTTCP() do { WSADATA wsd; WSAStartup(0x0002, &wsd); } while(0) + #define WSTARTTCP() do { WSADATA wsd; (void)WSAStartup(0x0002, &wsd); } while(0) #elif defined(MICROCHIP_TCPIP) || defined(MICROCHIP_MPLAB_HARMONY) #ifdef MICROCHIP_MPLAB_HARMONY #define WCLOSESOCKET(s) TCPIP_TCP_Close((s)) @@ -1136,6 +1136,9 @@ static int Base16_Decode(const byte* in, word32 inLen, word32 inIdx = 0; word32 outIdx = 0; + if (in == NULL || out == NULL || outLen == NULL) + return WS_BAD_ARGUMENT; + if (inLen == 1 && *outLen && in) { byte b = in[inIdx] - 0x30; /* 0 starts at 0x30 */ diff --git a/wolfssh/version.h b/wolfssh/version.h index c616365e..2ec51af0 100644 --- a/wolfssh/version.h +++ b/wolfssh/version.h @@ -35,8 +35,8 @@ extern "C" { #endif -#define LIBWOLFSSH_VERSION_STRING "1.4.17" -#define LIBWOLFSSH_VERSION_HEX 0x01004017 +#define LIBWOLFSSH_VERSION_STRING "1.4.18" +#define LIBWOLFSSH_VERSION_HEX 0x01004018 #ifdef __cplusplus }