mirror of https://github.com/wolfSSL/wolfssh.git
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 pathpull/73/head
parent
6261bb7d98
commit
6d434d0030
|
@ -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 */
|
||||
|
|
|
@ -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 "${CWD}/${ProjName}.out" "${CWD}/${ProjName}.bin"" 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=""${workspace_loc:/wolfcrypt/Debug}""/>
|
||||
</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 "${CWD}/${ProjName}.out" "${CWD}/${ProjName}.bin"" 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=""${workspace_loc:/wolfcrypt/Release}""/>
|
||||
</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>
|
|
@ -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>
|
|
@ -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
|
|
@ -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
|
|
@ -3,3 +3,4 @@
|
|||
# All paths should be given relative to the root
|
||||
|
||||
include ide/winvs/include.am
|
||||
include ide/CSBENCH/include.am
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
15
src/io.c
15
src/io.c
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
22
src/port.c
22
src/port.c
|
@ -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);
|
||||
|
|
46
src/ssh.c
46
src/ssh.c
|
@ -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) {
|
||||
|
|
|
@ -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)",
|
||||
|
|
630
src/wolfsftp.c
630
src/wolfsftp.c
|
@ -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';
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
||||
|
|
173
wolfssh/port.h
173
wolfssh/port.h
|
@ -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 */
|
||||
|
|
|
@ -49,6 +49,11 @@ extern "C" {
|
|||
#define USE_WINDOWS_API
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_NUCLEUS
|
||||
#ifndef WOLFSSH_STOREHANDLE
|
||||
#define WOLFSSH_STOREHANDLE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
108
wolfssh/test.h
108
wolfssh/test.h
|
@ -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 */
|
||||
#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);
|
||||
|
@ -438,16 +524,20 @@ static INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr)
|
|||
/* does bind and listen and returns the socket */
|
||||
*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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue