Init zephyr support

- SSH
- SFTP
- SCP
pull/593/head
Juliusz Sosinowicz 2023-09-26 19:48:10 +02:00
parent e5f4b692fb
commit 37412ff50f
32 changed files with 1315 additions and 174 deletions

92
.github/workflows/zephyr.yml vendored 100644
View File

@ -0,0 +1,92 @@
name: Zephyr tests
on:
push:
branches: [ '*' ]
pull_request:
branches: [ '*' ]
jobs:
run_test:
name: Build and run
strategy:
matrix:
config:
- zephyr-ref: v3.4.0
zephyr-sdk: 0.16.1
runs-on: ubuntu-latest
# This should be a safe limit for the tests to run.
timeout-minutes: 15
steps:
- name: Install dependencies
run: |
# Don't prompt for anything
export DEBIAN_FRONTEND=noninteractive
sudo apt-get update
# most of the ci-base zephyr docker image packages
sudo apt-get install -y zip bridge-utils uml-utilities \
git cmake ninja-build gperf ccache dfu-util device-tree-compiler wget \
python3-dev python3-pip python3-setuptools python3-tk python3-wheel xz-utils file \
make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1 \
autoconf automake bison build-essential ca-certificates cargo ccache chrpath cmake \
cpio device-tree-compiler dfu-util diffstat dos2unix doxygen file flex g++ gawk gcc \
gcovr git git-core gnupg gperf gtk-sharp2 help2man iproute2 lcov libcairo2-dev \
libglib2.0-dev libgtk2.0-0 liblocale-gettext-perl libncurses5-dev libpcap-dev \
libpopt0 libsdl1.2-dev libsdl2-dev libssl-dev libtool libtool-bin locales make \
net-tools ninja-build openssh-client parallel pkg-config python3-dev python3-pip \
python3-ply python3-setuptools python-is-python3 qemu rsync socat srecord sudo \
texinfo unzip wget ovmf xz-utils
- name: Install west
run: sudo pip install west
- name: Init west workspace
run: west init --mr ${{ matrix.config.zephyr-ref }} zephyr
- name: Update west.yml
working-directory: zephyr/zephyr
run: |
REF=$(echo '${{ github.ref }}' | sed -e 's/\//\\\//g')
sed -e 's/remotes:/remotes:\n \- name: wolfssl\n url\-base: https:\/\/github.com\/wolfssl/' -i west.yml
sed -e "s/remotes:/remotes:\n \- name: wolfssh\n url\-base: https:\/\/github.com\/${{ github.repository_owner }}/" -i west.yml
sed -e "s/projects:/projects:\n \- name: wolfssh\n path: modules\/lib\/wolfssh\n remote: wolfssh\n revision: $REF/" -i west.yml
sed -e 's/projects:/projects:\n \- name: wolfssl\n path: modules\/crypto\/wolfssl\n remote: wolfssl\n revision: master/' -i west.yml
- name: Update west workspace
working-directory: zephyr
run: west update -n -o=--depth=1
- name: Export zephyr
working-directory: zephyr
run: west zephyr-export
- name: Install pip dependencies
working-directory: zephyr
run: sudo pip install -r zephyr/scripts/requirements.txt
- name: Install zephyr SDK
run: |
wget -q https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v${{ matrix.config.zephyr-sdk }}/zephyr-sdk-${{ matrix.config.zephyr-sdk }}_linux-x86_64.tar.xz
tar xf zephyr-sdk-${{ matrix.config.zephyr-sdk }}_linux-x86_64.tar.xz
cd zephyr-sdk-${{ matrix.config.zephyr-sdk }}
./setup.sh -h -c
- name: Run wolfssh tests
id: wolfssh-test
working-directory: zephyr
run: |
./zephyr/scripts/twister --testsuite-root modules/lib/wolfssh --test zephyr/samples/tests/sample.lib.wolfssh_tests -vvv
rm -rf zephyr/twister-out
- name: Zip failure logs
if: ${{ failure() && steps.wolfssh-test.outcome == 'failure' }}
run: |
zip -9 -r logs.zip zephyr/twister-out
- name: Upload failure logs
if: ${{ failure() && steps.wolfssh-test.outcome == 'failure' }}
uses: actions/upload-artifact@v3
with:
name: zephyr-client-test-logs
path: logs.zip
retention-days: 5

5
.gitignore vendored
View File

@ -83,3 +83,8 @@ Debug
Release
DLL Debug
DLL Release
# Eclipse
.cproject
.project
.settings

View File

@ -39,7 +39,8 @@
#include <wolfssl/wolfcrypt/ecc.h>
#include "examples/client/client.h"
#include "examples/client/common.h"
#if !defined(USE_WINDOWS_API) && !defined(MICROCHIP_PIC32)
#if !defined(USE_WINDOWS_API) && !defined(MICROCHIP_PIC32) && \
defined(WOLFSSH_TERM) && !defined(NO_FILESYSTEM)
#include <termios.h>
#endif
@ -124,15 +125,6 @@ static const char* certName = NULL;
static const char* caCert = NULL;
#if defined(WOLFSSH_AGENT)
static inline void ato32(const byte* c, word32* u32)
{
*u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
}
#endif
static int NonBlockSSH_connect(WOLFSSH* ssh)
{
int ret;
@ -174,7 +166,8 @@ static int NonBlockSSH_connect(WOLFSSH* ssh)
return ret;
}
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_NUCLEUS)
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_NUCLEUS) && \
defined(WOLFSSH_TERM) && !defined(NO_FILESYSTEM)
typedef struct thread_args {
WOLFSSH* ssh;
@ -345,6 +338,12 @@ static THREAD_RET readInput(void* in)
return THREAD_RET_SUCCESS;
}
#if defined(WOLFSSH_AGENT)
static inline void ato32(const byte* c, word32* u32)
{
*u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
}
#endif
static THREAD_RET readPeer(void* in)
{
@ -460,13 +459,13 @@ static THREAD_RET readPeer(void* in)
}
else {
printf("%s", buf);
fflush(stdout);
WFFLUSH(stdout);
}
#else
if (write(STDOUT_FILENO, buf, ret) < 0) {
perror("write to stdout error ");
}
fflush(stdout);
WFFLUSH(stdout);
#endif
}
if (wolfSSH_stream_peek(args->ssh, buf, bufSz) <= 0) {
@ -640,6 +639,8 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
char** argv = ((func_args*)args)->argv;
((func_args*)args)->return_code = 0;
(void)keepOpen;
while ((ch = mygetopt(argc, argv, "?ac:h:i:j:p:tu:xzNP:RJ:A:Xe")) != -1) {
switch (ch) {
case 'h':
@ -859,7 +860,8 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
if (ret != WS_SUCCESS)
err_sys("Couldn't connect SSH stream.");
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_NUCLEUS)
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_NUCLEUS) && \
defined(WOLFSSH_TERM) && !defined(NO_FILESYSTEM)
if (keepOpen) /* set up for psuedo-terminal */
ClientSetEcho(2);
@ -995,7 +997,7 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
wc_ecc_fp_free(); /* free per thread cache */
#endif
return 0;
WOLFSSL_RETURN_FROM_THREAD(0);
}
#endif /* NO_WOLFSSH_CLIENT */

View File

@ -25,14 +25,17 @@
#define WOLFSSH_TEST_CLIENT
#include <stdio.h>
#include <wolfssh/ssh.h>
#include <wolfssh/internal.h>
#include <wolfssh/wolfsftp.h>
#include <wolfssh/port.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/coding.h>
#include "examples/client/common.h"
#ifndef USE_WINDOWS_API
#if !defined(USE_WINDOWS_API) && !defined(MICROCHIP_PIC32) && \
!defined(WOLFSSH_ZEPHYR)
#include <termios.h>
#endif
@ -487,11 +490,13 @@ int ClientUserAuth(byte authType,
passwordSz = (word32)strlen(defaultPassword);
memcpy(userPassword, defaultPassword, passwordSz);
}
#ifdef WOLFSSH_TERM
else {
printf("Password: ");
fflush(stdout);
WFFLUSH(stdout);
ClientSetEcho(0);
if (fgets((char*)userPassword, sizeof(userPassword), stdin) == NULL) {
if (WFGETS((char*)userPassword, sizeof(userPassword), stdin)
== NULL) {
fprintf(stderr, "Getting password failed.\n");
ret = WOLFSSH_USERAUTH_FAILURE;
}
@ -505,8 +510,9 @@ int ClientUserAuth(byte authType,
#ifdef USE_WINDOWS_API
printf("\r\n");
#endif
fflush(stdout);
WFFLUSH(stdout);
}
#endif
if (ret == WOLFSSH_USERAUTH_SUCCESS) {
authData->sf.password.password = userPassword;
@ -518,6 +524,7 @@ int ClientUserAuth(byte authType,
}
#ifdef WOLFSSH_TERM
/* type = 2 : shell / execute command settings
* type = 0 : password
* type = 1 : restore default
@ -604,6 +611,7 @@ int ClientSetEcho(int type)
return 0;
}
#endif
/* Set certificate to use and public key.
@ -662,7 +670,7 @@ int ClientSetPrivateKey(const char* privKeyName, int userEcc)
&isPrivate, NULL);
#else
printf("file system not compiled in!\n");
ret = WC_NOT_COMPILED;
ret = NOT_COMPILED_IN;
#endif
}

View File

@ -55,7 +55,7 @@
#undef WOLFSSH_SHELL
#endif
#ifdef WOLFSSL_NUCLEUS
#if defined(WOLFSSL_NUCLEUS) || defined(WOLFSSH_ZEPHYR)
/* use buffers for keys with server */
#define NO_FILESYSTEM
#define WOLFSSH_NO_EXIT
@ -1153,7 +1153,7 @@ static int sftp_worker(thread_ctx_t* threadCtx)
WOLFSSH* ssh = threadCtx->ssh;
WS_SOCKET_T s;
int ret = WS_SUCCESS;
int error;
int error = -1;
int selected;
unsigned char peek_buf[1];
int timeout = TEST_SFTP_TIMEOUT;
@ -1423,14 +1423,14 @@ static THREAD_RETURN WOLFSSH_THREAD server_worker(void* vArgs)
WFREE(threadCtx, NULL, 0);
return 0;
WOLFSSL_RETURN_FROM_THREAD(0);
}
#ifndef NO_FILESYSTEM
/* set bufSz to size wanted if too small and buf is null */
static int load_file(const char* fileName, byte* buf, word32* bufSz)
{
FILE* file;
WFILE* file;
word32 fileSz;
word32 readSz;
@ -1438,24 +1438,24 @@ static int load_file(const char* fileName, byte* buf, word32* bufSz)
if (WFOPEN(NULL, &file, fileName, "rb") != 0)
return 0;
fseek(file, 0, XSEEK_END);
fileSz = (word32)ftell(file);
rewind(file);
WFSEEK(NULL, file, 0, WSEEK_END);
fileSz = (word32)WFTELL(NULL, file);
WREWIND(NULL, file);
if (fileSz > *bufSz) {
if (buf == NULL)
*bufSz = fileSz;
fclose(file);
WFCLOSE(NULL, file);
return 0;
}
readSz = (word32)fread(buf, 1, fileSz, file);
readSz = (word32)WFREAD(NULL, buf, 1, fileSz, file);
if (readSz < fileSz) {
fclose(file);
WFCLOSE(NULL, file);
return 0;
}
fclose(file);
WFCLOSE(NULL, file);
return fileSz;
}
@ -1594,7 +1594,6 @@ static const char samplePasswordBuffer[] =
"jack:fetchapail\n";
#ifndef NO_FILESYSTEM
#ifndef WOLFSSH_NO_ECC
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
static const char samplePublicKeyEccBuffer[] =
@ -1634,7 +1633,6 @@ static const char samplePublicKeyRsaBuffer[] =
"biE57dK6BrH5iZwVLTQKux31uCJLPhiktI3iLbdlGZEctJkTasfVSsUizwVIyRjhVKmbdI"
"RGwkU38D043AR1h0mUoGCPIKuqcFMf gretel\n";
#endif
#endif /* NO_FILESYSTEM */
#ifdef WOLFSSH_ALLOW_USERAUTH_NONE
@ -1834,7 +1832,7 @@ static int LoadPasswdList(StrList* strList, PwMapList* mapList)
return count;
}
#ifndef NO_FILESYSTEM
static int LoadPubKeyList(StrList* strList, int format, PwMapList* mapList)
{
char names[256];
@ -1902,7 +1900,7 @@ static int LoadPubKeyList(StrList* strList, int format, PwMapList* mapList)
return count;
}
#endif
static int wsUserAuthResult(byte res,
WS_UserAuthData* authData,
@ -2077,6 +2075,7 @@ static int SetDefaultSftpPath(WOLFSSH* ssh, const char* defaultSftpPath)
int ret = 0;
if (defaultSftpPath == NULL) {
#ifndef NO_FILESYSTEM
#ifdef USE_WINDOWS_API
if (GetCurrentDirectoryA(sizeof(path)-1, path) == 0) {
ret = WS_INVALID_PATH_E;
@ -2086,6 +2085,11 @@ static int SetDefaultSftpPath(WOLFSSH* ssh, const char* defaultSftpPath)
ret = WS_INVALID_PATH_E;
}
#endif
#elif defined(WOLFSSH_ZEPHYR)
WSTRNCPY(path, CONFIG_WOLFSSH_SFTP_DEFAULT_DIR, WOLFSSH_MAX_FILENAME);
#else
ret = WS_INVALID_PATH_E;
#endif
}
else {
if (WSTRLEN(defaultSftpPath) >= sizeof(path)) {
@ -2159,17 +2163,24 @@ static INLINE void SignalTcpReady(func_args* serverArgs, word16 port)
#endif
}
#define ES_ERROR(...) do { \
fprintf(stderr, __VA_ARGS__); \
serverArgs->return_code = EXIT_FAILURE; \
WOLFSSL_RETURN_FROM_THREAD(0); \
} while(0)
THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
{
func_args* serverArgs = (func_args*)args;
WOLFSSH_CTX* ctx = NULL;
PwMapList pwMapList;
StrList* sshPubKeyList = NULL;
StrList* pemPubKeyList = NULL;
StrList* derPubKeyList = NULL;
#ifndef NO_FILESYSTEM
StrList* sshPubKeyList = NULL;
StrList* pemPubKeyList = NULL;
StrList* derPubKeyList = NULL;
#endif
StrList* passwdList = NULL;
WS_SOCKET_T listenFd = 0;
WS_SOCKET_T listenFd = WOLFSSH_SOCKET_INVALID;
word32 defaultHighwater = EXAMPLE_HIGHWATER_MARK;
word32 threadCount = 0;
int multipleConnections = 1;
@ -2181,7 +2192,9 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
char* readyFile = NULL;
const char* defaultSftpPath = NULL;
char nonBlock = 0;
char* userPubKey = NULL;
#ifndef NO_FILESYSTEM
char* userPubKey = NULL;
#endif
#ifdef WOLFSSH_CERTS
char* caCert = NULL;
#endif
@ -2198,7 +2211,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
case '?' :
ShowUsage();
serverArgs->return_code = MY_EX_USAGE;
return 0;
WOLFSSL_RETURN_FROM_THREAD(0);
case '1':
multipleConnections = 0;
@ -2225,17 +2238,13 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
case 'p':
if (myoptarg == NULL) {
err_sys("NULL port value");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("NULL port value");
}
else {
port = (word16)atoi(myoptarg);
#if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
if (port == 0) {
err_sys("port number cannot be 0");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("port number cannot be 0");
}
#endif
}
@ -2253,6 +2262,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
defaultSftpPath = myoptarg;
break;
#ifndef NO_FILESYSTEM
case 'j':
userPubKey = myoptarg;
break;
@ -2268,6 +2278,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
case 'K':
derPubKeyList = StrListAdd(derPubKeyList, myoptarg);
break;
#endif
case 'P':
passwdList = StrListAdd(passwdList, myoptarg);
@ -2276,7 +2287,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
default:
ShowUsage();
serverArgs->return_code = MY_EX_USAGE;
return 0;
WOLFSSL_RETURN_FROM_THREAD(0);
}
}
}
@ -2285,9 +2296,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
#ifdef WOLFSSH_TEST_BLOCK
if (!nonBlock) {
err_sys("Use -N when testing forced non blocking");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Use -N when testing forced non blocking");
}
#endif
@ -2304,16 +2313,12 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
(void)userEcc;
if (wolfSSH_Init() != WS_SUCCESS) {
fprintf(stderr, "Couldn't initialize wolfSSH.\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Couldn't initialize wolfSSH.\n");
}
ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_SERVER, NULL);
if (ctx == NULL) {
fprintf(stderr, "Couldn't allocate SSH CTX data.\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Couldn't allocate SSH CTX data.\n");
}
WMEMSET(&pwMapList, 0, sizeof(pwMapList));
@ -2330,6 +2335,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
wolfSSH_CTX_SetFwdCb(ctx, wolfSSH_FwdDefaultActions, NULL);
#endif
#ifndef NO_FILESYSTEM
if (sshPubKeyList) {
LoadPubKeyList(sshPubKeyList, WOLFSSH_FORMAT_SSH, &pwMapList);
StrListFree(sshPubKeyList);
@ -2345,6 +2351,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
StrListFree(derPubKeyList);
derPubKeyList = NULL;
}
#endif
if (passwdList) {
LoadPasswdList(passwdList, &pwMapList);
StrListFree(passwdList);
@ -2363,8 +2370,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
keyLoadBuf = (byte*)WMALLOC(EXAMPLE_KEYLOAD_BUFFER_SZ,
NULL, 0);
if (keyLoadBuf == NULL) {
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Error allocating keyLoadBuf");
}
#else
keyLoadBuf = buf;
@ -2373,15 +2379,11 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
bufSz = load_key(peerEcc, keyLoadBuf, bufSz);
if (bufSz == 0) {
fprintf(stderr, "Couldn't load first key file.\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Couldn't load first key file.\n");
}
if (wolfSSH_CTX_UsePrivateKey_buffer(ctx, keyLoadBuf, bufSz,
WOLFSSH_FORMAT_ASN1) < 0) {
fprintf(stderr, "Couldn't use first key buffer.\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Couldn't use first key buffer.\n");
}
#if !defined(WOLFSSH_NO_RSA) && !defined(WOLFSSH_NO_ECC)
@ -2390,18 +2392,15 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
bufSz = load_key(peerEcc, keyLoadBuf, bufSz);
if (bufSz == 0) {
fprintf(stderr, "Couldn't load second key file.\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Couldn't load second key file.\n");
}
if (wolfSSH_CTX_UsePrivateKey_buffer(ctx, keyLoadBuf, bufSz,
WOLFSSH_FORMAT_ASN1) < 0) {
fprintf(stderr, "Couldn't use second key buffer.\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Couldn't use second key buffer.\n");
}
#endif
#ifndef NO_FILESYSTEM
if (userPubKey) {
byte* userBuf = NULL;
word32 userBufSz = 0;
@ -2411,21 +2410,18 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
/* create temp buffer and load in file */
if (userBufSz == 0) {
fprintf(stderr, "Couldn't find size of file %s.\n", userPubKey);
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Couldn't find size of file %s.\n", userPubKey);
}
userBuf = (byte*)WMALLOC(userBufSz, NULL, 0);
if (userBuf == NULL) {
fprintf(stderr, "WMALLOC failed\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("WMALLOC failed\n");
}
load_file(userPubKey, userBuf, &userBufSz);
LoadPublicKeyBuffer(userBuf, userBufSz, &pwMapList);
WFREE(userBuf, NULL, 0);
}
#endif
#ifdef WOLFSSH_CERTS
if (caCert) {
@ -2436,25 +2432,18 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
load_file(caCert, NULL, &certBufSz);
if (certBufSz == 0) {
fprintf(stderr,
"Couldn't find size of file %s.\n", caCert);
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Couldn't find size of file %s.\n", caCert);
}
certBuf = (byte*)WMALLOC(certBufSz, NULL, 0);
if (certBuf == NULL) {
fprintf(stderr, "WMALLOC failed\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("WMALLOC failed\n");
}
load_file(caCert, certBuf, &certBufSz);
ret = wolfSSH_CTX_AddRootCert_buffer(ctx, certBuf, certBufSz,
WOLFSSH_FORMAT_PEM);
if (ret != 0) {
fprintf(stderr, "Couldn't add root cert\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Couldn't add root cert\n");
}
WFREE(certBuf, NULL, 0);
}
@ -2500,9 +2489,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
/* wait for network and storage device */
if (NETBOOT_Wait_For_Network_Up(NU_SUSPEND) != NU_SUCCESS) {
fprintf(stderr, "Couldn't find network.\r\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Couldn't find network.\r\n");
}
for(i = 0; i < 15 && ret != NU_SUCCESS; i++)
@ -2513,9 +2500,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
}
if (ret != NU_SUCCESS) {
fprintf(stderr, "Couldn't find storage device.\r\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Couldn't find storage device.\r\n");
}
}
#endif
@ -2523,9 +2508,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
/* if creating a ready file with port then override port to be 0 */
if (readyFile != NULL) {
#ifdef NO_FILESYSTEM
fprintf(stderr, "cannot create readyFile with no file system.\r\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("cannot create readyFile with no file system.\r\n");
#else
port = 0;
#endif
@ -2538,14 +2521,16 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
int ret;
ret = WFOPEN(NULL, &f, readyFile, "w");
if (f != NULL && ret == 0) {
fprintf(f, "%d\n", (int)port);
char portStr[10];
int l = WSNPRINTF(portStr, sizeof(portStr), "%d\n", (int)port);
WFWRITE(NULL, portStr, MIN((size_t)l, sizeof(portStr)), 1, f);
WFCLOSE(NULL, f);
}
#endif
}
do {
WS_SOCKET_T clientFd = 0;
WS_SOCKET_T clientFd = WOLFSSH_SOCKET_INVALID;
#ifdef WOLFSSL_NUCLEUS
struct addr_struct clientAddr;
#else
@ -2558,18 +2543,14 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
threadCtx = (thread_ctx_t*)WMALLOC(sizeof(thread_ctx_t),
NULL, 0);
if (threadCtx == NULL) {
fprintf(stderr, "Couldn't allocate thread context data.\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Couldn't allocate thread context data.\n");
}
WMEMSET(threadCtx, 0, sizeof *threadCtx);
ssh = wolfSSH_new(ctx);
if (ssh == NULL) {
WFREE(threadCtx, NULL, 0);
fprintf(stderr, "Couldn't allocate SSH data.\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Couldn't allocate SSH data.\n");
}
wolfSSH_SetUserAuthCtx(ssh, &pwMapList);
/* Use the session object for its own highwater callback ctx */
@ -2580,9 +2561,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
#ifdef WOLFSSH_SFTP
if (SetDefaultSftpPath(ssh, defaultSftpPath) != 0) {
fprintf(stderr, "Couldn't store default sftp path.\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Couldn't store default sftp path.\n");
}
#endif
@ -2598,9 +2577,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
/* Get the local IP address for the socket.
* 0.0.0.0 if ip adder any */
if (NU_Get_Sock_Name(listenFd, &sock, &addrLength) != NU_SUCCESS) {
fprintf(stderr, "Couldn't find network.\r\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Couldn't find network.\r\n");
}
WMEMCPY(ipaddr, &sock.ip_num, MAX_ADDRESS_SIZE);
@ -2618,9 +2595,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
&clientAddrSz);
#endif
if (clientFd == -1) {
err_sys("tcp accept failed");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("tcp accept failed");
}
if (nonBlock)
@ -2649,23 +2624,21 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
} while (multipleConnections && !quit);
if (listenFd != 0) {
if (listenFd != WOLFSSH_SOCKET_INVALID) {
WCLOSESOCKET(listenFd);
}
wc_FreeMutex(&doneLock);
PwMapListDelete(&pwMapList);
wolfSSH_CTX_free(ctx);
if (wolfSSH_Cleanup() != WS_SUCCESS) {
fprintf(stderr, "Couldn't clean up wolfSSH.\n");
serverArgs->return_code = EXIT_FAILURE;
return 0;
ES_ERROR("Couldn't clean up wolfSSH.\n");
}
#if !defined(WOLFSSH_NO_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
wc_ecc_fp_free(); /* free per thread cache */
#endif
(void)defaultSftpPath;
return 0;
WOLFSSL_RETURN_FROM_THREAD(0);
}
#endif /* NO_WOLFSSH_SERVER */

View File

@ -31,7 +31,8 @@
#endif
#include <stdio.h>
#if !defined(USE_WINDOWS_API) && !defined(MICROCHIP_PIC32)
#if !defined(USE_WINDOWS_API) && !defined(MICROCHIP_PIC32) && \
!defined(WOLFSSH_ZEPHYR)
#include <termios.h>
#endif
#include <wolfssh/ssh.h>

View File

@ -38,7 +38,7 @@
#include <wolfssh/internal.h>
#include <wolfssh/test.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include "examples/server/server.h"
#include "server.h"
#ifdef NO_FILESYSTEM
#include <wolfssh/certs_test.h>
@ -760,12 +760,15 @@ THREAD_RETURN WOLFSSH_THREAD server_test(void* args)
threadCtx->nonBlock = nonBlock;
#ifndef SINGLE_THREADED
ThreadStart(server_worker, threadCtx, &thread);
#if defined(WOLFSSH_OLD_THREADING) || defined(WOLFSSL_THREAD_NO_JOIN)
if (multipleConnections)
ThreadDetach(thread);
ThreadStartNoJoin(server_worker, threadCtx);
else
#endif
{
ThreadStart(server_worker, threadCtx, &thread);
ThreadJoin(thread);
}
#else
server_worker(threadCtx);
#endif /* SINGLE_THREADED */
@ -781,7 +784,7 @@ THREAD_RETURN WOLFSSH_THREAD server_test(void* args)
wc_ecc_fp_free(); /* free per thread cache */
#endif
return 0;
WOLFSSL_RETURN_FROM_THREAD(0);
}
#endif /* NO_WOLFSSH_SERVER */

