initial port to Nucleus

update example on Nucleus

add code sourcery IDE project

fix naming of IDE project files

clean up opendir for fail case

fix for build warnings

add fstat and fixes for nucleus port

update FALL_THROUGH case

add null terminator and more memory free's

fix for scan build warnings

fix warning of no return value

better bounds checking

better path cleaning

fix return values in header file

clean path before access

remove trailing delimiter from clean path
pull/73/head
Jacob Barthelmeh 2018-05-31 10:16:04 -06:00
parent 6261bb7d98
commit 6d434d0030
18 changed files with 1315 additions and 125 deletions

View File

@ -32,6 +32,10 @@
#include <wolfssh/test.h>
#include "examples/echoserver/echoserver.h"
#ifdef WOLFSSL_NUCLEUS
/* use buffers for keys with server */
#define NO_FILESYSTEM
#endif
#ifdef NO_FILESYSTEM
#include <wolfssh/certs_test.h>
@ -211,6 +215,10 @@ static THREAD_RETURN WOLFSSH_THREAD server_worker(void* vArgs)
exit(EXIT_FAILURE);
}
if (wolfSSH_shutdown(threadCtx->ssh) != WS_SUCCESS) {
fprintf(stderr, "Error with SSH shutdown.\n");
}
WCLOSESOCKET(threadCtx->fd);
wolfSSH_free(threadCtx->ssh);
free(threadCtx);
@ -585,6 +593,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
char** argv = serverArgs->argv;
serverArgs->return_code = 0;
if (argc > 0) {
while ((ch = mygetopt(argc, argv, "?1ep:")) != -1) {
switch (ch) {
case '?' :
@ -612,6 +621,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
exit(MY_EX_USAGE);
}
}
}
myoptind = 0; /* reset for test cases */
if (wolfSSH_Init() != WS_SUCCESS) {
@ -660,13 +670,41 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
buf[bufSz] = 0;
LoadPublicKeyBuffer(buf, bufSz, &pwMapList);
}
#ifdef WOLFSSL_NUCLEUS
{
int i;
int ret = !NU_SUCCESS;
/* wait for network and storage device */
if (NETBOOT_Wait_For_Network_Up(NU_SUSPEND) != NU_SUCCESS) {
fprintf(stderr, "Couldn't find network.\r\n");
exit(EXIT_FAILURE);
}
for(i = 0; i < 15 && ret != NU_SUCCESS; i++)
{
fprintf(stdout, "Checking for storage device\r\n");
ret = NU_Storage_Device_Wait(NU_NULL, NU_PLUS_TICKS_PER_SEC);
}
if (ret != NU_SUCCESS) {
fprintf(stderr, "Couldn't find storage device.\r\n");
exit(EXIT_FAILURE);
}
}
#endif
tcp_listen(&listenFd, &port, 1);
do {
SOCKET_T clientFd = 0;
#ifdef WOLFSSL_NUCLEUS
struct addr_struct clientAddr;
#else
SOCKADDR_IN_T clientAddr;
socklen_t clientAddrSz = sizeof(clientAddr);
#endif
WOLFSSH* ssh;
thread_ctx_t* threadCtx;
@ -688,10 +726,35 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
wolfSSH_SetHighwater(ssh, defaultHighwater);
}
#ifdef WOLFSSL_NUCLEUS
{
byte ipaddr[MAX_ADDRESS_SIZE];
char buf[16];
short addrLength;
struct sockaddr_struct sock;
addrLength = sizeof(struct sockaddr_struct);
/* 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");
exit(EXIT_FAILURE);
}
WMEMCPY(ipaddr, &sock.ip_num, MAX_ADDRESS_SIZE);
NU_Inet_NTOP(NU_FAMILY_IP, &ipaddr[0], buf, 16);
fprintf(stdout, "Listing on %s:%d\r\n", buf, port);
}
#endif
SignalTcpReady(serverArgs, port);
#ifdef WOLFSSL_NUCLEUS
clientFd = NU_Accept(listenFd, &clientAddr, 0);
#else
clientFd = accept(listenFd, (struct sockaddr*)&clientAddr,
&clientAddrSz);
#endif
if (clientFd == -1)
err_sys("tcp accept failed");
@ -715,6 +778,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
return 0;
}
#ifndef NO_MAIN_DRIVER
int main(int argc, char** argv)
@ -734,7 +798,9 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
wolfSSH_Init();
#ifndef WOLFSSL_NUCLEUS
ChangeToWolfSshRoot();
#endif
echoserver_test(&args);
wolfSSH_Cleanup();
@ -747,3 +813,37 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
char* myoptarg = NULL;
#endif /* NO_MAIN_DRIVER */
#ifdef WOLFSSL_NUCLEUS
#define WS_TASK_SIZE 200000
#define WS_TASK_PRIORITY 31
static NU_TASK serverTask;
/* expecting void return on main function */
static VOID main_nucleus(UNSIGNED argc, VOID* argv)
{
main((int)argc, (char**)argv);
}
/* using port 8080 because it was an open port on QEMU */
VOID Application_Initialize (NU_MEMORY_POOL* memPool,
NU_MEMORY_POOL* uncachedPool)
{
void* pt;
int ret;
UNUSED_PARAMETER(uncachedPool);
ret = NU_Allocate_Memory(memPool, &pt, WS_TASK_SIZE, NU_NO_SUSPEND);
if (ret == NU_SUCCESS) {
ret = NU_Create_Task(&serverTask, "wolfSSH Server", main_nucleus, 0,
NU_NULL, pt, WS_TASK_SIZE, WS_TASK_PRIORITY, 0,
NU_PREEMPT, NU_START);
if (ret != NU_SUCCESS) {
NU_Deallocate_Memory(pt);
}
}
}
#endif /* WOLFSSL_NUCLEUS */

View File

@ -0,0 +1,195 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="cdt.managedbuild.config.gnu.mentor.nucleus.exe.debug.1214077048">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.mentor.nucleus.exe.debug.1214077048" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.mentor.embedded.toolchains.core.nucleus.FuseErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="cs-rm -rf" description="" id="cdt.managedbuild.config.gnu.mentor.nucleus.exe.debug.1214077048" name="Debug" parent="cdt.managedbuild.config.gnu.mentor.nucleus.exe.debug" postbuildStep="${POSTLD} -O binary &quot;${CWD}/${ProjName}.out&quot; &quot;${CWD}/${ProjName}.bin&quot;" postcleanStep="">
<folderInfo id="cdt.managedbuild.config.gnu.mentor.nucleus.exe.debug.1214077048." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.mentor.nucleus.exe.debug.1208281997" name="Sourcery CodeBench for Nucleus" superClass="cdt.managedbuild.toolchain.gnu.mentor.nucleus.exe.debug">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.mentor.nucleus.1291172499" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.mentor.nucleus"/>
<builder buildPath="${workspace_loc:/CSBENCH}/Debug" id="cdt.managedbuild.builder.gnu.mentor.nucleus.363008008" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CodeSourcery GNU Builder" superClass="cdt.managedbuild.builder.gnu.mentor.nucleus"/>
<tool id="cdt.managedbuild.tool.gnu.mentor.archiver.nucleus.796002859" name="CodeSourcery GNU Archiver" superClass="cdt.managedbuild.tool.gnu.mentor.archiver.nucleus"/>
<tool id="cdt.managedbuild.tool.gnu.mentor.cpp.compiler.nucleus.1301230838" name="CodeSourcery GNU C++ Compiler" superClass="cdt.managedbuild.tool.gnu.mentor.cpp.compiler.nucleus">
<option id="mentor.gnu.cpp.compiler.option.optimization.level.166261543" name="Optimization Level" superClass="mentor.gnu.cpp.compiler.option.optimization.level" value="mentor.gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
<option id="mentor.gnu.cpp.compiler.option.debugging.level.1260284336" name="Debug Level" superClass="mentor.gnu.cpp.compiler.option.debugging.level" value="mentor.gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
<option id="mentor.gnu.cpp.compiler.option.indexer_include.2129830556" name="Include paths for indexer" superClass="mentor.gnu.cpp.compiler.option.indexer_include" valueType="includePath">
<listOptionValue builtIn="false" value="${CFG_INCLUDE}"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/./"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/bsp/realview_eb_ct926ejs/include/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/bsp/realview_eb_ct926ejs/include/bsp/arch/plat-realview_eb/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/os/arch/arm/tool-csgnu_arm/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/os/include/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/os/include/arch/arm/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/os/include/arch/arm/tool-csgnu_arm/"/>
</option>
</tool>
<tool id="cdt.managedbuild.tool.gnu.mentor.c.compiler.nucleus.733911603" name="CodeSourcery GNU C Compiler" superClass="cdt.managedbuild.tool.gnu.mentor.c.compiler.nucleus">
<option defaultValue="mentor.gnu.c.optimization.level.none" id="mentor.gnu.c.compiler.option.optimization.level.1781700399" name="Optimization Level" superClass="mentor.gnu.c.compiler.option.optimization.level" valueType="enumerated"/>
<option id="mentor.gnu.c.compiler.option.debugging.level.474868803" name="Debug Level" superClass="mentor.gnu.c.compiler.option.debugging.level" value="mentor.gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="mentor.gnu.c.compiler.option.indexer_include.335417164" name="Include paths for indexer" superClass="mentor.gnu.c.compiler.option.indexer_include" valueType="includePath">
<listOptionValue builtIn="false" value="${CFG_INCLUDE}"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/./"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/bsp/realview_eb_ct926ejs/include/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/bsp/realview_eb_ct926ejs/include/bsp/arch/plat-realview_eb/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/os/arch/arm/tool-csgnu_arm/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/os/include/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/os/include/arch/arm/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/os/include/arch/arm/tool-csgnu_arm/"/>
</option>
<option id="mentor.gnu.c.compiler.option.preprocessor.def.symbols.1534557880" name="Defined symbols (-D)" superClass="mentor.gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="WOLFSSL_USER_SETTINGS"/>
</option>
<option id="mentor.gnu.c.compiler.option.include.paths.2089432830" name="Include paths (-I)" superClass="mentor.gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="../../../"/>
<listOptionValue builtIn="false" value="../../../../wolfssl"/>
<listOptionValue builtIn="false" value="../../../../wolfssl/IDE/CSBENCH"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.mentor.c.compiler.nucleus.input.1877603173" superClass="cdt.managedbuild.tool.gnu.mentor.c.compiler.nucleus.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.mentor.c.linker.nucleus.1678700114" name="CodeSourcery GNU C Linker" superClass="cdt.managedbuild.tool.gnu.mentor.c.linker.nucleus">
<option id="mentor.gnu.c.link.option.libs.1194482769" name="Libraries (-l)" superClass="mentor.gnu.c.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" value="wolfssl"/>
</option>
<option id="mentor.gnu.c.link.option.paths.1319236070" name="Library search path (-L)" superClass="mentor.gnu.c.link.option.paths" valueType="libPaths">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/wolfcrypt/Debug}&quot;"/>
</option>
</tool>
<tool id="cdt.managedbuild.tool.gnu.mentor.cpp.linker.nucleus.596240520" name="CodeSourcery GNU C++ Linker" superClass="cdt.managedbuild.tool.gnu.mentor.cpp.linker.nucleus"/>
<tool id="cdt.managedbuild.tool.gnu.mentor.assembler.nucleus.1670834398" name="CodeSourcery GNU Assembler" superClass="cdt.managedbuild.tool.gnu.mentor.assembler.nucleus">
<option id="gnu.both.asm.option.debugging.level.1676640171" name="Debug Level" superClass="gnu.both.asm.option.debugging.level" value="gnu.both.asm.debugging.level.max" valueType="enumerated"/>
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.2026816449" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<tool id="com.mentor.embedded.toolchains.core.nucleus.exportgen.process.1917586302" name="Nucleus Exports Generator" superClass="com.mentor.embedded.toolchains.core.nucleus.exportgen.process"/>
<tool id="com.mentor.embedded.toolchains.core.nucleus.exportgen.application.2124639416" name="Nucleus Exports Generator" superClass="com.mentor.embedded.toolchains.core.nucleus.exportgen.application"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="src/misc.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings">
<externalSettings containerId="system-project;" factoryId="org.eclipse.cdt.core.cfg.export.settings.sipplier"/>
</storageModule>
</cconfiguration>
<cconfiguration id="cdt.managedbuild.config.gnu.mentor.nucleus.exe.release.593147631">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.mentor.nucleus.exe.release.593147631" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.mentor.embedded.toolchains.core.nucleus.FuseErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.mentor.nucleus.exe.release.593147631" name="Release" parent="cdt.managedbuild.config.gnu.mentor.nucleus.exe.release" postbuildStep="${POSTLD} -O binary &quot;${CWD}/${ProjName}.out&quot; &quot;${CWD}/${ProjName}.bin&quot;" postcleanStep="">
<folderInfo id="cdt.managedbuild.config.gnu.mentor.nucleus.exe.release.593147631." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.mentor.nucleus.exe.release.4556438" name="Sourcery CodeBench for Nucleus" superClass="cdt.managedbuild.toolchain.gnu.mentor.nucleus.exe.release">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.mentor.nucleus.655260117" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.mentor.nucleus"/>
<builder buildPath="${workspace_loc:/CSBENCH}/Release" id="cdt.managedbuild.builder.gnu.mentor.nucleus.461742616" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CodeSourcery GNU Builder" superClass="cdt.managedbuild.builder.gnu.mentor.nucleus"/>
<tool id="cdt.managedbuild.tool.gnu.mentor.archiver.nucleus.114153486" name="CodeSourcery GNU Archiver" superClass="cdt.managedbuild.tool.gnu.mentor.archiver.nucleus"/>
<tool id="cdt.managedbuild.tool.gnu.mentor.cpp.compiler.nucleus.79634184" name="CodeSourcery GNU C++ Compiler" superClass="cdt.managedbuild.tool.gnu.mentor.cpp.compiler.nucleus">
<option id="mentor.gnu.cpp.compiler.option.optimization.level.2040515769" name="Optimization Level" superClass="mentor.gnu.cpp.compiler.option.optimization.level" value="mentor.gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
<option id="mentor.gnu.cpp.compiler.option.debugging.level.1751501356" name="Debug Level" superClass="mentor.gnu.cpp.compiler.option.debugging.level"/>
<option id="mentor.gnu.cpp.compiler.option.indexer_include.1343364452" name="Include paths for indexer" superClass="mentor.gnu.cpp.compiler.option.indexer_include" valueType="includePath">
<listOptionValue builtIn="false" value="${CFG_INCLUDE}"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/./"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/bsp/realview_eb_ct926ejs/include/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/bsp/realview_eb_ct926ejs/include/bsp/arch/plat-realview_eb/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/os/arch/arm/tool-csgnu_arm/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/os/include/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/os/include/arch/arm/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/os/include/arch/arm/tool-csgnu_arm/"/>
</option>
</tool>
<tool id="cdt.managedbuild.tool.gnu.mentor.c.compiler.nucleus.28888809" name="CodeSourcery GNU C Compiler" superClass="cdt.managedbuild.tool.gnu.mentor.c.compiler.nucleus">
<option defaultValue="mentor.gnu.c.optimization.level.most" id="mentor.gnu.c.compiler.option.optimization.level.1932130070" name="Optimization Level" superClass="mentor.gnu.c.compiler.option.optimization.level" valueType="enumerated"/>
<option id="mentor.gnu.c.compiler.option.debugging.level.709958810" name="Debug Level" superClass="mentor.gnu.c.compiler.option.debugging.level"/>
<option id="mentor.gnu.c.compiler.option.indexer_include.717141201" name="Include paths for indexer" superClass="mentor.gnu.c.compiler.option.indexer_include" valueType="includePath">
<listOptionValue builtIn="false" value="${CFG_INCLUDE}"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/./"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/bsp/realview_eb_ct926ejs/include/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/bsp/realview_eb_ct926ejs/include/bsp/arch/plat-realview_eb/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/os/arch/arm/tool-csgnu_arm/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/os/include/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/os/include/arch/arm/"/>
<listOptionValue builtIn="false" value="${SYSTEM_HOME}/os/include/arch/arm/tool-csgnu_arm/"/>
</option>
<option id="mentor.gnu.c.compiler.option.preprocessor.def.symbols.925278548" name="Defined symbols (-D)" superClass="mentor.gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="WOLFSSL_USER_SETTINGS"/>
</option>
<option id="mentor.gnu.c.compiler.option.include.paths.308993068" name="Include paths (-I)" superClass="mentor.gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="../../../"/>
<listOptionValue builtIn="false" value="../../../../wolfssl"/>
<listOptionValue builtIn="false" value="../../../../wolfssl/IDE/CSBENCH"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.mentor.c.compiler.nucleus.input.25852946" superClass="cdt.managedbuild.tool.gnu.mentor.c.compiler.nucleus.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.mentor.c.linker.nucleus.636842819" name="CodeSourcery GNU C Linker" superClass="cdt.managedbuild.tool.gnu.mentor.c.linker.nucleus">
<option id="mentor.gnu.c.link.option.libs.554706755" name="Libraries (-l)" superClass="mentor.gnu.c.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" value="wolfssl"/>
</option>
<option id="mentor.gnu.c.link.option.paths.2121461092" name="Library search path (-L)" superClass="mentor.gnu.c.link.option.paths" valueType="libPaths">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/wolfcrypt/Release}&quot;"/>
</option>
</tool>
<tool id="cdt.managedbuild.tool.gnu.mentor.cpp.linker.nucleus.1551851046" name="CodeSourcery GNU C++ Linker" superClass="cdt.managedbuild.tool.gnu.mentor.cpp.linker.nucleus"/>
<tool id="cdt.managedbuild.tool.gnu.mentor.assembler.nucleus.2138744001" name="CodeSourcery GNU Assembler" superClass="cdt.managedbuild.tool.gnu.mentor.assembler.nucleus">
<option id="gnu.both.asm.option.debugging.level.1046354273" name="Debug Level" superClass="gnu.both.asm.option.debugging.level" value="gnu.both.asm.debugging.level.none" valueType="enumerated"/>
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.2099604782" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<tool id="com.mentor.embedded.toolchains.core.nucleus.exportgen.process.255113742" name="Nucleus Exports Generator" superClass="com.mentor.embedded.toolchains.core.nucleus.exportgen.process"/>
<tool id="com.mentor.embedded.toolchains.core.nucleus.exportgen.application.942752326" name="Nucleus Exports Generator" superClass="com.mentor.embedded.toolchains.core.nucleus.exportgen.application"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="src/misc.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings">
<externalSettings containerId="system-project;" factoryId="org.eclipse.cdt.core.cfg.export.settings.sipplier"/>
</storageModule>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="CSBENCH.cdt.managedbuild.target.gnu.mentor.nucleus.exe.1080439571" name="Executable" projectType="cdt.managedbuild.target.gnu.mentor.nucleus.exe"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mentor.nucleus.exe.release.593147631;cdt.managedbuild.config.gnu.mentor.nucleus.exe.release.593147631.;cdt.managedbuild.tool.gnu.mentor.c.compiler.nucleus.28888809;cdt.managedbuild.tool.gnu.mentor.c.compiler.nucleus.input.25852946">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.mentor.embedded.toolchains.core.nucleus.GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mentor.nucleus.exe.debug.1214077048;cdt.managedbuild.config.gnu.mentor.nucleus.exe.debug.1214077048.;cdt.managedbuild.tool.gnu.mentor.c.compiler.nucleus.733911603;cdt.managedbuild.tool.gnu.mentor.c.compiler.nucleus.input.1877603173">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.mentor.embedded.toolchains.core.nucleus.GCCManagedMakePerProjectProfileC"/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="com.mentor.embedded">
<project systemProject="system-project" version="2017.02.1"/>
</storageModule>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/sftp"/>
</configuration>
<configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/sftp"/>
</configuration>
</storageModule>
</cproject>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>sftp</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>echoserver</name>
<type>2</type>
<locationURI>PARENT-2-PROJECT_LOC../examples/echoserver</locationURI>
</link>
<link>
<name>src</name>
<type>2</type>
<locationURI>PARENT-2-PROJECT_LOC../src</locationURI>
</link>
</linkedResources>
</projectDescription>