View File

@ -39,7 +39,8 @@
#include <wolfssl/wolfcrypt/coding.h>
#include "examples/sftpclient/sftpclient.h"
#include "examples/client/common.h"
#ifndef USE_WINDOWS_API
#if !defined(USE_WINDOWS_API) && !defined(MICROCHIP_PIC32) && \
!defined(WOLFSSH_ZEPHYR)
#include <termios.h>
#endif
@ -379,7 +380,7 @@ static int doCmds(func_args* args)
err_msg("fputs error");
return -1;
}
fflush(stdout);
WFFLUSH(stdout);
WMEMSET(msg, 0, sizeof(msg));
if (SFTP_FGETS(args, msg, sizeof(msg) - 1) == NULL) {
@ -1385,7 +1386,7 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
wc_ecc_fp_free(); /* free per thread cache */
#endif
return 0;
WOLFSSL_RETURN_FROM_THREAD(0);
}
#else
@ -1399,7 +1400,7 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
"Please recompile with WOLFSSH_SFTP or --enable-sftp\n");
#endif
(void)args;
return 0;
WOLFSSL_RETURN_FROM_THREAD(0);
}
#endif /* WOLFSSH_SFTP */

View File

@ -29,6 +29,7 @@
#include <config.h>
#endif
#include <stdio.h>
#include <wolfssh/ssh.h>
#include <wolfssh/internal.h>
#include <wolfssh/log.h>
@ -826,7 +827,7 @@ void SshResourceFree(WOLFSSH* ssh, void* heap)
ssh->scpFileNameSz = 0;
}
if (ssh->scpRecvMsg) {
WFREE(ssh->scpRecvMsg, ssh->heap, DYNTYPE_STRING);
WFREE(ssh->scpRecvMsg, ssh->ctx->heap, DYNTYPE_STRING);
ssh->scpRecvMsg = NULL;
ssh->scpRecvMsgSz = 0;
}
@ -1245,7 +1246,7 @@ static int SetHostPrivateKey(WOLFSSH_CTX* ctx,
if (pvtKey->publicKeyFmt == keyId) {
if (pvtKey->key != NULL) {
ForceZero(pvtKey->key, pvtKey->keySz);
WFREE(pvtKey->key, heap, dynamicType);
WFREE(pvtKey->key, ctx->heap, dynamicType);
}
}
else {
@ -2247,8 +2248,8 @@ int wolfSSH_SendPacket(WOLFSSH* ssh)
int sent;
/* sanity check on amount requested to be sent */
if (ssh->outputBuffer.idx + ssh->outputBuffer.length >
ssh->outputBuffer.bufferSz) {
if (ssh->outputBuffer.length > ssh->outputBuffer.bufferSz ||
ssh->outputBuffer.length < ssh->outputBuffer.idx) {
WLOG(WS_LOG_ERROR, "Bad buffer state");
return WS_BUFFER_E;
}
@ -8327,7 +8328,7 @@ int SendKexInit(WOLFSSH* ssh)
byte* payload = NULL;
char* kexAlgoNames = NULL;
char* keyAlgoNames = NULL;
const byte* algo = 0;
const byte* algo = NULL;
word32 algoCount = 0, idx = 0, payloadSz = 0,
kexAlgoNamesSz = 0, keyAlgoNamesSz = 0;
int ret = WS_SUCCESS;
@ -9055,7 +9056,7 @@ int SendKexDhReply(WOLFSSH* ssh)
byte kPad = 0;
word32 sigBlockSz = 0;
word32 payloadSz = 0;
byte* output = 0;
byte* output = NULL;
word32 idx = 0;
word32 keyIdx = 0;
byte msgId = MSGID_KEXDH_REPLY;

View File

@ -141,6 +141,8 @@ void* wolfSSH_GetIOWriteCtx(WOLFSSH* ssh)
#include "nucleus.h"
#include "networking/nu_networking.h"
#include <errno.h>
#elif defined(WOLFSSH_ZEPHYR)
#include <zephyr/net/socket.h>
#else
#include <sys/types.h>
#include <errno.h>

View File

@ -45,7 +45,8 @@ Flags:
*/
#if !defined(NO_FILESYSTEM) && !defined(WOLFSSH_USER_FILESYSTEM)
#if !defined(NO_FILESYSTEM) && !defined(WOLFSSH_USER_FILESYSTEM) && \
!defined(WOLFSSH_ZEPHYR)
int wfopen(WFILE** f, const char* filename, const char* mode)
{
#ifdef USE_WINDOWS_API
@ -103,7 +104,7 @@ int wfopen(WFILE** f, const char* filename, const char* mode)
!defined(NO_WOLFSSH_SERVER)
#if defined(USE_WINDOWS_API) || defined(WOLFSSL_NUCLEUS) || \
defined(FREESCALE_MQX)
defined(FREESCALE_MQX) || defined(WOLFSSH_ZEPHYR)
/* This is current inline in the source. */
@ -475,6 +476,145 @@ int WS_DeleteFileA(const char* fileName, void* heap)
#endif /* USE_WINDOWS_API WOLFSSH_SFTP WOLFSSH_SCP */
#if defined(WOLFSSH_ZEPHYR) && (defined(WOLFSSH_SFTP) || defined(WOLFSSH_SCP))
int wssh_z_fstat(const char *p, struct fs_dirent *b)
{
size_t p_len;
if (p == NULL || b == NULL)
return -1;
p_len = WSTRLEN(p);
/* Detect if origin directory when it ends in ':' or ':/' */
if (p_len >= 3 && (p[p_len-1] == ':' ||
(p[p_len-1] == '/' && p[p_len-2] == ':'))) {
b->type = FS_DIR_ENTRY_DIR;
b->size = 0;
b->name[0] = '/';
b->name[1] = '\0';
return 0;
}
else
return fs_stat(p, b);
}
int z_fs_chdir(const char *path)
{
/* Just make sure that the path exists and is a directory */
struct fs_dirent dir;
int ret;
ret = wssh_z_fstat(path, &dir);
if (ret != 0 || dir.type != FS_DIR_ENTRY_DIR)
ret = -1;
return ret;
}
static struct {
byte open:1;
WFILE zfp;
} z_fds[WOLFSSH_MAX_DESCIPRTORS];
static wolfSSL_Mutex z_fds_mutex;
static int z_fds_setup = 0;
int wssh_z_fds_init(void)
{
int ret = 0;
if (!z_fds_setup) {
WMEMSET(z_fds, 0, sizeof(z_fds));
ret = wc_InitMutex(&z_fds_mutex);
if (ret == 0)
z_fds_setup = 1;
}
return ret;
}
int wssh_z_fds_cleanup(void)
{
int ret = 0;
if (z_fds_setup) {
WMEMSET(z_fds, 0, sizeof(z_fds));
ret = wc_FreeMutex(&z_fds_mutex);
z_fds_setup = 0;
}
return ret;
}
WFD wssh_z_open(const char *p, int f)
{
WFD ret = -1;
if (p != NULL) {
if (wc_LockMutex(&z_fds_mutex) == 0) {
WFD idx = 0;
/* find a free fd */
while(idx < WOLFSSH_MAX_DESCIPRTORS && z_fds[idx].open)
idx++;
if (idx < WOLFSSH_MAX_DESCIPRTORS) {
/* found a free fd */
fs_file_t_init(&z_fds[idx].zfp);
if (fs_open(&z_fds[idx].zfp, p, f) == 0) {
z_fds[idx].open = 1;
ret = idx;
}
}
wc_UnLockMutex(&z_fds_mutex);
}
}
return ret;
}
int wssh_z_close(WFD fd)
{
int ret = -1;
if (fd >= 0 && fd < WOLFSSH_MAX_DESCIPRTORS) {
if (wc_LockMutex(&z_fds_mutex) == 0) {
if (z_fds[fd].open) {
z_fds[fd].open = 0;
if (fs_close(&z_fds[fd].zfp) == 0)
ret = 0;
}
wc_UnLockMutex(&z_fds_mutex);
}
}
return ret;
}
int wPwrite(WFD fd, unsigned char* buf, unsigned int sz,
const unsigned int* shortOffset)
{
int ret = -1;
if (fd >= 0 && fd < WOLFSSH_MAX_DESCIPRTORS) {
if (wc_LockMutex(&z_fds_mutex) == 0) {
if (z_fds[fd].open) {
const word32* offset = (const word32*)shortOffset;
if (fs_seek(&z_fds[fd].zfp, offset[0], FS_SEEK_SET) == 0)
ret = fs_write(&z_fds[fd].zfp, buf, sz);
}
wc_UnLockMutex(&z_fds_mutex);
}
}
return ret;
}
int wPread(WFD fd, unsigned char* buf, unsigned int sz,
const unsigned int* shortOffset)
{
int ret = -1;
if (fd >= 0 && fd < WOLFSSH_MAX_DESCIPRTORS) {
if (wc_LockMutex(&z_fds_mutex) == 0) {
if (z_fds[fd].open) {
const word32* offset = (const word32*)shortOffset;
if (fs_seek(&z_fds[fd].zfp, offset[0], FS_SEEK_SET) == 0)
ret = fs_read(&z_fds[fd].zfp, buf, sz);
}
wc_UnLockMutex(&z_fds_mutex);
}
}
return ret;
}
#endif
#ifndef WSTRING_USER

View File

@ -71,6 +71,10 @@ int wolfSSH_Init(void)
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
#endif
#if defined(WOLFSSH_ZEPHYR) && (defined(WOLFSSH_SFTP) || defined(WOLFSSH_SCP))
if (wssh_z_fds_init() != 0)
ret = WS_CRYPTO_FAILED;
#endif
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_Init(), returning %d", ret);
return ret;
@ -85,6 +89,10 @@ int wolfSSH_Cleanup(void)
if (wolfCrypt_Cleanup() != 0)
ret = WS_CRYPTO_FAILED;
#if defined(WOLFSSH_ZEPHYR) && (defined(WOLFSSH_SFTP) || defined(WOLFSSH_SCP))
if (wssh_z_fds_cleanup() != 0)
ret = WS_CRYPTO_FAILED;
#endif
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_Cleanup(), returning %d", ret);
return ret;
@ -1317,6 +1325,7 @@ void* wolfSSH_GetPublicKeyCheckCtx(WOLFSSH* ssh)
#ifdef WOLFSSH_TERM
#if defined(WOLFSSH_TERM) && !defined(NO_FILESYSTEM)
/* Used to resize terminal window with shell connections
* returns WS_SUCCESS on success */
int wolfSSH_ChangeTerminalSize(WOLFSSH* ssh, word32 columns, word32 rows,
@ -1350,6 +1359,7 @@ void wolfSSH_SetTerminalResizeCtx(WOLFSSH* ssh, void* usrCtx)
{
ssh->termCtx = usrCtx;
}
#endif
#endif
@ -2383,7 +2393,14 @@ int wolfSSH_RealPath(const char* defaultPath, char* in,
char* prev = strrchr(out, '/');
if (prev != NULL) {
if (prev != out) {
if (prev != out
#ifdef WOLFSSH_ZEPHYR
/* Zephyr FAT fs path names follow the format of '/RAM:'
* and we want to preserve the '/' after this mount
* point definition too. */
&& prev[-1] != ':'
#endif
) {
prev[0] = 0;
curSz = (word32)WSTRLEN(out);
}

View File

@ -1980,7 +1980,7 @@ int wsScpRecvCallback(WOLFSSH* ssh, int state, const char* basePath,
#ifdef WOLFSCP_FLUSH
flush_bytes += bytes;
if (flush_bytes >= WRITE_FLUSH_SIZE) {
if (fflush(fp) != 0)
if (WFFLUSH(fp) != 0)
WLOG(WS_LOG_ERROR, scpError, "scp fflush failed", 0);
if (fsync(fileno(fp)) != 0)
WLOG(WS_LOG_ERROR, scpError, "scp fsync failed", 0);
@ -1996,7 +1996,7 @@ int wsScpRecvCallback(WOLFSSH* ssh, int state, const char* basePath,
/* close file */
if (fp != NULL) {
#ifdef WOLFSCP_FLUSH
(void)fflush(fp);
(void)WFFLUSH(fp);
(void)fsync(fileno(fp));
flush_bytes = 0;
#endif
@ -2011,7 +2011,7 @@ int wsScpRecvCallback(WOLFSSH* ssh, int state, const char* basePath,
ret = WS_SCP_CONTINUE;
} else {
WLOG(WS_LOG_ERROR,
"scp: unable to get timestamp info, abort");
"scp: unable to set timestamp info, abort");
ret = WS_SCP_ABORT;
}
}
@ -2163,6 +2163,20 @@ static int GetFileStats(void *fs, ScpSendCtx* ctx, const char* fileName,
*mTime = ctx->s.fupdate;
*aTime = ctx->s.faccdate;
NU_Done(&ctx->s);
#elif defined(WOLFSSH_ZEPHYR)
/* No time data in zephyr fs */
*mTime = (word64)0;
*aTime = (word64)0;
/* Default perms */
*fileMode = 0755;
/* Mimic S_IFMT */
if (ctx->s.type == FS_DIR_ENTRY_FILE)
*fileMode |= 0040000;
else if (ctx->s.type == FS_DIR_ENTRY_DIR)
*fileMode |= 0100000;
else
ret = WS_BAD_FILE_E;
#else
*mTime = (word64)ctx->s.st_mtime;
*aTime = (word64)ctx->s.st_atime;
@ -2214,7 +2228,7 @@ static ScpDir* ScpNewDir(void *fs, const char* path, void* heap)
}
#else
if (WOPENDIR(fs, heap, &entry->dir, path) != 0
#ifndef WOLFSSL_NUCLEUS
#if !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSH_ZEPHYR)
|| entry->dir == NULL
#endif
) {
@ -2359,6 +2373,13 @@ static int FindNextDirEntry(void *fs, ScpSendCtx* ctx)
} while ((ctx->entry != NULL) &&
(((WSTRLEN(ctx->entry) == 1) && WSTRNCMP(ctx->entry, ".", 1) == 0) ||
((WSTRLEN(ctx->entry) == 2) && WSTRNCMP(ctx->entry, "..", 2) == 0)));
#elif defined(WOLFSSH_ZEPHYR)
do {
if (fs_readdir(&ctx->currentDir->dir, &ctx->entry) != 0)
return WS_FATAL_ERROR;
if (ctx->entry.name[0] == 0) /* Reached end-of-dir */
return WS_NEXT_ERROR;
} while (1);
#else
do {
ctx->entry = WREADDIR(fs, &ctx->currentDir->dir);
@ -2391,6 +2412,8 @@ int ScpFileIsDir(ScpSendCtx* ctx)
return (ctx->s.fattribute & ADIRENT);
#elif defined(USE_WINDOWS_API)
return (ctx->s.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
#elif defined(WOLFSSH_ZEPHYR)
return ctx->s.type == FS_DIR_ENTRY_DIR;
#else
return S_ISDIR(ctx->s.st_mode);
#endif
@ -2402,6 +2425,8 @@ static int ScpFileIsFile(ScpSendCtx* ctx)
return (ctx->s.fattribute != ADIRENT);
#elif defined(USE_WINDOWS_API)
return ((ctx->s.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0);
#elif defined(WOLFSSH_ZEPHYR)
return ctx->s.type == FS_DIR_ENTRY_FILE;
#else
return S_ISREG(ctx->s.st_mode);
#endif
@ -2441,6 +2466,8 @@ static int ScpProcessEntry(WOLFSSH* ssh, char* fileName, word64* mTime,
GetFullPathNameA(fileName, MAX_PATH, path, NULL);
dNameLen = (int)WSTRLEN(path);
}
#elif defined(WOLFSSH_ZEPHYR)
dNameLen = (int)WSTRLEN(sendCtx->entry.name);
#else
dNameLen = (int)WSTRLEN(sendCtx->entry->d_name);
#endif
@ -2466,6 +2493,11 @@ static int ScpProcessEntry(WOLFSSH* ssh, char* fileName, word64* mTime,
DEFAULT_SCP_FILE_NAME_SZ);
WSTRNCPY(fileName, sendCtx->entry,
DEFAULT_SCP_FILE_NAME_SZ);
#elif defined(WOLFSSH_ZEPHYR)
WSTRNCAT(filePath, sendCtx->entry.name,
DEFAULT_SCP_FILE_NAME_SZ);
WSTRNCPY(fileName, sendCtx->entry.name,
DEFAULT_SCP_FILE_NAME_SZ);
#else
WSTRNCAT(filePath, sendCtx->entry->d_name,
DEFAULT_SCP_FILE_NAME_SZ);
@ -2715,7 +2747,7 @@ int wsScpSendCallback(WOLFSSH* ssh, int state, const char* peerRequest,
if (ret == WS_SUCCESS || ret == WS_NEXT_ERROR) {
#ifdef WOLFSSL_NUCLEUS
#if defined(WOLFSSL_NUCLEUS) || defined(WOLFSSH_ZEPHYR)
if (ret == WS_NEXT_ERROR) {
#else
/* reached end of directory */

View File

@ -1217,7 +1217,7 @@ static int wolfSSH_SFTP_RecvRealPath(WOLFSSH* ssh, int reqId, byte* data,
char s[WOLFSSH_MAX_FILENAME];
word32 rSz, sSz;
word32 lidx = 0;
int ret;
int ret = 0;
byte* out;
word32 outSz = 0;
@ -1245,10 +1245,13 @@ static int wolfSSH_SFTP_RecvRealPath(WOLFSSH* ssh, int reqId, byte* data,
/* If the default path isn't set, try to get it. */
if (ssh->sftpDefaultPath == NULL) {
char wd[WOLFSSH_MAX_FILENAME];
WMEMSET(wd, 0, WOLFSSH_MAX_FILENAME);
ret = WS_SUCCESS;
#ifndef USE_WINDOWS_API
#ifdef WOLFSSH_ZEPHYR
WSTRNCPY(wd, CONFIG_WOLFSSH_SFTP_DEFAULT_DIR, WOLFSSH_MAX_FILENAME);
#elif !defined(USE_WINDOWS_API)
if (WGETCWD(ssh->fs, wd, sizeof(wd)-1) == NULL) {
ret = WS_INVALID_PATH_E;
}
@ -1467,7 +1470,7 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
wolfSSH_SFTP_buffer_data(&state->buffer),
wolfSSH_SFTP_buffer_size(&state->buffer));
break;
#ifndef _WIN32_WCE
#if !defined(_WIN32_WCE) && !defined(WOLFSSH_ZEPHYR)
case WOLFSSH_FTP_SETSTAT:
ret = wolfSSH_SFTP_RecvSetSTAT(ssh, state->reqId,
wolfSSH_SFTP_buffer_data(&state->buffer),
@ -2959,6 +2962,72 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
return WS_SUCCESS;
}
#elif defined(WOLFSSH_ZEPHYR)
/* helper function that gets file information from reading directory
*
* returns WS_SUCCESS on success
*/
static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
char* dirName)
{
struct fs_dirent dp;
int sz;
if (dir == NULL || ssh == NULL || out == NULL) {
return WS_BAD_ARGUMENT;
}
/* 0 return and dp.name[0] == 0 means end-of-dir */
if (fs_readdir(dir, &dp) != 0 || dp.name[0] == 0) {
return WS_FATAL_ERROR;
}
sz = (int)WSTRLEN(dp.name);
out->fName = (char*)WMALLOC(sz + 1, out->heap, DYNTYPE_SFTP);
if (out->fName == NULL) {
return WS_MEMORY_E;
}
WMEMCPY(out->fName, dp.name, sz);
out->fName[sz] = '\0';
out->fSz = sz;
/* attempt to get file attributes. Could be directory or have none */
{
char r[WOLFSSH_MAX_FILENAME];
char s[WOLFSSH_MAX_FILENAME];
if ((WSTRLEN(dirName) + WSTRLEN(out->fName) + 2) > sizeof(r)) {
WLOG(WS_LOG_SFTP, "Path length too large");
WFREE(out->fName, out->heap, DYNTYPE_SFTP);
return WS_FATAL_ERROR;
}
WSNPRINTF(r, sizeof(r), "%s/%s", dirName, out->fName);
if (wolfSSH_RealPath(ssh->sftpDefaultPath, r, s, sizeof(s)) < 0) {
WFREE(out->fName, out->heap, DYNTYPE_SFTP);
WLOG(WS_LOG_SFTP, "Error cleaning path to get attributes");
return WS_FATAL_ERROR;
}
if (SFTP_GetAttributes(ssh->fs, s, &out->atrb, 0, ssh->ctx->heap)
!= WS_SUCCESS) {
WLOG(WS_LOG_SFTP, "Unable to get attribute values for %s",
out->fName);
}
}
/* Use attributes and fName to create long name */
if (SFTP_CreateLongName(out) != WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, "Error creating long name for %s", out->fName);
WFREE(out->fName, out->heap, DYNTYPE_SFTP);
return WS_FATAL_ERROR;
}
return WS_SUCCESS;
}
#else
/* helper function that gets file information from reading directory
@ -3108,7 +3177,7 @@ int wolfSSH_SFTP_SetDefaultPath(WOLFSSH* ssh, const char* path)
*/
int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
{
WDIR dir;
WDIR* dir = NULL;
word32 handle[2] = {0, 0};
word32 sz;
word32 idx = 0;
@ -3153,7 +3222,7 @@ int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
/* find DIR given handle */
while (cur != NULL) {
if (cur->id[0] == handle[0] && cur->id[1] == handle[1]) {
dir = cur->dir;
dir = &cur->dir;
dirName = cur->dirName;
break;
}
@ -3170,7 +3239,7 @@ int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
if (!cur->isEof) {
do {
name = wolfSSH_SFTPNAME_new(ssh->ctx->heap);
ret = wolfSSH_SFTPNAME_readdir(ssh, &dir, name, dirName);
ret = wolfSSH_SFTPNAME_readdir(ssh, dir, name, dirName);
if (ret == WS_SUCCESS || ret == WS_NEXT_ERROR) {
count++;
outSz += name->fSz + name->lSz + (UINT32_SZ * 2);
@ -4624,6 +4693,57 @@ static int SFTP_GetAttributes_Handle(WOLFSSH* ssh, byte* handle, int handleSz,
return WS_SUCCESS;
}
#elif defined(WOLFSSH_ZEPHYR)
static int PopulateAttributes(WS_SFTP_FILEATRB* atr, WSTAT_T* stats)
{
WMEMSET(atr, 0, sizeof(WS_SFTP_FILEATRB));
atr->flags |= WOLFSSH_FILEATRB_SIZE;
atr->sz[0] = (word32)(stats->size & 0xFFFFFFFF);
atr->flags |= WOLFSSH_FILEATRB_PERM;
/* Default perms */
atr->per = 0755;
/* Mimic S_IFMT */
if (stats->type == FS_DIR_ENTRY_FILE)
atr->per |= 0040000;
else if (stats->type == FS_DIR_ENTRY_DIR)
atr->per |= 0100000;
else
return WS_BAD_FILE_E;
return WS_SUCCESS;
}
int SFTP_GetAttributes(void* fs, const char* fileName, WS_SFTP_FILEATRB* atr,
byte noFollow, void* heap)
{
WSTAT_T stats;
WOLFSSH_UNUSED(heap);
WOLFSSH_UNUSED(noFollow);
if (WSTAT(fs, fileName, &stats) != 0) {
return WS_BAD_FILE_E;
}
return PopulateAttributes(atr, &stats);
}
int SFTP_GetAttributes_Handle(WOLFSSH* ssh, byte* handle, int handleSz,
WS_SFTP_FILEATRB* atr)
{
WOLFSSH_UNUSED(ssh);
WOLFSSH_UNUSED(handle);
WOLFSSH_UNUSED(handleSz);
WOLFSSH_UNUSED(atr);
WLOG(WS_LOG_SFTP, "SFTP_GetAttributes_Handle() not implemented yet");
return WS_NOT_COMPILED;
}
#elif defined(WOLFSSH_USER_FILESYSTEM)
/* User-defined I/O support */
#else
@ -4643,12 +4763,12 @@ int SFTP_GetAttributes(void* fs, const char* fileName, WS_SFTP_FILEATRB* atr,
if (noFollow) {
/* Note, for windows, we treat WSTAT and WLSTAT the same. */
if (WLSTAT(ssh->fs, fileName, &stats) != 0) {
if (WLSTAT(fs, fileName, &stats) != 0) {
return WS_BAD_FILE_E;
}
}
else {
if (WSTAT(ssh->fs, fileName, &stats) != 0) {
if (WSTAT(fs, fileName, &stats) != 0) {
return WS_BAD_FILE_E;
}
}
@ -4693,7 +4813,7 @@ int SFTP_GetAttributes_Handle(WOLFSSH* ssh, byte* handle, int handleSz,
WLOG(WS_LOG_SFTP, "Unexpected handle size SFTP_GetAttributes_Handle()");
}
if (fstat(*(int*)handle, &stats) != 0) {
if (WFSTAT(ssh->fs, *(int*)handle, &stats) != 0) {
return WS_BAD_FILE_E;
}
@ -4968,7 +5088,7 @@ int wolfSSH_SFTP_RecvLSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
}
#ifndef USE_WINDOWS_API
#if !defined(USE_WINDOWS_API) && !defined(WOLFSSH_ZEPHYR)
/* Set the files mode
* return WS_SUCCESS on success */
static int SFTP_SetMode(WOLFSSH* ssh, char* name, word32 mode) {
@ -4981,7 +5101,7 @@ static int SFTP_SetMode(WOLFSSH* ssh, char* name, word32 mode) {
#endif
#ifndef _WIN32_WCE
#if !defined(_WIN32_WCE) && !defined(WOLFSSH_ZEPHYR)
/* sets a files attributes
* returns WS_SUCCESS on success */
@ -4999,7 +5119,7 @@ static int SFTP_SetFileAttributes(WOLFSSH* ssh, char* name, WS_SFTP_FILEATRB* at
/* @TODO set group and user id */
}
#ifndef USE_WINDOWS_API
#if !defined(USE_WINDOWS_API) && !defined(WOLFSSH_ZEPHYR)
/* check if permissions attribute present */
if (atr->flags & WOLFSSH_FILEATRB_PERM) {
ret = SFTP_SetMode(ssh, name, atr->per);

View File

@ -27,6 +27,7 @@
#else
#include <wolfssl/options.h>
#endif
#include <wolfssl/wolfcrypt/wc_port.h>
#include <stdio.h>
#include <wolfssh/ssh.h>
@ -59,13 +60,24 @@ char* myoptarg = NULL;
#define WABORT()
#endif
#define Fail(description, result) do { \
#define PrintError(description, result) do { \
printf("\nERROR - %s line %d failed with:", __FILE__, __LINE__); \
fputs("\n expected: ", stdout); printf description; \
fputs("\n result: ", stdout); printf result; fputs("\n\n", stdout); \
fflush(stdout); \
printf("\n expected: "); printf description; \
printf("\n result: "); printf result; printf("\n\n"); \
} while(0)
#ifdef WOLFSSH_ZEPHYR
#define Fail(description, result) do { \
PrintError(description, result); \
WABORT(); \
} while(0)
#else
#define Fail(description, result) do { \
PrintError(description, result); \
WFFLUSH(stdout); \
WABORT(); \
} while(0)
#endif
#define Assert(test, description, result) if (!(test)) Fail(description, result)
@ -846,6 +858,10 @@ static void test_wolfSSH_SFTP_SendReadPacket(void)
wolfSSH_free(ssh);
wolfSSH_CTX_free(ctx);
#ifdef WOLFSSH_ZEPHYR
/* Weird deadlock without this sleep */
k_sleep(Z_TIMEOUT_TICKS(100));
#endif
ThreadJoin(serThread);
}

View File

@ -23,6 +23,10 @@
#endif
#include <stdio.h>
#include <wolfssh/settings.h>
#if defined(WOLFSSH_SFTP) && !defined(SINGLE_THREADED)
#include <wolfssh/ssh.h>
#include <wolfssh/wolfsftp.h>
@ -34,16 +38,22 @@
#include "examples/echoserver/echoserver.h"
#include "examples/sftpclient/sftpclient.h"
#if defined(WOLFSSH_SFTP) && !defined(SINGLE_THREADED)
static const char* cmds[] = {
"mkdir a",
"cd a",
"pwd",
"ls",
#ifdef WOLFSSH_ZEPHYR
"put " CONFIG_WOLFSSH_SFTP_DEFAULT_DIR "/configure",
#else
"put configure",
#endif
"ls",
#ifdef WOLFSSH_ZEPHYR
"get configure " CONFIG_WOLFSSH_SFTP_DEFAULT_DIR "/test-get",
#else
"get configure test-get",
#endif
"rm configure",
"cd ../",
"ls",
@ -85,11 +95,19 @@ static int Expected(int command)
case 4:
{
#ifdef WOLFSSH_ZEPHYR
/* No . and .. in zephyr fs API */
char expt1[] = "wolfSSH sftp> ";
char expt2[] = "wolfSSH sftp> ";
#else
char expt1[] = ".\n..\nwolfSSH sftp> ";
char expt2[] = "..\n.\nwolfSSH sftp> ";
#endif
if (WMEMCMP(expt1, inBuf, sizeof(expt1)) != 0 &&
WMEMCMP(expt2, inBuf, sizeof(expt2)) != 0) {
fprintf(stderr, "Unexpected string of %s\n", inBuf);
printf("unexpected ls\n");
printf("\texpected \n%s\n\tor\n%s\n\tbut got\n%s\n", expt1,
expt2, inBuf);
return -1;
}
else
@ -166,7 +184,8 @@ int wolfSSH_SftpTest(int flag)
char portNumber[8];
THREAD_TYPE serThread;
THREAD_TYPE cliThread;
wolfSSH_Init();
WMEMSET(&ser, 0, sizeof(func_args));
WMEMSET(&cli, 0, sizeof(func_args));
@ -212,11 +231,15 @@ int wolfSSH_SftpTest(int flag)
cli.argc = argsCount;
cli.signal = &ready;
cli.sftp_cb = commandCb;
ThreadStart(sftpclient_test, (void*)&cli, &cliThread);
sftpclient_test(&cli);
#ifdef WOLFSSH_ZEPHYR
/* Weird deadlock without this sleep */
k_sleep(Z_TIMEOUT_TICKS(100));
#endif
ThreadJoin(serThread);
ThreadJoin(cliThread);
wolfSSH_Cleanup();
return ret;
}

View File

@ -134,7 +134,7 @@ int wolfSSH_TestsuiteTest(int argc, char** argv)
WSTRNCPY(serverArgv[serverArgc++], "echoserver", ARGLEN);
WSTRNCPY(serverArgv[serverArgc++], "-1", ARGLEN);
WSTRNCPY(serverArgv[serverArgc++], "-f", ARGLEN);
#ifndef USE_WINDOWS_API
#if !defined(USE_WINDOWS_API) && !defined(WOLFSSH_ZEPHYR)
WSTRNCPY(serverArgv[serverArgc++], "-p", ARGLEN);
WSTRNCPY(serverArgv[serverArgc++], "-0", ARGLEN);
#endif
@ -150,7 +150,7 @@ int wolfSSH_TestsuiteTest(int argc, char** argv)
WSTRNCPY(cA[clientArgc++], "client", ARGLEN);
WSTRNCPY(cA[clientArgc++], "-u", ARGLEN);
WSTRNCPY(cA[clientArgc++], "jill", ARGLEN);
#ifndef USE_WINDOWS_API
#if !defined(USE_WINDOWS_API) && !defined(WOLFSSH_ZEPHYR)
WSTRNCPY(cA[clientArgc++], "-p", ARGLEN);
WSNPRINTF(cA[clientArgc++], ARGLEN, "%d", ready.port);
#endif
@ -166,6 +166,10 @@ int wolfSSH_TestsuiteTest(int argc, char** argv)
return clientArgs.return_code;
}
#ifdef WOLFSSH_ZEPHYR
/* Weird deadlock without this sleep */
k_sleep(Z_TIMEOUT_TICKS(100));
#endif
ThreadJoin(serverThread);
wolfSSH_Cleanup();
@ -174,8 +178,10 @@ int wolfSSH_TestsuiteTest(int argc, char** argv)
#ifdef WOLFSSH_SFTP
printf("testing SFTP blocking\n");
wolfSSH_SftpTest(0);
#ifndef WOLFSSH_NO_NONBLOCKING
printf("testing SFTP non blocking\n");
wolfSSH_SftpTest(1);
#endif
#endif
return EXIT_SUCCESS;

View File

@ -35,7 +35,7 @@
#define WOLFSSH_TEST_HEX2BIN
#include <wolfssh/test.h>
#include "tests/unit.h"
#include "unit.h"
/* Key Derivation Function (KDF) Unit Test */

View File

@ -351,6 +351,38 @@ extern "C" {
#define WOPENDIR(fs,h,c,d) f_opendir((c),(d))
#define WCLOSEDIR(fs,d) f_closedir(d)
#endif
#elif defined(WOLFSSH_ZEPHYR)
#include <zephyr/fs/fs.h>
#include <stdlib.h>
#include <stdio.h>
#define WFFLUSH(s) ((void)(s))
#define WFILE struct fs_file_t
#define FLUSH_STD(a)
int z_fs_chdir(const char *path);
/* Use wolfCrypt z_fs_open and z_fs_close */
#define WFOPEN(fs,f,fn,m) ((*(f) = z_fs_open((fn),(m))) == NULL)
#define WFCLOSE(fs,f) z_fs_close(f)
#define WFREAD(fs,b,s,a,f) fs_read((f),(b),(s)*(a))
#define WFWRITE(fs,b,s,a,f) fs_write((f),(b),(s)*(a))
#define WFSEEK(fs,s,o,w) fs_seek((s),(o),(w))
#define WFTELL(fs,s) fs_tell((s))
#define WREWIND(fs,s) fs_seek((s), 0, FS_SEEK_SET)
#define WSEEK_END FS_SEEK_END
#define WBADFILE NULL
#define WCHMOD(fs,f,m) chmod((f),(m))
#undef WFGETS
#define WFGETS(b,s,f) NULL /* Not ported yet */
#undef WFPUTS
#define WFPUTS(b,s) EOF /* Not ported yet */
#define WUTIMES(a,b) (0) /* Not ported yet */
#define WCHDIR(fs,b) z_fs_chdir((b))
#elif defined(WOLFSSH_USER_FILESYSTEM)
/* User-defined I/O support */
#else
@ -361,12 +393,15 @@ extern "C" {
#define WFILE FILE
WOLFSSH_API int wfopen(WFILE**, const char*, const char*);
#define WFFLUSH fflush
#define WFOPEN(fs,f,fn,m) wfopen((f),(fn),(m))
#define WFCLOSE(fs,f) fclose(f)
#define WFREAD(fs,b,s,a,f) fread((b),(s),(a),(f))
#define WFWRITE(fs,b,s,a,f) fwrite((b),(s),(a),(f))
#define WFSEEK(fs,s,o,w) fseek((s),(o),(w))
#define WFTELL(fs,s) ftell((s))
#define WFSTAT(fs,fd,b) fstat((fd),(b))
#define WREWIND(fs,s) rewind((s))
#define WSEEK_END SEEK_END
#define WBADFILE NULL
@ -481,7 +516,9 @@ extern "C" {
#define WVSNPRINTF(s,n,f,...) vsnprintf((s),(n),(f),__VA_ARGS__)
#define WSTRTOK(s1,s2,s3) strtok_r((s1),(s2),(s3))
#else
#ifndef FREESCALE_MQX
#ifdef WOLFSSH_ZEPHYR
#include <strings.h>
#elif !defined(FREESCALE_MQX)
#include <stdio.h>
#endif
#define WSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n))
@ -518,6 +555,9 @@ extern "C" {
#define WTIME(t1) mqx_time((t1))
#define WLOCALTIME(c,r) (localtime_r((c),(r))!=NULL)
#define WOLFSSH_NO_TIMESTAMP /* no strftime() */
#elif defined(WOLFSSH_ZEPHYR)
#define WTIME time
#define WLOCALTIME(c,r) (gmtime_r((c),(r))!=NULL)
#else
#define WTIME time
#define WLOCALTIME(c,r) (localtime_r((c),(r))!=NULL)
@ -1221,6 +1261,50 @@ extern "C" {
#define WDIR HANDLE
#endif /* NO_WOLFSSH_DIR */
#elif defined(WOLFSSH_ZEPHYR)
#include <zephyr/fs/fs.h>
#define WDIR struct fs_dir_t
#define WSTAT_T struct fs_dirent
/* FAT_FS fs_stat doesn't handling stat'ing the top level dir. Let's wrap
* and implement that. */
int wssh_z_fstat(const char *p, struct fs_dirent *b);
#define WOPENDIR(fs,h,c,d) (fs_dir_t_init((c)), fs_opendir((c),(d)))
#define WCLOSEDIR(fs,d) fs_closedir((d))
#define WMKDIR(fs,p,m) fs_mkdir((p))
#define WRMDIR(fs,d) fs_unlink((d))
#define WSTAT(fs,p,b) wssh_z_fstat((p),(b))
#define WREMOVE(fs,d) fs_unlink((d))
#define WRENAME(fs,o,n) fs_rename((o),(n))
#define WS_DELIM '/'
#define WOLFSSH_O_RDWR FS_O_RDWR
#define WOLFSSH_O_RDONLY FS_O_READ
#define WOLFSSH_O_WRONLY FS_O_WRITE
#define WOLFSSH_O_APPEND FS_O_APPEND
#define WOLFSSH_O_CREAT FS_O_CREATE
#define WOLFSSH_O_TRUNC 0
#define WOLFSSH_O_EXCL 0
/* Our "file descriptor" wrapper */
#ifndef WOLFSSH_MAX_DESCIPRTORS
#define WOLFSSH_MAX_DESCIPRTORS 10
#endif
#define WFD int
int wssh_z_fds_init(void);
int wssh_z_fds_cleanup(void);
WFD wssh_z_open(const char *p, int f);
#define WOPEN(fs,p,f,m) wssh_z_open((p),(f))
int wssh_z_close(WFD fd);
#define WCLOSE(fs,fd) wssh_z_close((fd))
int wPwrite(WFD, unsigned char*, unsigned int, const unsigned int*);
int wPread(WFD, unsigned char*, unsigned int, const unsigned int*);
#define WPWRITE(fs,fd,b,s,o) wPwrite((fd),(b),(s),(o))
#define WPREAD(fs,fd,b,s,o) wPread((fd),(b),(s),(o))
#elif defined(WOLFSSH_USER_FILESYSTEM)
/* User-defined I/O support */
#include "myFilesystem.h"

View File

@ -38,6 +38,10 @@
#include "wolfSSL.I-CUBE-wolfSSH_conf.h"
#endif
#if defined(WOLFSSH_ZEPHYR) && defined(CONFIG_WOLFSSH_SETTINGS_FILE)
#include CONFIG_WOLFSSH_SETTINGS_FILE
#endif
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -126,6 +126,35 @@
#endif
#define SOCKET_T int
#define NUM_SOCKETS 5
#elif defined(WOLFSSH_ZEPHYR)
#include <zephyr/kernel.h>
#include <zephyr/posix/posix_types.h>
#include <zephyr/posix/pthread.h>
#include <zephyr/posix/fcntl.h>
#include <zephyr/net/socket.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/util.h>
#include <stdlib.h>
#define SOCKET_T int
#define NUM_SOCKETS 5
#if (defined(WOLFSSH_TEST_CLIENT) || defined(WOLFSSH_TEST_SERVER)) && \
!defined(TEST_IPV6)
static unsigned long inet_addr(const char *cp)
{
unsigned int a[4]; unsigned long ret;
int i, j;
for (i=0, j=0; i<4; i++) {
a[i] = 0;
while (cp[j] != '.' && cp[j] != '\0') {
a[i] *= 10;
a[i] += cp[j] - '0';
j++;
}
}
ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ;
return(ret) ;
}
#endif
#elif defined(WOLFSSH_USER_IO)
#include <unistd.h>
#include <pthread.h>
@ -169,7 +198,7 @@
#elif defined(WOLFSSH_TIRTOS)
#define WOLFSSH_SOCKET_INVALID ((SOCKET_T)-1)
#else
#define WOLFSSH_SOCKET_INVALID (SOCKET_T)(0)
#define WOLFSSH_SOCKET_INVALID (SOCKET_T)(-1)
#endif
#endif /* WOLFSSH_SOCKET_INVALID */
@ -222,7 +251,9 @@
#define serverKeyRsaPemFile "./keys/server-key-rsa.pem"
#ifndef TEST_IPV6
#ifdef WOLFSSH_ZEPHYR
static const char* const wolfSshIp = "192.0.2.1";
#elif !defined(TEST_IPV6)
static const char* const wolfSshIp = "127.0.0.1";
#else /* TEST_IPV6 */
static const char* const wolfSshIp = "::1";
@ -252,6 +283,12 @@ static INLINE void err_sys(const char* msg)
{
printf("wolfSSH error: %s\n", msg);
}
#elif defined(WOLFSSH_ZEPHYR)
static INLINE void err_sys(const char* msg)
{
printf("wolfSSH error: %s errno: %d\n", msg, errno);
exit(EXIT_FAILURE);
}
#else
static INLINE WS_NORETURN void err_sys(const char* msg)
{
@ -397,7 +434,21 @@ static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
#ifndef TEST_IPV6
/* peer could be in human readable form */
if ( ((size_t)peer != INADDR_ANY) && isalpha((int)peer[0])) {
if ( ((size_t)peer != INADDR_ANY) && isalnum((int)peer[0])) {
#ifdef WOLFSSH_ZEPHYR
struct zsock_addrinfo hints, *addrInfo;
char portStr[6];
XSNPRINTF(portStr, sizeof(portStr), "%d", port);
XMEMSET(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if (getaddrinfo((char*)peer, portStr, &hints, &addrInfo) == 0) {
XMEMCPY(addr, addrInfo->ai_addr, sizeof(*addr));
freeaddrinfo(addrInfo);
useLookup = 1;
}
#else
#ifdef CYASSL_MDK_ARM
int err;
struct hostent* entry = gethostbyname(peer, &err);
@ -408,6 +459,7 @@ static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
NU_HOSTENT h;
entry = &h;
NU_Get_Host_By_Name((char*)peer, entry);
#elif defined(WOLFSSH_ZEPHYR)
#else
struct hostent* entry = gethostbyname(peer);
#endif
@ -424,6 +476,7 @@ static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
}
else
err_sys("no entry for host");
#endif
}
#endif
@ -499,6 +552,8 @@ static INLINE void tcp_socket(WS_SOCKET_T* sockFd)
*sockFd = 0;
#elif defined(MICROCHIP_TCPIP)
*sockFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
#elif defined(WOLFSSH_ZEPHYR)
*sockFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
#elif defined(WOLFSSL_NUCLEUS)
*sockFd = NU_Socket(NU_FAMILY_IP, NU_TYPE_STREAM, 0);
#else
@ -530,6 +585,8 @@ static INLINE void tcp_socket(WS_SOCKET_T* sockFd)
/* nothing to define */
#elif defined(WOLFSSL_ESPIDF)
/* nothing to define */
#elif defined(WOLFSSL_ZEPHYR)
/* nothing to define */
#else /* no S_NOSIGPIPE */
signal(SIGPIPE, SIG_IGN);
#endif /* S_NOSIGPIPE */
@ -581,9 +638,10 @@ static INLINE void tcp_listen(WS_SOCKET_T* sockfd, word16* port, int useAnyAddr)
build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSshIp), *port);
tcp_socket(sockfd);
#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)\
&& !defined(WOLFSSL_KEIL_TCP_NET)\
&& !defined(WOLFSSL_NUCLEUS)
#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM) \
&& !defined(WOLFSSL_KEIL_TCP_NET) \
&& !defined(WOLFSSL_NUCLEUS) \
&& !defined(WOLFSSH_ZEPHYR)
{
int res;
#ifdef MICROCHIP_TCPIP
@ -844,6 +902,7 @@ static INLINE void WaitTcpReady(func_args* args)
#define WOLFSSL_V5_5_1 0x05005001
#if (LIBWOLFSSL_VERSION_HEX < WOLFSSL_V5_5_1) && !defined(WOLFSSL_THREAD)
#define WOLFSSH_OLD_THREADING
#ifdef SINGLE_THREADED
typedef unsigned int THREAD_RETURN;
typedef void* THREAD_TYPE;
@ -871,6 +930,27 @@ static INLINE void WaitTcpReady(func_args* args)
#ifdef WOLFSSH_TEST_THREADING
#ifndef WOLFSSH_OLD_THREADING
static INLINE void ThreadStart(THREAD_CB fun, void* args, THREAD_TYPE* thread)
{
(void)wolfSSL_NewThread(thread, fun, args);
}
static INLINE void ThreadJoin(THREAD_TYPE thread)
{
(void)wolfSSL_JoinThread(thread);
}
#ifdef WOLFSSL_THREAD_NO_JOIN
static INLINE void ThreadStartNoJoin(THREAD_CB fun, void* args)
{
(void)wolfSSL_NewThreadNoJoin(fun, args);
}
#endif
#else
typedef THREAD_RETURN (WOLFSSH_THREAD *THREAD_FUNC)(void*);
@ -969,6 +1049,15 @@ static INLINE void ThreadDetach(THREAD_TYPE thread)
#endif
}
static INLINE void ThreadStartNoJoin(THREAD_FUNC fun, void* args)
{
THREAD_TYPE thread;
ThreadStart(fun, args, &thread);
ThreadDetach(thread);
}
#endif /* WOLFSSH_OLD_THREADING */
#endif /* WOLFSSH_TEST_THREADING */
#ifdef TEST_IPV6

View File

@ -83,6 +83,9 @@ enum WS_ScpFileStates {
#elif defined(USE_WINDOWS_API)
char* entry;
WIN32_FILE_ATTRIBUTE_DATA s;
#elif defined(WOLFSSH_ZEPHYR)
struct fs_dirent entry;
WSTAT_T s; /* stat info from file */
#else
struct dirent* entry; /* file entry, from readdir() */
struct stat s; /* stat info from file */

View File

@ -0,0 +1,13 @@
if(CONFIG_WOLFSSH)
zephyr_include_directories(${ZEPHYR_CURRENT_MODULE_DIR})
zephyr_include_directories(${ZEPHYR_CURRENT_MODULE_DIR}/zephyr)
zephyr_library_include_directories(${ZEPHYR_CURRENT_MODULE_DIR})
FILE(GLOB wolfssh_sources ${ZEPHYR_CURRENT_MODULE_DIR}/src/*.c)
target_sources(app PRIVATE ${wolfssh_sources})
if(CONFIG_WOLFSSH_DEBUG)
target_compile_definitions(app PUBLIC DEBUG_WOLFSSH)
endif()
target_compile_definitions(app PUBLIC WOLFSSH_ZEPHYR)
target_compile_definitions(app PUBLIC WOLFSSH_IGNORE_FILE_WARN)
target_compile_definitions(app PUBLIC WOLFSSH_NO_TIMESTAMP)
endif()

25
zephyr/Kconfig 100644
View File

@ -0,0 +1,25 @@
menuconfig WOLFSSH
bool "wolfSSH module support"
select WOLFSSL
if WOLFSSH
config WOLFSSH_SETTINGS_FILE
string "wolfSSH settings file"
help
Use a specific wolfSSH settings file.
config WOLFSSH_SFTP_DEFAULT_DIR
string "wolfSSH sftp default directory"
help
Use a specific directory as the default wolfSSH sftp working directory.
config WOLFSSH_DEBUG
bool "wolfSSH debug activation"
help
Enable debugging activation for wolfSSH.
config ZEPHYR_WOLFSSH_MODULE
bool
depends on WOLFSSH
endif

69
zephyr/README.md 100644
View File

@ -0,0 +1,69 @@
Zephyr Project Port
===================
## Overview
This port is for the Zephyr RTOS Project, available [here](https://www.zephyrproject.org/).
It provides the following zephyr code.
- modules/lib/wolfssh
- wolfSSH library code
- modules/lib/wolfssh/zephyr/
- Configuration and CMake files for wolfSSH as a Zephyr module
- modules/lib/wolfssh/zephyr/samples/tests
- wolfSSH tests
## How to setup as a Zephyr Module
Follow the [instructions](https://docs.zephyrproject.org/latest/develop/getting_started/index.html) to setup a zephyr project.
### Modify your project's west manifest
Add wolfSSH as a project to your west.yml:
```
manifest:
remotes:
# <your other remotes>
- name: wolfssh
url-base: https://github.com/wolfssl
projects:
# <your other projects>
- name: wolfssh
path: modules/lib/wolfssh
revision: master
remote: wolfssh
```
Update west's modules:
```bash
west update
```
Now west recognizes 'wolfssh' as a module, and will include it's Kconfig and
CMakeFiles.txt in the build system.
## Build and Run Samples
If you want to run build apps without running `west zephyr-export` then it is
possible by setting the `CMAKE_PREFIX_PATH` variable to the location of the
zephyr sdk and building from the `zephyr` directory. For example:
```
CMAKE_PREFIX_PATH=/path/to/zephyr-sdk-<VERSION> west build -p always -b qemu_x86 ../modules/lib/wolfssh/zephyr/samples/tests/
```
### Build and Run Tests
build and execute `tests`
```bash
cd [zephyrproject]
west build -p auto -b qemu_x86 modules/lib/wolfssh/zephyr/samples/tests
west build -t run
```

View File

@ -0,0 +1,6 @@
name: wolfssh
build:
cmake: zephyr
kconfig: zephyr/Kconfig
depends:
- wolfssl

View File

@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(wolfssl_tests)
FILE(GLOB app_sources ../../../tests/*.c ../../../examples/client/client.c
../../../examples/client/common.c ../../../examples/echoserver/echoserver.c
../../../examples/sftpclient/sftpclient.c tests.c)
target_sources(app PRIVATE ${app_sources})
add_definitions(-DWOLFSSL_ZEPHYR)
add_definitions(-DWOLFSSL_USER_SETTINGS)

View File

@ -0,0 +1,78 @@
# Kernel options
CONFIG_MAIN_STACK_SIZE=32768
CONFIG_ENTROPY_GENERATOR=y
CONFIG_INIT_STACKS=y
CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=131072
# Enable wolfSSH
CONFIG_WOLFSSH=y
CONFIG_WOLFSSH_SETTINGS_FILE="samples/tests/user_settings.h"
CONFIG_WOLFSSH_SFTP_DEFAULT_DIR="/RAM:"
# Pthreads
CONFIG_PTHREAD_IPC=y
# Clock for time()
CONFIG_POSIX_CLOCK=y
# Networking
CONFIG_NETWORKING=y
CONFIG_NET_TEST=y
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=n
CONFIG_NET_TCP=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_NET_TEST=y
CONFIG_NET_LOOPBACK=y
# Network driver config
CONFIG_TEST_RANDOM_GENERATOR=y
# Network address config
CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_CONFIG_NEED_IPV4=y
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1"
CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2"
CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2"
CONFIG_NET_PKT_TX_COUNT=10
# Logging
CONFIG_PRINTK=y
CONFIG_LOG=y
CONFIG_LOG_MODE_IMMEDIATE=y
#CONFIG_WOLFSSH_DEBUG=y
#CONFIG_WOLFSSL_DEBUG=y
#CONFIG_DEBUG=y
# Enable logging using RTT and UART
#CONFIG_CBPRINTF_LIBC_SUBSTS=y
#CONFIG_CBPRINTF_FP_SUPPORT=y
#CONFIG_CONSOLE=y
#CONFIG_LOG_BACKEND_UART=y
#CONFIG_LOG_BUFFER_SIZE=15360
# TLS configuration
CONFIG_WOLFSSL=y
CONFIG_WOLFSSL_BUILTIN=y
CONFIG_WOLFSSL_SETTINGS_FILE="samples/tests/wolfssl_user_settings.h"
CONFIG_WOLFSSL_TLS_VERSION_1_2=y
CONFIG_WOLFSSL_KEY_EXCHANGE_ALL_ENABLED=y
CONFIG_WOLFSSL_CIPHER_ALL_ENABLED=y
CONFIG_WOLFSSL_MAC_ALL_ENABLED=y
CONFIG_WOLFSSL_HMAC_DRBG_ENABLED=y
# FS
CONFIG_DISK_ACCESS=y
CONFIG_DISK_DRIVERS=y
CONFIG_DISK_DRIVER_RAM=y
CONFIG_DISK_RAM_VOLUME_SIZE=64
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_MKFS=y
CONFIG_FAT_FILESYSTEM_ELM=y
CONFIG_FS_FATFS_LFN=y
CONFIG_FS_FATFS_LFN_MODE_STACK=y

View File

@ -0,0 +1,15 @@
sample:
description: wolfSSH tests
name: wolfSSH tests
common:
harness: console
harness_config:
type: one_line
regex:
- "Zephyr wolfSSH tests passed"
tests:
sample.lib.wolfssh_tests:
timeout: 50
platform_allow: qemu_x86
integration_platforms:
- qemu_x86

View File

@ -0,0 +1,100 @@
/* tests.c
*
* Copyright (C) 2014-2023 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/>.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef WOLFSSL_USER_SETTINGS
#include <wolfssl/wolfcrypt/settings.h>
#else
#include <wolfssl/options.h>
#endif
/* tests/unit.h collides with the wolfSSL header so use relative include */
#include "../../../tests/unit.h"
#include "../../../tests/testsuite.h"
#include "../../../tests/api.h"
#include "../../../tests/sftp.h"
#include <stdio.h>
#include <wolfssh/settings.h>
#include <wolfssh/ssh.h>
#include <zephyr/fs/fs.h>
#include <zephyr/storage/disk_access.h>
#include <ff.h>
#ifndef CONFIG_FAT_FILESYSTEM_ELM
#error "This test is designed for FAT FS"
#endif
#define CHECK_TEST_RETURN(func) do { \
printf("\tRunning %s... ", #func); \
ret = (func); \
if (ret != 0) { \
printf("failed with %d\n", ret); \
goto exit_main; \
} \
printf("ok\n"); \
} while(0)
int main(void)
{
int ret = 0;
static FATFS fat_fs;
static struct fs_mount_t mnt_point = {
.type = FS_FATFS,
.mnt_point = CONFIG_WOLFSSH_SFTP_DEFAULT_DIR,
.fs_data = &fat_fs,
};
struct fs_file_t zfp;
char file_contents[5];
int i;
char filename[50];
WMEMSET(file_contents, 0xFE, sizeof(file_contents));
/* +1 because the default dir mount point starts with a / and we want to
* remove it when formatting */
CHECK_TEST_RETURN(fs_mkfs(FS_FATFS,
(uintptr_t)(CONFIG_WOLFSSH_SFTP_DEFAULT_DIR+1), NULL, 0));
CHECK_TEST_RETURN(fs_mount(&mnt_point));
/* Setup the necessary files for the sftp tests */
fs_file_t_init(&zfp);
snprintf(filename, sizeof(filename), "%s/%s",
CONFIG_WOLFSSH_SFTP_DEFAULT_DIR, "configure");
CHECK_TEST_RETURN(fs_open(&zfp, filename, FS_O_WRITE|FS_O_CREATE));
/* Write some random data to file */
for (i = 0; i < 10; i++)
CHECK_TEST_RETURN(fs_write(&zfp, file_contents, sizeof(file_contents))
< 0);
CHECK_TEST_RETURN(fs_close(&zfp));
CHECK_TEST_RETURN(wolfSSH_UnitTest(0, NULL));
CHECK_TEST_RETURN(wolfSSH_TestsuiteTest(0, NULL));
CHECK_TEST_RETURN(wolfSSH_ApiTest(0, NULL));
printf("Zephyr wolfSSH tests passed\n");
exit_main:
return ret;
}

View File

@ -0,0 +1,68 @@
/* user_settings.h
*
* Copyright (C) 2014-2023 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/>.
*/
#ifndef WOLFSSH_USER_SETTINGS_H
#define WOLFSSH_USER_SETTINGS_H
#ifdef __cplusplus
extern "C" {
#endif
#include <wolfssl/wolfcrypt/types.h>
#undef WOLFSSH_SFTP
#define WOLFSSH_SFTP
#undef WOLFSSH_SCP
#define WOLFSSH_SCP
#undef NO_APITEST_MAIN_DRIVER
#define NO_APITEST_MAIN_DRIVER
#undef NO_TESTSUITE_MAIN_DRIVER
#define NO_TESTSUITE_MAIN_DRIVER
#undef NO_UNITTEST_MAIN_DRIVER
#define NO_UNITTEST_MAIN_DRIVER
#undef NO_MAIN_DRIVER
#define NO_MAIN_DRIVER
#undef WS_NO_SIGNAL
#define WS_NO_SIGNAL
#undef WS_USE_TEST_BUFFERS
#define WS_USE_TEST_BUFFERS
#undef NO_WOLFSSL_DIR
#define NO_WOLFSSL_DIR
#undef WOLFSSH_NO_NONBLOCKING
#define WOLFSSH_NO_NONBLOCKING
#define DEFAULT_WINDOW_SZ (128 * 128)
#define WOLFSSH_MAX_SFTP_RW 8192
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,134 @@
/* wolfssl_user_settings.h
*
* Copyright (C) 2014-2023 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/>.
*/
#ifndef WOLFSSL_USER_SETTINGS_H
#define WOLFSSL_USER_SETTINGS_H
#ifdef __cplusplus
extern "C" {
#endif
#undef WOLFSSL_ZEPHYR
#define WOLFSSL_ZEPHYR
#undef TFM_TIMING_RESISTANT
#define TFM_TIMING_RESISTANT
#undef ECC_TIMING_RESISTANT
#define ECC_TIMING_RESISTANT
#undef WC_RSA_BLINDING
#define WC_RSA_BLINDING
#undef HAVE_AESGCM
#define HAVE_AESGCM
#undef WOLFSSL_SHA512
#define WOLFSSL_SHA512
#undef WOLFSSL_SHA384
#define WOLFSSL_SHA384
#undef NO_DSA
#define NO_DSA
#undef HAVE_ECC
#define HAVE_ECC
#undef TFM_ECC256
#define TFM_ECC256
#undef WOLFSSL_BASE64_ENCODE
#define WOLFSSL_BASE64_ENCODE
#undef NO_RC4
#define NO_RC4
#undef WOLFSSL_SHA224
#define WOLFSSL_SHA224
#undef WOLFSSL_SHA3
#define WOLFSSL_SHA3
#undef HAVE_POLY1305
#define HAVE_POLY1305
#undef HAVE_ONE_TIME_AUTH
#define HAVE_ONE_TIME_AUTH
#undef HAVE_CHACHA
#define HAVE_CHACHA
#undef HAVE_HASHDRBG
#define HAVE_HASHDRBG
#undef HAVE_TLS_EXTENSIONS
#define HAVE_TLS_EXTENSIONS
#undef HAVE_SUPPORTED_CURVES
#define HAVE_SUPPORTED_CURVES
#undef HAVE_EXTENDED_MASTER
#define HAVE_EXTENDED_MASTER
#undef NO_PSK
#define NO_PSK
#undef NO_MD4
#define NO_MD4
#undef NO_PWDBASED
#define NO_PWDBASED
#undef USE_FAST_MATH
#define USE_FAST_MATH
#undef WOLFSSL_NO_ASM
#define WOLFSSL_NO_ASM
#undef WOLFSSL_X86_BUILD
#define WOLFSSL_X86_BUILD
#undef WC_NO_ASYNC_THREADING
#define WC_NO_ASYNC_THREADING
#undef NO_DES3
#define NO_DES3
#undef WOLFSSL_STATIC_MEMORY
#define WOLFSSL_STATIC_MEMORY
#undef WOLFSSL_TLS13
#define WOLFSSL_TLS13
#undef HAVE_HKDF
#define HAVE_HKDF
#undef WC_RSA_PSS
#define WC_RSA_PSS
#undef HAVE_FFDHE_2048
#define HAVE_FFDHE_2048
#ifdef __cplusplus
}
#endif
#endif /* WOLFSSL_USER_SETTINGS_H */