13
ide/CSBENCH/README 100644
View File

@ -0,0 +1,13 @@
This is to build with Sourcery CodeBench IDE
It makes the assumption that the root wolfssl and wolfssh directory are in the same folder
workspace ->
->wolfssl
->wolfssh
To build first compile the wolfssl library using the project provided in wolfssl/IDE/CSBENCH
Next compile the sftp example project provided in wolfssh/ide/CSBENCH
Note that this is using port 8080 to listen on by default

View File

@ -0,0 +1,7 @@
# vim:ft=automake
# included from Top Level Makefile.am
# All paths should be given relative to the root
EXTRA_DIST+= ide/CSBENCH/.cproject
EXTRA_DIST+= ide/CSBENCH/.project
EXTRA_DIST+= ide/CSBENCH/README

View File

@ -3,3 +3,4 @@
# All paths should be given relative to the root
include ide/winvs/include.am
include ide/CSBENCH/include.am

View File

@ -236,6 +236,9 @@ const char* GetErrorString(int err)
case WS_SFTP_COMPLETE:
return "sftp connection established";
case WS_NEXT_ERROR:
return "Getting next value/state results in error";
default:
return "Unknown error code";
}
@ -4502,7 +4505,7 @@ int DoReceive(WOLFSSH* ssh)
return ret;
}
}
FALL_THROUGH;
FALL_THROUGH /* no break */
case PROCESS_PACKET_LENGTH:
if (ssh->inputBuffer.idx + UINT32_SZ > ssh->inputBuffer.bufferSz)
@ -4515,7 +4518,7 @@ int DoReceive(WOLFSSH* ssh)
return WS_OVERFLOW_E;
ssh->processReplyState = PROCESS_PACKET_FINISH;
FALL_THROUGH;
FALL_THROUGH /* no break */
case PROCESS_PACKET_FINISH:
readSz = ssh->curSz + LENGTH_SZ + peerMacSz;
@ -4581,7 +4584,7 @@ int DoReceive(WOLFSSH* ssh)
}
}
ssh->processReplyState = PROCESS_PACKET;
FALL_THROUGH;
FALL_THROUGH /* no break */
case PROCESS_PACKET:
if ( (ret = DoPacket(ssh)) < 0) {
@ -4604,6 +4607,7 @@ int DoReceive(WOLFSSH* ssh)
return WS_SUCCESS;
}
return ret;
}

View File

@ -128,6 +128,10 @@ void* wolfSSH_GetIOWriteCtx(WOLFSSH* ssh)
#include "tcpip/tcpip.h"
#include "sys/errno.h"
#include <errno.h>
#elif defined(WOLFSSL_NUCLEUS)
#include "nucleus.h"
#include "networking/nu_networking.h"
#include <errno.h>
#else
#include <sys/types.h>
#include <errno.h>
@ -208,6 +212,14 @@ void* wolfSSH_GetIOWriteCtx(WOLFSSH* ssh)
#define SOCKET_ECONNREFUSED SCK_ERROR
#define SOCKET_ECONNABORTED SCK_ERROR
#endif
#elif defined(WOLFSSL_NUCLEUS)
#define SOCKET_EWOULDBLOCK NU_WOULD_BLOCK
#define SOCKET_EAGAIN NU_WOULD_BLOCK
#define SOCKET_ECONNRESET NU_NOT_CONNECTED
#define SOCKET_EINTR NU_NOT_CONNECTED
#define SOCKET_EPIPE NU_NOT_CONNECTED
#define SOCKET_ECONNREFUSED NU_CONNECTION_REFUSED
#define SOCKET_ECONNABORTED NU_NOT_CONNECTED
#else
#define SOCKET_EWOULDBLOCK EWOULDBLOCK
#define SOCKET_EAGAIN EAGAIN
@ -233,6 +245,9 @@ void* wolfSSH_GetIOWriteCtx(WOLFSSH* ssh)
TCPIP_TCP_ArrayPut((socket),(uint8_t*)(buf),(sz))
#define RECV_FUNCTION(socket,buf,sz,flags) \
TCPIP_TCP_ArrayGet((socket),(uint8_t*)(buf),(sz))
#elif defined(WOLFSSL_NUCLEUS)
#define SEND_FUNCTION NU_Send
#define RECV_FUNCTION NU_Recv
#else
#define SEND_FUNCTION send
#define RECV_FUNCTION recv

View File

@ -29,7 +29,13 @@
#include <config.h>
#endif
#ifdef WOLFSSL_USER_SETTINGS
#include <wolfssl/wolfcrypt/settings.h>
#else
#include <wolfssl/options.h>
#endif
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/rsa.h>
#include <wolfssh/error.h>

View File

@ -40,6 +40,28 @@ int wfopen(WFILE** f, const char* filename, const char* mode)
{
#ifdef USE_WINDOWS_API
return fopen_s(f, filename, mode) != 0;
#elif defined(WOLFSSL_NUCLEUS)
int m = WOLFSSH_O_CREAT;
if (WSTRSTR(mode, "r")) {
m |= WOLFSSH_O_RDONLY;
}
if (WSTRSTR(mode, "w")) {
if (m &= WOLFSSH_O_RDONLY) {
m ^= WOLFSSH_O_RDONLY;
m |= WOLFSSH_O_RDWR;
}
else {
m |= WOLFSSH_O_WRONLY;
}
}
if (filename != NULL && f != NULL) {
**f = NU_Open(filename, m, 0);
return 1;
}
else {
return 0;
}
#else
if (f != NULL) {
*f = fopen(filename, mode);

View File

@ -270,7 +270,7 @@ int wolfSSH_accept(WOLFSSH* ssh)
}
ssh->acceptState = ACCEPT_SERVER_VERSION_SENT;
WLOG(WS_LOG_DEBUG, acceptState, "SERVER_VERSION_SENT");
FALL_THROUGH;
FALL_THROUGH /* no break */
case ACCEPT_SERVER_VERSION_SENT:
while (ssh->clientState < CLIENT_VERSION_DONE) {
@ -282,7 +282,7 @@ int wolfSSH_accept(WOLFSSH* ssh)
}
ssh->acceptState = ACCEPT_CLIENT_VERSION_DONE;
WLOG(WS_LOG_DEBUG, acceptState, "CLIENT_VERSION_DONE");
FALL_THROUGH;
FALL_THROUGH /* no break */
case ACCEPT_CLIENT_VERSION_DONE:
if ( (ssh->error = SendKexInit(ssh)) < WS_SUCCESS) {
@ -292,7 +292,7 @@ int wolfSSH_accept(WOLFSSH* ssh)
}
ssh->acceptState = ACCEPT_SERVER_KEXINIT_SENT;
WLOG(WS_LOG_DEBUG, acceptState, "SERVER_KEXINIT_SENT");
FALL_THROUGH;
FALL_THROUGH /* no break */
case ACCEPT_SERVER_KEXINIT_SENT:
while (ssh->isKeying) {
@ -304,7 +304,7 @@ int wolfSSH_accept(WOLFSSH* ssh)
}
ssh->acceptState = ACCEPT_KEYED;
WLOG(WS_LOG_DEBUG, acceptState, "KEYED");
FALL_THROUGH;
FALL_THROUGH /* no break */
case ACCEPT_KEYED:
while (ssh->clientState < CLIENT_USERAUTH_REQUEST_DONE) {
@ -316,7 +316,7 @@ int wolfSSH_accept(WOLFSSH* ssh)
}
ssh->acceptState = ACCEPT_CLIENT_USERAUTH_REQUEST_DONE;
WLOG(WS_LOG_DEBUG, acceptState, "CLIENT_USERAUTH_REQUEST_DONE");
FALL_THROUGH;
FALL_THROUGH /* no break */
case ACCEPT_CLIENT_USERAUTH_REQUEST_DONE:
if ( (ssh->error = SendServiceAccept(ssh,
@ -328,7 +328,7 @@ int wolfSSH_accept(WOLFSSH* ssh)
ssh->acceptState = ACCEPT_SERVER_USERAUTH_ACCEPT_SENT;
WLOG(WS_LOG_DEBUG, acceptState,
"ACCEPT_SERVER_USERAUTH_ACCEPT_SENT");
FALL_THROUGH;
FALL_THROUGH /* no break */
case ACCEPT_SERVER_USERAUTH_ACCEPT_SENT:
while (ssh->clientState < CLIENT_USERAUTH_DONE) {
@ -340,7 +340,7 @@ int wolfSSH_accept(WOLFSSH* ssh)
}
ssh->acceptState = ACCEPT_CLIENT_USERAUTH_DONE;
WLOG(WS_LOG_DEBUG, acceptState, "CLIENT_USERAUTH_DONE");
FALL_THROUGH;
FALL_THROUGH /* no break */
case ACCEPT_CLIENT_USERAUTH_DONE:
if ( (ssh->error = SendUserAuthSuccess(ssh)) < WS_SUCCESS) {
@ -350,7 +350,7 @@ int wolfSSH_accept(WOLFSSH* ssh)
}
ssh->acceptState = ACCEPT_SERVER_USERAUTH_SENT;
WLOG(WS_LOG_DEBUG, acceptState, "SERVER_USERAUTH_SENT");
FALL_THROUGH;
FALL_THROUGH /* no break */
case ACCEPT_SERVER_USERAUTH_SENT:
while (ssh->clientState < CLIENT_CHANNEL_OPEN_DONE) {
@ -362,7 +362,7 @@ int wolfSSH_accept(WOLFSSH* ssh)
}
ssh->acceptState = ACCEPT_CLIENT_CHANNEL_REQUEST_DONE;
WLOG(WS_LOG_DEBUG, acceptState, "CLIENT_CHANNEL_REQUEST_DONE");
FALL_THROUGH;
FALL_THROUGH /* no break */
case ACCEPT_CLIENT_CHANNEL_REQUEST_DONE:
if ( (ssh->error = SendChannelOpenConf(ssh)) < WS_SUCCESS) {
@ -372,7 +372,7 @@ int wolfSSH_accept(WOLFSSH* ssh)
}
ssh->acceptState = ACCEPT_SERVER_CHANNEL_ACCEPT_SENT;
WLOG(WS_LOG_DEBUG, acceptState, "SERVER_CHANNEL_ACCEPT_SENT");
FALL_THROUGH;
FALL_THROUGH /* no break */
case ACCEPT_SERVER_CHANNEL_ACCEPT_SENT:
while (ssh->clientState < CLIENT_DONE) {
@ -440,7 +440,7 @@ int wolfSSH_connect(WOLFSSH* ssh)
}
ssh->connectState = CONNECT_CLIENT_VERSION_SENT;
WLOG(WS_LOG_DEBUG, connectState, "CLIENT_VERSION_SENT");
FALL_THROUGH;
FALL_THROUGH /* no break */
case CONNECT_CLIENT_VERSION_SENT:
while (ssh->serverState < SERVER_VERSION_DONE) {
@ -452,7 +452,7 @@ int wolfSSH_connect(WOLFSSH* ssh)
}
ssh->connectState = CONNECT_SERVER_VERSION_DONE;
WLOG(WS_LOG_DEBUG, connectState, "SERVER_VERSION_DONE");
FALL_THROUGH;
FALL_THROUGH /* no break */
case CONNECT_SERVER_VERSION_DONE:
if ( (ssh->error = SendKexInit(ssh)) < WS_SUCCESS) {
@ -462,7 +462,7 @@ int wolfSSH_connect(WOLFSSH* ssh)
}
ssh->connectState = CONNECT_CLIENT_KEXINIT_SENT;
WLOG(WS_LOG_DEBUG, connectState, "CLIENT_KEXINIT_SENT");
FALL_THROUGH;
FALL_THROUGH /* no break */
case CONNECT_CLIENT_KEXINIT_SENT:
while (ssh->serverState < SERVER_KEXINIT_DONE) {
@ -474,7 +474,7 @@ int wolfSSH_connect(WOLFSSH* ssh)
}
ssh->connectState = CONNECT_SERVER_KEXINIT_DONE;
WLOG(WS_LOG_DEBUG, connectState, "SERVER_KEXINIT_DONE");
FALL_THROUGH;
FALL_THROUGH /* no break */
case CONNECT_SERVER_KEXINIT_DONE:
if (ssh->handshake->kexId == ID_DH_GEX_SHA256)
@ -488,7 +488,7 @@ int wolfSSH_connect(WOLFSSH* ssh)
}
ssh->connectState = CONNECT_CLIENT_KEXDH_INIT_SENT;
WLOG(WS_LOG_DEBUG, connectState, "CLIENT_KEXDH_INIT_SENT");
FALL_THROUGH;
FALL_THROUGH /* no break */
case CONNECT_CLIENT_KEXDH_INIT_SENT:
while (ssh->isKeying) {
@ -500,7 +500,7 @@ int wolfSSH_connect(WOLFSSH* ssh)
}
ssh->connectState = CONNECT_KEYED;
WLOG(WS_LOG_DEBUG, connectState, "KEYED");
FALL_THROUGH;
FALL_THROUGH /* no break */
case CONNECT_KEYED:
if ( (ssh->error = SendServiceRequest(ssh, ID_SERVICE_USERAUTH)) <
@ -510,7 +510,7 @@ int wolfSSH_connect(WOLFSSH* ssh)
}
ssh->connectState = CONNECT_CLIENT_USERAUTH_REQUEST_SENT;
WLOG(WS_LOG_DEBUG, connectState, "CLIENT_USERAUTH_REQUEST_SENT");
FALL_THROUGH;
FALL_THROUGH /* no break */
case CONNECT_CLIENT_USERAUTH_REQUEST_SENT:
while (ssh->serverState < SERVER_USERAUTH_REQUEST_DONE) {
@ -522,7 +522,7 @@ int wolfSSH_connect(WOLFSSH* ssh)
}
ssh->connectState = CONNECT_SERVER_USERAUTH_REQUEST_DONE;
WLOG(WS_LOG_DEBUG, connectState, "SERVER_USERAUTH_REQUEST_DONE");
FALL_THROUGH;
FALL_THROUGH /* no break */
case CONNECT_SERVER_USERAUTH_REQUEST_DONE:
if ( (ssh->error = SendUserAuthRequest(ssh, ID_NONE)) <
@ -533,7 +533,7 @@ int wolfSSH_connect(WOLFSSH* ssh)
}
ssh->connectState = CONNECT_CLIENT_USERAUTH_SENT;
WLOG(WS_LOG_DEBUG, connectState, "CLIENT_USERAUTH_SENT");
FALL_THROUGH;
FALL_THROUGH /* no break */
case CONNECT_CLIENT_USERAUTH_SENT:
while (ssh->serverState < SERVER_USERAUTH_ACCEPT_DONE) {
@ -545,7 +545,7 @@ int wolfSSH_connect(WOLFSSH* ssh)
}
ssh->connectState = CONNECT_SERVER_USERAUTH_ACCEPT_DONE;
WLOG(WS_LOG_DEBUG, connectState, "SERVER_USERAUTH_ACCEPT_DONE");
FALL_THROUGH;
FALL_THROUGH /* no break */
case CONNECT_SERVER_USERAUTH_ACCEPT_DONE:
if ( (ssh->error = SendChannelOpenSession(ssh, DEFAULT_WINDOW_SZ,
@ -557,7 +557,7 @@ int wolfSSH_connect(WOLFSSH* ssh)
ssh->connectState = CONNECT_CLIENT_CHANNEL_OPEN_SESSION_SENT;
WLOG(WS_LOG_DEBUG, connectState,
"CLIENT_CHANNEL_OPEN_SESSION_SENT");
FALL_THROUGH;
FALL_THROUGH /* no break */
case CONNECT_CLIENT_CHANNEL_OPEN_SESSION_SENT:
while (ssh->serverState < SERVER_CHANNEL_OPEN_DONE) {
@ -570,7 +570,7 @@ int wolfSSH_connect(WOLFSSH* ssh)
ssh->connectState = CONNECT_SERVER_CHANNEL_OPEN_SESSION_DONE;
WLOG(WS_LOG_DEBUG, connectState,
"SERVER_CHANNEL_OPEN_SESSION_DONE");
FALL_THROUGH;
FALL_THROUGH /* no break */
case CONNECT_SERVER_CHANNEL_OPEN_SESSION_DONE:
if ( (ssh->error = SendChannelRequest(ssh, ssh->channelName,
@ -582,7 +582,7 @@ int wolfSSH_connect(WOLFSSH* ssh)
ssh->connectState = CONNECT_CLIENT_CHANNEL_REQUEST_SENT;
WLOG(WS_LOG_DEBUG, connectState,
"CLIENT_CHANNEL_REQUEST_SENT");
FALL_THROUGH;
FALL_THROUGH /* no break */
case CONNECT_CLIENT_CHANNEL_REQUEST_SENT:
while (ssh->serverState < SERVER_DONE) {

View File

@ -1155,7 +1155,7 @@ int ReceiveScpMessage(WOLFSSH* ssh)
switch (buf[0]) {
case 'C':
FALL_THROUGH;
FALL_THROUGH /* no break */
case 'D':
if (buf[0] == 'C') {
@ -1255,7 +1255,7 @@ int SendScpConfirmation(WOLFSSH* ssh)
case WS_SCP_CONTINUE:
/* default to ok confirmation */
FALL_THROUGH;
FALL_THROUGH /* no break */
default:
msg[0] = SCP_CONFIRM_OK;
@ -1307,9 +1307,9 @@ int ReceiveScpConfirmation(WOLFSSH* ssh)
case SCP_CONFIRM_OK:
break;
case SCP_CONFIRM_ERR:
FALL_THROUGH;
FALL_THROUGH /* no break */
case SCP_CONFIRM_FATAL:
FALL_THROUGH;
FALL_THROUGH /* no break */
default:
WLOG(WS_LOG_ERROR,
"scp error: peer sent error confirmation (code: %d)",

View File

@ -41,6 +41,7 @@ static int SFTP_ParseAtributes_buffer(WOLFSSH* ssh, WS_SFTP_FILEATRB* atr,
byte* buf, word32 bufSz);
static int SFTP_GetAttributes(const char* fileName, WS_SFTP_FILEATRB* atr,
byte link);
static int SFTP_GetAttributes_Handle(byte* handle, int handleSz, WS_SFTP_FILEATRB* atr);
static WS_SFTPNAME* wolfSSH_SFTPNAME_new(void* heap);
/* Gets packet header information
@ -199,7 +200,7 @@ int wolfSSH_SFTP_accept(WOLFSSH* ssh)
return WS_FATAL_ERROR;
}
ssh->connectState = SFTP_RECV;
FALL_THROUGH
FALL_THROUGH /* no break */
case SFTP_RECV:
if ((ssh->error = SFTP_ServerSendInit(ssh)) != WS_SUCCESS) {
@ -305,7 +306,6 @@ static int SFTP_SetAtributes(WOLFSSH* ssh, byte* buf, word32 bufSz,
}
/* cleans up absolute path */
static void clean_path(char* path)
{
@ -313,31 +313,31 @@ static void clean_path(char* path)
long sz = (long)WSTRLEN(path);
byte found;
/* remove any double '/' chars */
#ifdef WOLFSSL_NUCLEUS
for (i = 0; i < sz; i++) {
if (path[i] == '/' && path[i+1] == '/') {
if (path[i] == '/') path[i] = '\\';
}
#endif
/* remove any ./ patterns */
for (i = 1; i < sz - 1; i++) {
if (path[i] == '.' && path[i - 1] != '.' && path[i + 1] == WS_DELIM) {
WMEMMOVE(path + i, path + i + 1, sz - i - 1);
path[sz - 1] = '\0';
i--;
}
}
sz = (int)WSTRLEN(path);
/* remove any double '/' or '\' chars */
for (i = 0; i < sz; i++) {
if ((path[i] == WS_DELIM && path[i+1] == WS_DELIM)) {
WMEMMOVE(path + i, path + i + 1, sz - i + 1);
sz -= 1;
i--;
}
}
/* remove any trailing '.' and '/' chars */
sz = WSTRLEN(path);
do {
i = (int)sz - 1;
if (i > 0 && path[i] == '.' && path[i-1] == '.') {
break;
}
if (path[i] == '.' || path[i] == '/') {
path[i] = '\0';
}
sz = WSTRLEN(path);
} while ((int)sz - 1 > 0 &&
(path[(int)sz - 1] == '.' || path[(int)sz - 1] == '/'));
if (path != NULL) {
/* go through path until no cases are found */
do {
@ -346,8 +346,8 @@ static void clean_path(char* path)
int enIdx = 0; /* end of cut */
found = 0;
for (i = 0; i < sz; i++) {
if (path[i] == '/') {
for (i = 1; i < sz; i++) {
if (path[i] == WS_DELIM) {
int z;
/* if next two chars are .. then delete */
@ -356,7 +356,7 @@ static void clean_path(char* path)
/* start at one char before / and retrace path */
for (z = i - 1; z > 0; z--) {
if (path[z] == '/') {
if (path[z] == WS_DELIM || path[z] == ':') {
prIdx = z;
break;
}
@ -382,6 +382,35 @@ static void clean_path(char* path)
}
}
} while (found);
#ifdef WOLFSSL_NUCLEUS
sz = WSTRLEN(path);
if (path[sz - 1] == ':') {
path[sz] = WS_DELIM;
path[sz + 1] = '\0';
}
/* clean up any multiple drive listed i.e. A:/A: */
{
int i,j;
sz = WSTRLEN(path);
for (i = 0, j = 0; i < sz; i++) {
if (path[i] == ':') {
if (j == 0) j = i;
else {
/* @TODO only checking once */
WMEMMOVE(path, path + i - WS_DRIVE_SIZE, sz - i + WS_DRIVE_SIZE);
path[sz - i + WS_DRIVE_SIZE] = '\0';
break;
}
}
}
}
#endif
/* remove trailing delimiter */
if (sz > 3 && path[sz - 1] == WS_DELIM) {
path[sz - 1] = '\0';
}
}
}
@ -394,6 +423,7 @@ static int wolfSSH_SFTP_RecvRealPath(WOLFSSH* ssh, int reqId, int maxSz)
char r[WOLFSSH_MAX_FILENAME];
word32 rSz;
word32 idx = 0;
word32 i;
byte* out;
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_REALPATH");
@ -414,7 +444,7 @@ static int wolfSSH_SFTP_RecvRealPath(WOLFSSH* ssh, int reqId, int maxSz)
}
ato32((byte*)dir, &rSz);
if (rSz > WOLFSSH_MAX_FILENAME) {
if (rSz > WOLFSSH_MAX_FILENAME || (int)(rSz + UINT32_SZ) > maxSz) {
WFREE(dir, ssh->ctx->heap, DYNTYPE_BUFFER);
return WS_BUFFER_E;
}
@ -423,7 +453,7 @@ static int wolfSSH_SFTP_RecvRealPath(WOLFSSH* ssh, int reqId, int maxSz)
WFREE(dir, ssh->ctx->heap, DYNTYPE_BUFFER);
/* get working directory in the case of receiving non absolute path */
if (r[0] != '/') {
if (r[0] != '/' && r[1] != ':') {
char wd[WOLFSSH_MAX_FILENAME];
if (WGETCWD(wd, WOLFSSH_MAX_FILENAME) == NULL) {
@ -436,8 +466,14 @@ static int wolfSSH_SFTP_RecvRealPath(WOLFSSH* ssh, int reqId, int maxSz)
WSTRNCAT(wd, r, WOLFSSH_MAX_FILENAME - 1);
WMEMCPY(r, wd, WOLFSSH_MAX_FILENAME);
}
clean_path(r);
rSz = (int)WSTRLEN(r);
/* for real path always send '/' chars */
for (i = 0; i < rSz; i++) {
if (r[i] == WS_DELIM) r[i] = '/';
}
WLOG(WS_LOG_SFTP, "Real Path Directory = %s", r);
/* send response */
@ -514,6 +550,9 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
case WOLFSSH_FTP_LSTAT:
return wolfSSH_SFTP_RecvLSTAT(ssh, reqId, maxSz);
case WOLFSSH_FTP_FSTAT:
return wolfSSH_SFTP_RecvFSTAT(ssh, reqId, maxSz);
case WOLFSSH_FTP_OPEN:
return wolfSSH_SFTP_RecvOpen(ssh, reqId, maxSz);
@ -544,7 +583,7 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
/* read rest of data off the wire and send error status to client */
{
byte* data;
WLOG(WS_LOG_SFTP, "Unknown packet type received");
WLOG(WS_LOG_SFTP, "Unknown packet type [%d] received", type);
data = (byte*)WMALLOC(maxSz, ssh->ctx->heap, DYNTYPE_BUFFER);
if (data != NULL) {
wolfSSH_stream_read(ssh, data, maxSz);
@ -605,6 +644,11 @@ int wolfSSH_SFTP_SendStatus(WOLFSSH* ssh, word32 status, word32 reqId,
c32toa(status, buf + idx); idx += UINT32_SZ;
sz = (reason != NULL)? (int)WSTRLEN(reason): 0;
if (sz + idx + UINT32_SZ > maxSz) {
WFREE(buf, ssh->heap, DYNTYPE_BUFFER);
return WS_BUFFER_E;
}
c32toa(sz, buf + idx); idx += UINT32_SZ;
if (reason != NULL) {
WMEMCPY(buf + idx, reason, sz); idx += sz;
@ -612,6 +656,11 @@ int wolfSSH_SFTP_SendStatus(WOLFSSH* ssh, word32 status, word32 reqId,
sz = (lang != NULL)? (int)WSTRLEN(lang): 0;
if (sz + idx + UINT32_SZ > maxSz) {
WFREE(buf, ssh->heap, DYNTYPE_BUFFER);
return WS_BUFFER_E;
}
c32toa(sz, buf + idx); idx += UINT32_SZ;
if (lang != NULL) {
WMEMCPY(buf + idx, lang, sz);
@ -666,6 +715,7 @@ int wolfSSH_SFTP_RecvRMDIR(WOLFSSH* ssh, int reqId, word32 maxSz)
WMEMCPY(dir, data + idx, sz);
dir[sz] = '\0';
clean_path(dir);
ret = WRMDIR(dir);
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
WFREE(dir, ssh->ctx->heap, DYNTYPE_BUFFER);
@ -696,7 +746,7 @@ int wolfSSH_SFTP_RecvMKDIR(WOLFSSH* ssh, int reqId, word32 maxSz)
int ret;
byte* data;
char* dir;
word32 mode;
word32 mode = 0;
word32 idx = 0;
if (ssh == NULL) {
@ -730,11 +780,12 @@ int wolfSSH_SFTP_RecvMKDIR(WOLFSSH* ssh, int reqId, word32 maxSz)
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz != UINT32_SZ) {
WLOG(WS_LOG_SFTP, "Attribute size larger than 4 not yet supported");
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
WFREE(dir, ssh->ctx->heap, DYNTYPE_BUFFER);
return WS_FATAL_ERROR;
WLOG(WS_LOG_SFTP, "Skipping over attribute");
}
else {
ato32(data + idx, &mode);
}
clean_path(dir);
ret = WMKDIR(dir, mode);
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
WFREE(dir, ssh->ctx->heap, DYNTYPE_BUFFER);
@ -811,28 +862,28 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, word32 maxSz)
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
if ((reason & WOLFSSH_FXF_READ) && (reason & WOLFSSH_FXF_WRITE)) {
m |= O_RDWR;
m |= WOLFSSH_O_RDWR;
}
else {
if (reason & WOLFSSH_FXF_READ) {
m |= O_RDONLY;
m |= WOLFSSH_O_RDONLY;
}
if (reason & WOLFSSH_FXF_WRITE) {
m |= O_WRONLY;
m |= WOLFSSH_O_WRONLY;
}
}
if (reason & WOLFSSH_FXF_APPEND) {
m |= O_APPEND;
m |= WOLFSSH_O_APPEND;
}
if (reason & WOLFSSH_FXF_CREAT) {
m |= O_CREAT;
m |= WOLFSSH_O_CREAT;
}
if (reason & WOLFSSH_FXF_TRUNC) {
m |= O_TRUNC;
m |= WOLFSSH_O_TRUNC;
}
if (reason & WOLFSSH_FXF_EXCL) {
m |= O_EXCL;
m |= WOLFSSH_O_EXCL;
}
/* if file permissions not set then use default */
@ -840,6 +891,7 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, word32 maxSz)
atr.per = 0644;
}
clean_path(dir);
fd = WOPEN(dir, m, atr.per);
if (fd < 0) {
WLOG(WS_LOG_SFTP, "Error opening file %s", dir);
@ -849,6 +901,15 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, word32 maxSz)
return WS_BAD_FILE_E;
}
#ifdef WOLFSSH_STOREHANDLE
if (SFTP_AddHandleNode(ssh, (byte*)&fd, sizeof(WFD), dir) != WS_SUCCESS) {
WLOG(WS_LOG_SFTP, "Unable to store handle");
WFREE(dir, ssh->ctx->heap, DYNTYPE_BUFFER);
wolfSSH_SFTP_SendStatus(ssh, WOLFSSH_FTP_FAILURE, reqId,
"Internal Failure", "English");
return WS_FATAL_ERROR;
}
#endif
WFREE(dir, ssh->ctx->heap, DYNTYPE_BUFFER);
SendPacketType(ssh, WOLFSSH_FTP_HANDLE, (byte*)&fd, sizeof(WFD));
@ -862,6 +923,7 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, word32 maxSz)
/* hold pointers to directory handles */
typedef struct DIR_HANDLE {
WDIR dir;
byte isEof; /* flag for if read everything */
word64 id; /* handle ID */
struct DIR_HANDLE* next;
} DIR_HANDLE;
@ -917,10 +979,14 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, word32 maxSz)
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
/* get directory handle */
ctx = WOPENDIR(dir);
if (ctx == NULL) {
clean_path(dir);
if (WOPENDIR(&ctx, dir) != 0) {
WLOG(WS_LOG_SFTP, "Error with opening directory");
WFREE(dir, ssh->ctx->heap, DYNTYPE_BUFFER);
return WS_FATAL_ERROR;
wolfSSH_SFTP_SendStatus(ssh, WOLFSSH_FTP_NOFILE, reqId,
"Unable To Open Directory", "English");
return WS_BAD_FILE_E;
}
WFREE(dir, ssh->ctx->heap, DYNTYPE_BUFFER);
@ -933,8 +999,13 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, word32 maxSz)
if (dirList == NULL) {
return WS_MEMORY_E;
}
#ifdef WOLFSSL_NUCLEUS
WMEMCPY(&dirList->dir, &ctx, sizeof(WDIR));
#else
dirList->dir = ctx;
#endif
dirList->id = idCount++;
dirList->isEof = 0;
dirList->next = NULL;
SendPacketType(ssh, WOLFSSH_FTP_HANDLE, (byte*)&dirList->id,
sizeof(word64));
@ -945,8 +1016,13 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, word32 maxSz)
if (cur == NULL) {
return WS_MEMORY_E;
}
#ifdef WOLFSSL_NUCLEUS
WMEMCPY(&cur->dir, &ctx, sizeof(WDIR));
#else
cur->dir = ctx;
#endif
cur->id = idCount++;
cur->isEof = 0;
cur->next = dirList;
dirList = cur;
SendPacketType(ssh, WOLFSSH_FTP_HANDLE, (byte*)&cur->id,
@ -957,12 +1033,54 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, word32 maxSz)
}
#ifdef WOLFSSL_NUCLEUS
/* For Nucleus port
* helper function that gets file information from reading directory
* @TODO allow user to override
*
* returns WS_SUCCESS on success
*/
static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out)
{
int sz;
if (dir == NULL || ssh == NULL || out == NULL) {
return WS_BAD_ARGUMENT;
}
sz = (int)WSTRLEN(dir->sfname);
out->fName = (char*)WMALLOC(sz + 1, out->heap, DYNTYPE_SFTP);
if (out->fName == NULL) {
return WS_MEMORY_E;
}
WMEMCPY(out->fName, dir->sfname, sz);
out->fName[sz] = '\0';
out->fSz = sz;
sz = (int)WSTRLEN(dir->lfname);
out->lName = (char*)WMALLOC(sz + 1, out->heap, DYNTYPE_SFTP);
if (out ->lName == NULL) {
return WS_MEMORY_E;
}
WMEMCPY(out->lName, dir->lfname, sz);
out->lName[sz] = '\0';
out->lSz = sz;
SFTP_GetAttributes(out->fName, &out->atrb, 0);
if ((WREADDIR(dir)) == NULL) {
return WS_NEXT_ERROR;
}
return WS_SUCCESS;
}
#else
/* helper function that gets file information from reading directory
* @TODO allow user to override
*
* returns WS_SUCCESS on success
*/
static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR dir, WS_SFTPNAME* out)
static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out)
{
struct dirent* dp;
int sz;
@ -971,7 +1089,7 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR dir, WS_SFTPNAME* out)
return WS_BAD_ARGUMENT;
}
dp = WREADDIR(dir);
dp = WREADDIR(*dir);
if (dp == NULL) {
return WS_FATAL_ERROR;
}
@ -983,6 +1101,7 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR dir, WS_SFTPNAME* out)
}
out->lName = (char*)WMALLOC(sz + 1, out->heap, DYNTYPE_SFTP);
if (out ->lName == NULL) {
WFREE(out->fName, out->heap, DYNTYPE_SFTP);
return WS_MEMORY_E;
}
@ -1000,6 +1119,7 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR dir, WS_SFTPNAME* out)
return WS_SUCCESS;
}
#endif
/* helper function to create a name packet. out buffer will have the following
@ -1033,6 +1153,11 @@ static int wolfSSH_SFTP_SendName(WOLFSSH* ssh, WS_SFTPNAME* list, word32 count,
c32toa(count, out + idx); idx += UINT32_SZ;
for (i = 0; i < count && cur != NULL; i++) {
if (*outSz - idx < cur->fSz + cur->lSz + UINT32_SZ * 2) {
/* not enough space for the buffer */
return WS_FATAL_ERROR;
}
c32toa(cur->fSz, out + idx); idx += UINT32_SZ;
WMEMCPY(out + idx, cur->fName, cur->fSz); idx += cur->fSz;
c32toa(cur->lSz, out + idx); idx += UINT32_SZ;
@ -1067,6 +1192,7 @@ int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, word32 maxSz)
WS_SFTPNAME* name = NULL;
WS_SFTPNAME* list = NULL;
word32 outSz = 0;
DIR_HANDLE* cur = dirList;
if (ssh == NULL) {
return WS_BAD_ARGUMENT;
@ -1089,8 +1215,6 @@ int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, word32 maxSz)
WMEMCPY((byte*)&handle, data + idx, sz);
/* find DIR given handle */
{
DIR_HANDLE* cur = dirList;
while (cur != NULL) {
if (cur->id == handle) {
dir = cur->dir;
@ -1102,7 +1226,6 @@ int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, word32 maxSz)
/* unable to find handle */
return WS_FATAL_ERROR;
}
}
/* this closes the directory before returning */
//wc_ReadDirFirst(&ctx, dir, NULL);
@ -1111,8 +1234,8 @@ int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, word32 maxSz)
outSz += UINT32_SZ + WOLFSSH_SFTP_HEADER; /* hold header+number of files */
do {
name = wolfSSH_SFTPNAME_new(ssh->ctx->heap);
ret = wolfSSH_SFTPNAME_readdir(ssh, dir, name);
if (ret == WS_SUCCESS) {
ret = wolfSSH_SFTPNAME_readdir(ssh, &dir, name);
if (ret == WS_SUCCESS || ret == WS_NEXT_ERROR) {
count++;
outSz += name->fSz + name->lSz + (UINT32_SZ * 2);
outSz += SFTP_AtributesSz(ssh, &name->atrb);
@ -1130,12 +1253,18 @@ int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, word32 maxSz)
} while (ret == WS_SUCCESS);
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
if (list == NULL) {
if (list == NULL || cur->isEof) {
wolfSSH_SFTP_SendStatus(ssh, WOLFSSH_FTP_EOF, reqId,
"No More Files In Directory", "English");
return WS_SUCCESS;
}
/* if next state would cause an error then set EOF flag for when called
* again */
if (ret == WS_NEXT_ERROR) {
cur->isEof = 1;
}
data = (byte*)WMALLOC(outSz, ssh->ctx->heap, DYNTYPE_BUFFER);
if (data == NULL) {
return WS_MEMORY_E;
@ -1161,7 +1290,11 @@ int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, word32 maxSz)
int wolfSSH_SFTP_RecvCloseDir(WOLFSSH* ssh, byte* handle, word32 handleSz)
{
DIR_HANDLE* cur = dirList;
#ifdef WOLFSSL_NUCLEUS
WDIR* dir = NULL;
#else
WDIR dir = NULL;
#endif
if (ssh == NULL || handle == NULL || handleSz != sizeof(word64)) {
return WS_BAD_ARGUMENT;
@ -1172,7 +1305,11 @@ int wolfSSH_SFTP_RecvCloseDir(WOLFSSH* ssh, byte* handle, word32 handleSz)
/* find DIR given handle */
while (cur != NULL) {
if (cur->id == *((word64*)handle)) {
#ifdef WOLFSSL_NUCLEUS
dir = &cur->dir;
#else
dir = cur->dir;
#endif
break;
}
cur = cur->next;
@ -1188,7 +1325,8 @@ int wolfSSH_SFTP_RecvCloseDir(WOLFSSH* ssh, byte* handle, word32 handleSz)
if (cur != NULL) {
DIR_HANDLE* pre = dirList;
WLOG(WS_LOG_SFTP, "Free'ing and closing handle %ld pointer of [%p]", cur->id, cur);
WLOG(WS_LOG_SFTP, "Free'ing and closing handle %ld pointer of [%p]",
(long)cur->id, cur);
/* case where node is at head of list */
if (pre == cur) {
dirList = cur->next;
@ -1235,7 +1373,6 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, word32 maxSz)
return WS_MEMORY_E;
}
/* @TODO check for infinite loop */
sz = 0;
do {
ret = wolfSSH_stream_read(ssh, data + sz, maxSz - sz);
@ -1243,6 +1380,10 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, word32 maxSz)
sz += ret;
}
} while (sz < maxSz && ret > 0);
if (ret < 0) {
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
return ret;
}
/* get file handle */
ato32(data + idx, &sz); idx += UINT32_SZ;
@ -1268,6 +1409,11 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, word32 maxSz)
ret = (int)WPWRITE(fd, data + idx, sz, ofst);
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
if (ret < 0) {
#if defined(WOLFSSL_NUCLEUS) && defined(DEBUG_WOLFSSH)
if (ret == NUF_NOSPC) {
WLOG(WS_LOG_SFTP, "Ran out of memory");
}
#endif
WLOG(WS_LOG_SFTP, "Error writing to file");
wolfSSH_SFTP_SendStatus(ssh, WOLFSSH_FTP_FAILURE, reqId,
"Write File Error", "English");
@ -1303,7 +1449,10 @@ int wolfSSH_SFTP_RecvRead(WOLFSSH* ssh, int reqId, word32 maxSz)
if (data == NULL) {
return WS_MEMORY_E;
}
wolfSSH_stream_read(ssh, data, maxSz);
if ((ret = wolfSSH_stream_read(ssh, data, maxSz)) < 0) {
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
return ret;
}
/* get file handle */
ato32(data + idx, &sz); idx += UINT32_SZ;
@ -1378,7 +1527,10 @@ int wolfSSH_SFTP_RecvClose(WOLFSSH* ssh, int reqId, word32 maxSz)
if (data == NULL) {
return WS_MEMORY_E;
}
wolfSSH_stream_read(ssh, data, maxSz);
if ((ret = wolfSSH_stream_read(ssh, data, maxSz)) < 0) {
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
return ret;
}
/* get file handle */
ato32(data + idx, &sz); idx += UINT32_SZ;
@ -1398,6 +1550,12 @@ int wolfSSH_SFTP_RecvClose(WOLFSSH* ssh, int reqId, word32 maxSz)
WMEMSET((byte*)&fd, 0, sizeof(WFD));
WMEMCPY((byte*)&fd, data + idx, sz);
ret = WCLOSE(fd);
#ifdef WOLFSSH_STOREHANDLE
if (SFTP_RemoveHandleNode(ssh, data + idx, sz) != WS_SUCCESS) {
WLOG(WS_LOG_SFTP, "Unable to remove handle from list");
ret = WS_FATAL_ERROR;
}
#endif
}
else {
ret = WS_FATAL_ERROR;
@ -1446,9 +1604,6 @@ int wolfSSH_SFTP_RecvRemove(WOLFSSH* ssh, int reqId, word32 maxSz)
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
return ret;
}
else {
ret = WS_SUCCESS;
}
/* get file name */
ato32(data + idx, &sz); idx += UINT32_SZ;
@ -1465,9 +1620,23 @@ int wolfSSH_SFTP_RecvRemove(WOLFSSH* ssh, int reqId, word32 maxSz)
name[sz] = '\0';
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
if (WREMOVE(name) < 0) {
clean_path(name);
if ((ret = WREMOVE(name)) < 0) {
WLOG(WS_LOG_SFTP, "Error removing file");
ret = WS_FATAL_ERROR;
#if defined(WOLFSSL_NUCLEUS) && defined(DEBUG_WOLFSSH)
if (ret == NUF_ACCES)
WLOG(WS_LOG_SFTP, "access error");
if (ret == NUF_BAD_USER)
WLOG(WS_LOG_SFTP, "bad user");
if (ret == NUF_IO_ERROR)
WLOG(WS_LOG_SFTP, "io error");
if (ret == NUF_NOFILE)
WLOG(WS_LOG_SFTP, "%s file not found", name);
#endif
ret = WS_BAD_FILE_E;
}
else {
ret = WS_SUCCESS;
}
/* Let the client know the results from trying to remove the file */
@ -1547,6 +1716,8 @@ int wolfSSH_SFTP_RecvRename(WOLFSSH* ssh, int reqId, word32 maxSz)
}
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
clean_path(old);
clean_path(nw);
if (ret == WS_SUCCESS && WRENAME(old, nw) < 0) {
WLOG(WS_LOG_SFTP, "Error renaming file");
ret = WS_BAD_FILE_E;
@ -1568,6 +1739,233 @@ int wolfSSH_SFTP_RecvRename(WOLFSSH* ssh, int reqId, word32 maxSz)
}
#ifdef WOLFSSH_STOREHANDLE
/* some systems do not have a fstat function to allow for attribute lookup given
* a file descriptor. In those cases we keep track of an internal list matching
* handles to file names */
typedef struct WS_HANDLE_LIST {
byte handle[WOLFSSH_MAX_HANDLE];
word32 handleSz;
char name[WOLFSSH_MAX_FILENAME];
struct WS_HANDLE_LIST* next;
struct WS_HANDLE_LIST* prev;
} WS_HANDLE_LIST;
static WS_HANDLE_LIST* handleList = NULL;
/* get a handle node from the list
* returns WS_HANDLE_LIST pointer on success and NULL on failure */
static WS_HANDLE_LIST* SFTP_GetHandleNode(byte* handle, word32 handleSz)
{
WS_HANDLE_LIST* cur = handleList;
if (handle == NULL) {
return NULL;
}
/* for Nucleus need to find name from handle */
while (cur != NULL) {
if(handleSz == cur->handleSz && WMEMCMP(handle, cur->handle, handleSz) == 0) {
break; /* found handle */
}
cur = cur->next;
}
return cur;
}
/* add a name and handle to the handle list
* return WS_SUCCESS on success */
int SFTP_AddHandleNode(WOLFSSH* ssh, byte* handle, word32 handleSz, char* name)
{
WS_HANDLE_LIST* cur;
int sz;
if (handle == NULL || name == NULL) {
return WS_BAD_ARGUMENT;
}
cur = (WS_HANDLE_LIST*)WMALLOC(sizeof(WS_HANDLE_LIST), ssh->ctx->heap,
DYNTYPE_SFTP);
if (cur == NULL) {
return WS_MEMORY_E;
}
WMEMCPY(cur->handle, handle, handleSz);
cur->handleSz = handleSz;
sz = (int)WSTRLEN(name);
if (sz + 1 >= WOLFSSH_MAX_FILENAME) {
WFREE(cur, ssh->ctx->heap, DYNTYPE_SFTP);
return WS_BUFFER_E;
}
WMEMCPY(cur->name, name, sz);
cur->name[sz] = '\0';
cur->prev = NULL;
cur->next = handleList;
if (handleList != NULL) {
handleList->prev = cur;
}
handleList = cur;
return WS_SUCCESS;
}
/* remove a handle node from the list
* returns WS_SUCCESS on success */
int SFTP_RemoveHandleNode(WOLFSSH* ssh, byte* handle, word32 handleSz)
{
WS_HANDLE_LIST* cur;
if (ssh == NULL || handle == NULL) {
return WS_BAD_ARGUMENT;
}
cur = SFTP_GetHandleNode(handle, handleSz);
if (cur == NULL) {
WLOG(WS_LOG_SFTP, "Fatal Error! Trying to remove a handle that was not in the list");
return WS_FATAL_ERROR;
}
if (cur->next != NULL) {
cur->next->prev = cur->prev;
}
if (cur->prev != NULL) {
cur->prev->next = cur->next;
}
if (cur->next == NULL && cur->prev == NULL) {
handleList = NULL;
}
WFREE(cur, ssh->ctx->heap, DYNTYPE_SFTP);
return WS_SUCCESS;
}
#endif /* WOLFSSH_STOREHANDLE */
#ifdef WOLFSSL_NUCLEUS
/* @TODO can be overriden by user for portability
* NOTE: if atr->flags is set to a value of 0 then no attributes are set.
* Fills out a WS_SFTP_FILEATRB structure
* returns WS_SUCCESS on success
*/
int SFTP_GetAttributes(const char* fileName, WS_SFTP_FILEATRB* atr, byte link)
{
DSTAT stats;
int sz = (int)WSTRLEN(fileName);
int ret;
if (link) {
ret = WLSTAT(fileName, &stats);
}
else {
ret = WSTAT(fileName, &stats);
}
WMEMSET(atr, 0, sizeof(WS_SFTP_FILEATRB));
if (sz > 2 && fileName[sz - 2] == ':' && ret == NUF_NOFILE) {
atr->flags |= WOLFSSH_FILEATRB_PERM;
atr->per |= 0x4000;
return WS_SUCCESS;
}
if (ret != NU_SUCCESS) {
return WS_BAD_FILE_E;
}
atr->flags |= WOLFSSH_FILEATRB_SIZE;
atr->sz = (word64)stats.fsize;
/* get additional attributes */
{
byte atrib = 0;
if (NU_Get_Attributes(&atrib, fileName) == NU_SUCCESS) {
atr->flags |= WOLFSSH_FILEATRB_PERM;
if (atrib & ADIRENT) {
atr->per |= 0x4000;
}
else {
atr->per |= 0x8000;
}
if (atrib & ANORMAL) {
atr->per |= 0x755;
}
if (atrib & ARDONLY) {
atr->per |= 0x444;
}
}
}
/* @TODO handle attribute extensions */
NU_Done(&stats);
return WS_SUCCESS;
}
/* @TODO can be overriden by user for portability
* Gets attributes based on file descriptor
* NOTE: if atr->flags is set to a value of 0 then no attributes are set.
* Fills out a WS_SFTP_FILEATRB structure
* returns WS_SUCCESS on success
*/
int SFTP_GetAttributes_Handle(byte* handle, int handleSz, WS_SFTP_FILEATRB* atr)
{
DSTAT stats;
WS_HANDLE_LIST* cur;
if (handle == NULL || atr == NULL) {
return WS_FATAL_ERROR;
}
cur = SFTP_GetHandleNode(handle, handleSz);
if (cur == NULL) {
WLOG(WS_LOG_SFTP, "Unknown handle");
return WS_BAD_FILE_E;
}
if (WSTAT(cur->name, &stats) != NU_SUCCESS) {
return WS_FATAL_ERROR;
}
WMEMSET(atr, 0, sizeof(WS_SFTP_FILEATRB));
atr->flags |= WOLFSSH_FILEATRB_SIZE;
atr->sz = (word64)stats.fsize;
{
byte atrib = 0;
if (NU_Get_Attributes(&atrib, cur->name) == NU_SUCCESS) {
atr->flags |= WOLFSSH_FILEATRB_PERM;
if (atrib & ADIRENT) {
atr->per |= 0x4000;
}
else {
atr->per |= 0x8000;
}
if (atrib & ANORMAL) {
atr->per |= 0x755;
}
if (atrib & ARDONLY) {
atr->per |= 0x444;
}
}
}
/* @TODO handle attribute extensions */
NU_Done(&stats);
return WS_SUCCESS;
}
#else
/* @TODO can be overriden by user for portability
* NOTE: if atr->flags is set to a value of 0 then no attributes are set.
* Fills out a WS_SFTP_FILEATRB structure
@ -1613,6 +2011,114 @@ int SFTP_GetAttributes(const char* fileName, WS_SFTP_FILEATRB* atr, byte link)
}
/* @TODO can be overriden by user for portability
* Gets attributes based on file descriptor
* NOTE: if atr->flags is set to a value of 0 then no attributes are set.
* Fills out a WS_SFTP_FILEATRB structure
* returns WS_SUCCESS on success
*/
int SFTP_GetAttributes_Handle(byte* handle, int handleSz, WS_SFTP_FILEATRB* atr)
{
struct stat stats;
if (handleSz != sizeof(word32)) {
WLOG(WS_LOG_SFTP, "Unexpected handle size SFTP_GetAttributes_Handle()");
}
if (fstat(*(int*)handle, &stats) != 0) {
return WS_BAD_FILE_E;
}
WMEMSET(atr, 0, sizeof(WS_SFTP_FILEATRB));
atr->flags |= WOLFSSH_FILEATRB_SIZE;
atr->sz = (word64)stats.st_size;
atr->flags |= WOLFSSH_FILEATRB_UIDGID;
atr->uid = (word32)stats.st_uid;
atr->gid = (word32)stats.st_gid;
atr->flags |= WOLFSSH_FILEATRB_PERM;
atr->per = (word32)stats.st_mode;
#if 0
/* @TODO porting time from stat structure */
atr->flags |= WOLFSSH_FILEATRB_TIME;
atr->atime = (word32)stats.st_atimespec.tv_sec;
atr->mtime = (word32)stats.st_mtimespec.tv_sec;
#endif
/* @TODO handle attribute extensions */
return WS_SUCCESS;
}
#endif
/* Handles receiving fstat packet
* returns WS_SUCCESS on success
*/
int wolfSSH_SFTP_RecvFSTAT(WOLFSSH* ssh, int reqId, word32 maxSz)
{
WS_SFTP_FILEATRB atr;
word32 handleSz;
word32 sz;
byte* data;
byte* handle;
word32 idx = 0;
if (ssh == NULL) {
return WS_BAD_ARGUMENT;
}
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_FSTAT");
data = (byte*)WMALLOC(maxSz, ssh->ctx->heap, DYNTYPE_BUFFER);
if (data == NULL) {
return WS_MEMORY_E;
}
wolfSSH_stream_read(ssh, data, maxSz);
ato32(data + idx, &handleSz); idx += UINT32_SZ;
if (handleSz + idx > maxSz) {
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
return WS_BUFFER_E;
}
handle = data + idx;
/* try to get file attributes and send back to client */
WMEMSET((byte*)&atr, 0, sizeof(WS_SFTP_FILEATRB));
if (SFTP_GetAttributes_Handle(handle, handleSz, &atr) != WS_SUCCESS) {
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
WLOG(WS_LOG_SFTP, "Unable to get fstat of file/directory");
wolfSSH_SFTP_SendStatus(ssh, WOLFSSH_FTP_FAILURE, reqId,
"STAT error", "English");
return WS_BAD_FILE_E;
}
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
sz = SFTP_AtributesSz(ssh, &atr);
data = (byte*)WMALLOC(sz + WOLFSSH_SFTP_HEADER, ssh->ctx->heap,
DYNTYPE_BUFFER);
if (data == NULL) {
return WS_MEMORY_E;
}
if (SFTP_SetHeader(ssh, reqId, WOLFSSH_FTP_ATTRS, sz, data) != WS_SUCCESS) {
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
return WS_FATAL_ERROR;
}
SFTP_SetAtributes(ssh, data + WOLFSSH_SFTP_HEADER, sz, &atr);
if (wolfSSH_stream_send(ssh, data, sz + WOLFSSH_SFTP_HEADER) < 0) {
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
return WS_FATAL_ERROR;
}
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
return WS_SUCCESS;
}
/* Handles receiving stat packet
* returns WS_SUCCESS on success
*/
@ -1654,6 +2160,7 @@ int wolfSSH_SFTP_RecvSTAT(WOLFSSH* ssh, int reqId, word32 maxSz)
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
/* try to get file attributes and send back to client */
clean_path(name);
WMEMSET((byte*)&atr, 0, sizeof(WS_SFTP_FILEATRB));
if (SFTP_GetAttributes(name, &atr, 0) != WS_SUCCESS) {
WFREE(name, ssh->ctx->heap, DYNTYPE_BUFFER);
@ -1729,6 +2236,7 @@ int wolfSSH_SFTP_RecvLSTAT(WOLFSSH* ssh, int reqId, word32 maxSz)
WMEMCPY(name, data + idx, sz);
name[sz] = '\0';
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
clean_path(name);
/* try to get file attributes and send back to client */
WMEMSET((byte*)&atr, 0, sizeof(WS_SFTP_FILEATRB));
@ -1868,7 +2376,7 @@ int wolfSSH_SFTP_connect(WOLFSSH* ssh)
return WS_FATAL_ERROR;
}
ssh->connectState = SFTP_RECV;
FALL_THROUGH
FALL_THROUGH /* no break */
case SFTP_RECV:
if ((ssh->error = SFTP_ClientRecvInit(ssh)) != WS_SUCCESS) {
@ -3263,7 +3771,11 @@ int wolfSSH_SFTP_SaveOfst(WOLFSSH* ssh, char* frm, char* to, word64 ofst)
return WS_MEMORY_E;
}
/* @TODO sanity check before copy */
if (frmSz > WOLFSSH_MAX_FILENAME || toSz > WOLFSSH_MAX_FILENAME) {
WLOG(WS_LOG_SFTP, "File name is too large");
return WS_BUFFER_E;
}
current = &ssh->sftpOfst[idx];
WMEMCPY(current->from, frm, frmSz);
current->from[frmSz] = '\0';

View File

@ -93,8 +93,9 @@ enum WS_ErrorCodes {
WS_MATCH_MAC_ALGO_E = -53, /* cannot match MAC algo with peer */
WS_PERMISSIONS = -54,
WS_SFTP_COMPLETE = -55, /* SFTP connection established */
WS_NEXT_ERROR = -56, /* Getting next value/state results in error */
WS_LAST_E = -55 /* Update this to indicate last error */
WS_LAST_E = -56 /* Update this to indicate last error */
};

View File

@ -53,6 +53,15 @@ extern "C" {
#endif
#ifndef NO_FILESYSTEM
#ifdef WOLFSSL_NUCLEUS
#define WFILE int
WOLFSSH_API int wfopen(WFILE**, const char*, const char*);
#define WFOPEN(f,fn,m) wfopen((f),(fn),(m))
#define WFCLOSE(f) NU_Close(*(f))
#define WFWRITE(b,x,s,f) NU_Write(*(f),(const CHAR*)(b),(s))
#define WFREAD(b,x,s,f) NU_Read(*(f),(CHAR*)(b),(s))
#else
#define WFILE FILE
WOLFSSH_API int wfopen(WFILE**, const char*, const char*);
@ -76,7 +85,7 @@ extern "C" {
#define WMKDIR(p,m) mkdir((p),(m))
#endif
#endif
#endif
/* setup string handling */
#ifndef WSTRING_USER
#include <string.h>
@ -130,8 +139,153 @@ extern "C" {
#define WLOCALTIME(c,r) (localtime_r((c),(r))!=NULL)
#endif
#ifdef WOLFSSH_SFTP
#ifndef NO_WOLFSSH_SERVER
#if defined(WOLFSSH_SFTP) && !defined(NO_WOLFSSH_SERVER)
#ifdef WOLFSSL_NUCLEUS
#include "storage/nu_storage.h"
#define WRMDIR(d) (NU_Remove_Dir((d)) == NU_SUCCESS)?0:1
#define WMKDIR(d,m) (NU_Make_Dir((d)) == NU_SUCCESS)?0:1
#define WSTAT(p,b) NU_Get_First((b),(p))
#define WLSTAT(p,b) NU_Get_First((b),(p))
#define WREMOVE(d) NU_Delete((d))
#define WRENAME(o,n) NU_Rename((o),(n))
#define WS_DELIM '\\'
#ifndef WGETCWD
static inline char* wGetCwd(char* buf, unsigned int bufSz)
{
int ret;
MNT_LIST_S* list = NU_NULL;
if (buf == NULL || bufSz < 3) {
return NULL;
}
ret = NU_List_Mount(&list);
if (ret != NU_SUCCESS) {
return NULL;
}
buf[0] = list->mnt_name[0];
buf[1] = ':';
buf[2] = '\0';
return buf;
}
#define WGETCWD(r,rSz) wGetCwd((r),(rSz))
#endif
#define WOLFSSH_O_RDWR PO_RDWR
#define WOLFSSH_O_RDONLY PO_RDONLY
#define WOLFSSH_O_WRONLY PO_WRONLY
#define WOLFSSH_O_APPEND PO_APPEND
#define WOLFSSH_O_CREAT PO_CREAT
#define WOLFSSH_O_TRUNC PO_TRUNC
#define WOLFSSH_O_EXCL PO_EXCL
#define WFD int
#ifndef WOPEN
static inline int wOpen(char* f, short flag, short mode)
{
/* @TODO could use PS_IWRITE only or PS_IREAD only? */
return NU_Open(f, PO_TEXT | flag, (PS_IWRITE | PS_IREAD));
}
#define WOPEN(f,m,p) wOpen((f),(m),(p))
#endif
#define WCLOSE(fd) NU_Close((fd))
#ifndef WPWRITE
static inline int wPwrite(WFD fd, unsigned char* buf, unsigned int sz, long ofst)
{
if (ofst > 0) {
NU_Seek(fd, ofst, 0);
}
return NU_Write(fd, (const CHAR*)buf, sz);
}
#define WPWRITE(fd,b,s,o) wPwrite((fd),(b),(s),(o))
#endif
#ifndef WPREAD
static inline int wPread(WFD fd, unsigned char* buf, unsigned int sz, long ofst)
{
if (ofst > 0) {
NU_Seek(fd, ofst, 0);
}
return NU_Read(fd, (CHAR*)buf, sz);
}
#define WPREAD(fd,b,s,o) wPread((fd),(b),(s),(o))
#endif
#ifndef NO_WOLFSSL_DIR
#define WDIR DSTAT
#ifndef WOPENDIR
static inline int wOpenDir(WDIR* d, char* dir)
{
int ret;
int idx = WSTRLEN(dir);
char tmp[256]; /* default max file name size */
if (idx < 3) {
return -1;
}
memcpy(tmp, dir, idx);
if (tmp[idx - 1] == '.') {
tmp[idx - 1] = '*';
}
else {
/* if opening a directory then make sure pattern '/' '*' is used */
unsigned char atrib = 0;
if (NU_Get_Attributes(&atrib, dir) == NU_SUCCESS) {
if (atrib & ADIRENT) {
if (tmp[idx-1] != WS_DELIM) {
if (idx + 2 > sizeof(tmp)) {
/* not enough space */
return -1;
}
tmp[idx++] = WS_DELIM;
tmp[idx++] = '*';
}
}
}
}
if (tmp[idx - 1] == WS_DELIM) {
if (idx + 1 > sizeof(tmp)) {
/* not enough space */
return -1;
}
tmp[idx++] = '*';
}
tmp[idx] = '\0';
ret = NU_Get_First(d, tmp);
/* if back to root directory i.e. A:/ then handle case
* where file system has nothing in it. */
if (dir[idx - 3] == ':' && ret == NUF_NOFILE) {
memset(d, 0, sizeof(WDIR));
ret = NU_SUCCESS;
}
if (ret == NU_SUCCESS) {
return 0;
}
return -1;
}
#define WOPENDIR(c,d) wOpenDir((c),(d))
#endif
#define WCLOSEDIR(d) NU_Done((d))
#define WREADDIR(d) (NU_Get_Next((d)) == NU_SUCCESS)?(d):NULL
#endif /* NO_WOLFSSL_DIR */
#else
#include <unistd.h> /* used for rmdir */
#include <sys/stat.h> /* used for mkdir, stat, and lstat */
#include <stdio.h> /* used for remove and rename */
@ -143,9 +297,18 @@ extern "C" {
#define WREMOVE(d) remove((d))
#define WRENAME(o,n) rename((o),(n))
#define WGETCWD(r,rSz) getcwd((r),(rSz))
#define WS_DELIM '/'
#include <fcntl.h> /* used for open, close, pwrite, and pread */
#define WFD int
#define WOLFSSH_O_RDWR O_RDWR
#define WOLFSSH_O_RDONLY O_RDONLY
#define WOLFSSH_O_WRONLY O_WRONLY
#define WOLFSSH_O_APPEND O_APPEND
#define WOLFSSH_O_CREAT O_CREAT
#define WOLFSSH_O_TRUNC O_TRUNC
#define WOLFSSH_O_EXCL O_EXCL
#define WOPEN(f,m,p) open((f),(m),(p))
#define WCLOSE(fd) close((fd))
#define WPWRITE(fd,b,s,o) pwrite((fd),(b),(s),(o))
@ -154,7 +317,9 @@ extern "C" {
#ifndef NO_WOLFSSL_DIR
#include <dirent.h> /* used for opendir, readdir, and closedir */
#define WDIR DIR*
#define WOPENDIR(d) opendir((d))
/* returns 0 on success */
#define WOPENDIR(c,d) ((*(c) = opendir((d))) == NULL)
#define WCLOSEDIR(d) closedir((d))
#define WREADDIR(d) readdir((d))
#endif /* NO_WOLFSSL_DIR */

View File

@ -49,6 +49,11 @@ extern "C" {
#define USE_WINDOWS_API
#endif
#ifdef WOLFSSL_NUCLEUS
#ifndef WOLFSSH_STOREHANDLE
#define WOLFSSH_STOREHANDLE
#endif
#endif
#ifdef __cplusplus
}

View File

@ -33,6 +33,22 @@
#endif
#define socklen_t int
#define NUM_SOCKETS 1
#elif defined(WOLFSSL_NUCLEUS)
#include "nucleus.h"
#include "networking/nu_networking.h"
#define SOCKET_T int
#define socklen_t int
#define NUM_SOCKETS 1
#define INADDR_ANY IP_ADDR_ANY
#define AF_INET NU_FAMILY_IP
#define SOCK_STREAM NU_TYPE_STREAM
#define sin_addr id
#define s_addr is_ip_addrs
#define sin_family family
#define sin_port port
#else /* USE_WINDOWS_API */
#include <unistd.h>
#include <netdb.h>
@ -88,6 +104,9 @@
#define WCLOSESOCKET(s) closesocket((s))
#endif
#define WSTARTTCP()
#elif defined(WOLFSSL_NUCLEUS)
#define WCLOSESOCKET(s) NU_Close_Socket((s))
#define WSTARTTCP()
#else
#define WCLOSESOCKET(s) close(s)
#define WSTARTTCP()
@ -105,6 +124,10 @@
#define WOLFSSH_THREAD
#define INFINITE -1
#define WAIT_OBJECT_0 0L
#elif defined(WOLFSSL_NUCLEUS)
typedef unsigned int THREAD_RETURN;
typedef intptr_t THREAD_TYPE;
#define WOLFSSH_THREAD
#else
typedef unsigned int THREAD_RETURN;
typedef intptr_t THREAD_TYPE;
@ -116,7 +139,9 @@
typedef struct sockaddr_in6 SOCKADDR_IN_T;
#define AF_INET_V AF_INET6
#else
#ifndef WOLFSSL_NUCLEUS
typedef struct sockaddr_in SOCKADDR_IN_T;
#endif
#define AF_INET_V AF_INET
#endif
@ -179,8 +204,12 @@ void WaitTcpReady(func_args*);
#else /* TEST_IPV6 */
static const char* const wolfSshIp = "::1";
#endif /* TEST_IPV6 */
static const word16 wolfSshPort = 22222;
#ifdef WOLFSSL_NUCLEUS
/* port 8080 was open with QEMU */
static const word16 wolfSshPort = 8080;
#else
static const word16 wolfSshPort = 22222;
#endif
#ifdef __GNUC__
#define WS_NORETURN __attribute__((noreturn))
@ -283,6 +312,43 @@ static INLINE int mygetopt(int argc, char** argv, const char* optstring)
* - 4996: deprecated function */
#endif
#ifdef WOLFSSL_NUCLEUS
static INLINE void build_addr(struct addr_struct* addr, const char* peer,
word16 port)
{
int useLookup = 0;
(void)useLookup;
memset(addr, 0, sizeof(struct addr_struct));
#ifndef TEST_IPV6
/* peer could be in human readable form */
if ( ((size_t)peer != INADDR_ANY) && isalpha((int)peer[0])) {
NU_HOSTENT* entry;
NU_HOSTENT h;
entry = &h;
NU_Get_Host_By_Name((char*)peer, entry);
if (entry) {
memcpy(&addr->id.is_ip_addrs, entry->h_addr_list[0],
entry->h_length);
useLookup = 1;
}
else
err_sys("no entry for host");
}
#endif
#ifndef TEST_IPV6
addr->family = NU_FAMILY_IP;
addr->port = port;
/* @TODO always setting any ip addr here */
PUT32(addr->id.is_ip_addrs, 0, IP_ADDR_ANY);
#endif
}
#else
static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
word16 port)
{
@ -299,13 +365,23 @@ static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
struct hostent* entry = gethostbyname(peer, &err);
#elif defined(MICROCHIP_MPLAB_HARMONY)
struct hostent* entry = gethostbyname((char*)peer);
#elif defined(WOLFSSL_NUCLEUS)
NU_HOSTENT* entry;
NU_HOSTENT h;
entry = &h;
NU_Get_Host_By_Name((char*)peer, entry);
#else
struct hostent* entry = gethostbyname(peer);
#endif
if (entry) {
#ifdef WOLFSSL_NUCLEUS
memcpy(&addr->id.is_ip_addrs, entry->h_addr_list[0],
entry->h_length);
#else
memcpy(&addr->sin_addr.s_addr, entry->h_addr_list[0],
entry->h_length);
#endif
useLookup = 1;
}
else
@ -321,7 +397,11 @@ static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
#endif
addr->sin_port = htons(port);
if ((size_t)peer == INADDR_ANY)
#ifdef WOLFSSL_NUCLEUS
PUT32(addr->id.is_ip_addrs, 0, INADDR_ANY);
#else
addr->sin_addr.s_addr = INADDR_ANY;
#endif
else {
if (!useLookup) {
#ifdef MICROCHIP_MPLAB_HARMONY
@ -367,6 +447,7 @@ static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
}
#endif
}
#endif /* WOLFSSL_NUCLEUS */
#ifdef USE_WINDOWS_API
#pragma warning(pop)
@ -380,6 +461,8 @@ static INLINE void tcp_socket(SOCKET_T* sockFd)
*sockFd = 0;
#elif defined(MICROCHIP_TCPIP)
*sockFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
#elif defined(WOLFSSL_NUCLEUS)
*sockFd = NU_Socket(NU_FAMILY_IP, NU_TYPE_STREAM, 0);
#else
*sockFd = socket(AF_INET_V, SOCK_STREAM, 0);
#endif
@ -405,6 +488,8 @@ static INLINE void tcp_socket(SOCKET_T* sockFd)
/* nothing to define */
#elif defined(MICROCHIP_MPLAB_HARMONY) && !defined(_FULL_SIGNAL_IMPLEMENTATION)
/* not full signal implementation */
#elif defined(WOLFSSL_NUCLEUS)
/* nothing to define */
#else /* no S_NOSIGPIPE */
signal(SIGPIPE, SIG_IGN);
#endif /* S_NOSIGPIPE */
@ -415,6 +500,7 @@ static INLINE void tcp_socket(SOCKET_T* sockFd)
if (!TCPIP_TCP_OptionsSet(*sockFd, TCP_OPTION_NODELAY, (void*)1)) {
err_sys("setsockopt TCP_NODELAY failed\n");
}
#elif defined(WOLFSSL_NUCLEUS)
#else
int on = 1;
socklen_t len = sizeof(on);
@ -439,15 +525,19 @@ static INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr)
*sockfd = TCPIP_TCP_ServerOpen(IP_ADDRESS_TYPE_IPV4, *port, 0);
return;
#else
#ifdef WOLFSSL_NUCLEUS
struct addr_struct addr;
#else
SOCKADDR_IN_T addr;
#endif
/* don't use INADDR_ANY by default, firewall may block, make user switch
on */
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_KEIL_TCP_NET)\
&& !defined(WOLFSSL_NUCLEUS)
{
int res;
#ifdef MICROCHIP_TCPIP
@ -462,11 +552,19 @@ static INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr)
}
#endif
#ifdef WOLFSSL_NUCLEUS
if (NU_Bind(*sockfd, &addr, sizeof(addr)) <= 0)
err_sys("tcp bind failed");
if (NU_Listen(*sockfd, NUM_SOCKETS) != NU_SUCCESS)
err_sys("tcp listen failed");
#else
if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
err_sys("tcp bind failed");
if (listen(*sockfd, NUM_SOCKETS) != 0)
err_sys("tcp listen failed");
#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS)
#endif
#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS) && !defined(WOLFSSL_NUCLEUS)
if (*port == 0) {
socklen_t len = sizeof(addr);
if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) {
@ -484,7 +582,7 @@ static INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr)
/* Wolf Root Directory Helper */
/* KEIL-RL File System does not support relative directory */
#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS) \
&& !defined(NO_WOLFSSL_DIR)
&& !defined(NO_WOLFSSL_DIR) && !defined(WOLFSSL_NUCLEUS)
/* Maximum depth to search for WolfSSL root */
#define MAX_WOLF_ROOT_DEPTH 5

View File

@ -107,6 +107,10 @@ enum {
WOLFSSH_FXF_EXCL = 0x00000020
};
#ifndef WS_DRIVE_SIZE
#define WS_DRIVE_SIZE 1
#endif
typedef struct WS_SFTP_FILEATRB_EX WS_SFTP_FILEATRB_EX;
struct WS_SFTP_FILEATRB_EX {
char* type;
@ -118,7 +122,7 @@ struct WS_SFTP_FILEATRB_EX {
typedef struct WS_SFTP_FILEATRB {
word32 flags;
long sz;
word64 sz;
word32 uid; /* user ID */
word32 gid; /* group ID */
word32 per; /* permissions */
@ -209,6 +213,7 @@ WOLFSSH_LOCAL int wolfSSH_SFTP_RecvRemove(WOLFSSH* ssh, int reqId, word32 maxSz)
WOLFSSH_LOCAL int wolfSSH_SFTP_RecvRename(WOLFSSH* ssh, int reqId, word32 maxSz);
WOLFSSH_LOCAL int wolfSSH_SFTP_RecvSTAT(WOLFSSH* ssh, int reqId, word32 maxSz);
WOLFSSH_LOCAL int wolfSSH_SFTP_RecvLSTAT(WOLFSSH* ssh, int reqId, word32 maxSz);
WOLFSSH_LOCAL int wolfSSH_SFTP_RecvFSTAT(WOLFSSH* ssh, int reqId, word32 maxSz);
#ifndef NO_WOLFSSL_DIR
WOLFSSH_LOCAL int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, word32 maxSz);
@ -216,3 +221,6 @@ WOLFSSH_LOCAL int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, word32 maxSz
WOLFSSH_LOCAL int wolfSSH_SFTP_RecvCloseDir(WOLFSSH* ssh, byte* handle,
word32 handleSz);
#endif /* NO_WOLFSSL_DIR */
WOLFSSL_LOCAL int SFTP_AddHandleNode(WOLFSSH* ssh, byte* handle, word32 handleSz, char* name);
WOLFSSL_LOCAL int SFTP_RemoveHandleNode(WOLFSSH* ssh, byte* handle, word32 handleSz);