mirror of https://github.com/wolfSSL/wolfssh.git
1. Initialize the ret value in RecvSetSTAT().
2. Delete trailing commas in a couple enums. 3. Add extern "C" C++ guards around wolfsftp.h. 4. In port.c, comment out the pwrite and pread wrappers for Windows builds. 5. Remove the getcwd from RecvRealPath(), but needs a better fix. 6. Leave out several operations that need to be touched later. Emphasis is to get Get and Put running. 7. Open, Close, Read, Write, have a WINCE version using the Win32 API. 8. Remove the include of stdio.h from port.c for Windows builds. 9. Remove and Rename actions return an error for Windows builds.pull/134/head
parent
73839469ed
commit
a457abd11d
|
|
@ -1,4 +1,4 @@
|
|||
/* port.c
|
||||
/* port.c
|
||||
*
|
||||
* Copyright (C) 2014-2016 wolfSSL Inc.
|
||||
*
|
||||
|
|
@ -31,8 +31,11 @@
|
|||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <wolfssh/port.h>
|
||||
#ifndef USE_WINDOWS_API
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NO_FILESYSTEM
|
||||
|
|
@ -79,6 +82,7 @@ int wfopen(WFILE** f, const char* filename, const char* mode)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if defined(USE_WINDOWS_API) && (defined(WOLFSSH_SFTP) || \
|
||||
defined(WOLFSSH_SCP)) && !defined(NO_WOLFSSH_SERVER)
|
||||
int wPwrite(WFD fd, unsigned char* buf, unsigned int sz, long ofst)
|
||||
|
|
@ -123,6 +127,7 @@ int wPread(WFD fd, unsigned char* buf, unsigned int sz, long ofst)
|
|||
}
|
||||
|
||||
#endif /* USE_WINDOWS_API */
|
||||
#endif
|
||||
#endif /* !NO_FILESYSTEM */
|
||||
|
||||
#ifndef WSTRING_USER
|
||||
|
|
|
|||
539
src/wolfsftp.c
539
src/wolfsftp.c
|
|
@ -638,7 +638,6 @@ static int SFTP_SetAttributes(WOLFSSH* ssh, byte* buf, word32 bufSz,
|
|||
c32toa(atr->per, buf + idx); idx += UINT32_SZ;
|
||||
}
|
||||
|
||||
|
||||
/* check if time attribute present */
|
||||
if (atr->flags & WOLFSSH_FILEATRB_TIME) {
|
||||
c32toa(atr->atime, buf + idx); idx += UINT32_SZ;
|
||||
|
|
@ -857,6 +856,7 @@ static int wolfSSH_SFTP_RecvRealPath(WOLFSSH* ssh, int reqId, byte* data,
|
|||
r[rSz] = '\0';
|
||||
|
||||
/* get working directory in the case of receiving non absolute path */
|
||||
#ifndef USE_WINDOWS_API
|
||||
if (r[0] != '/' && r[1] != ':') {
|
||||
char wd[WOLFSSH_MAX_FILENAME];
|
||||
|
||||
|
|
@ -884,6 +884,7 @@ static int wolfSSH_SFTP_RecvRealPath(WOLFSSH* ssh, int reqId, byte* data,
|
|||
WSTRNCAT(wd, r, WOLFSSH_MAX_FILENAME);
|
||||
WMEMCPY(r, wd, WOLFSSH_MAX_FILENAME);
|
||||
}
|
||||
#endif /* USE_WINDOWS_API */
|
||||
|
||||
clean_path(r);
|
||||
rSz = (int)WSTRLEN(r);
|
||||
|
|
@ -997,7 +998,7 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
|||
ret = wolfSSH_SFTP_RecvRealPath(ssh, state->reqId,
|
||||
state->data, state->sz);
|
||||
break;
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
case WOLFSSH_FTP_RMDIR:
|
||||
ret = wolfSSH_SFTP_RecvRMDIR(ssh, state->reqId,
|
||||
state->data, state->sz);
|
||||
|
|
@ -1017,11 +1018,14 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
|||
ret = wolfSSH_SFTP_RecvLSTAT(ssh, state->reqId,
|
||||
state->data, state->sz);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef USE_WINDOWS_API
|
||||
case WOLFSSH_FTP_FSTAT:
|
||||
ret = wolfSSH_SFTP_RecvFSTAT(ssh, state->reqId,
|
||||
state->data, state->sz);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case WOLFSSH_FTP_OPEN:
|
||||
ret = wolfSSH_SFTP_RecvOpen(ssh, state->reqId,
|
||||
|
|
@ -1052,11 +1056,12 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
|||
ret = wolfSSH_SFTP_RecvRename(ssh, state->reqId,
|
||||
state->data, state->sz);
|
||||
break;
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
case WOLFSSH_FTP_SETSTAT:
|
||||
ret = wolfSSH_SFTP_RecvSetSTAT(ssh, state->reqId,
|
||||
state->data, state->sz);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef NO_WOLFSSH_DIR
|
||||
case WOLFSSH_FTP_OPENDIR:
|
||||
|
|
@ -1225,6 +1230,8 @@ int wolfSSH_SFTP_CreateStatus(WOLFSSH* ssh, word32 status, word32 reqId,
|
|||
}
|
||||
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
|
||||
/* Handles packet to remove a directory
|
||||
*
|
||||
* returns WS_SUCCESS on success
|
||||
|
|
@ -1385,12 +1392,15 @@ int wolfSSH_SFTP_RecvMKDIR(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#endif /* _WIN32_WCE */
|
||||
|
||||
|
||||
/* Handles packet to open a file
|
||||
*
|
||||
* returns WS_SUCCESS on success
|
||||
*/
|
||||
int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
||||
#ifndef USE_WINDOWS_API
|
||||
{
|
||||
WS_SFTP_FILEATRB atr;
|
||||
WFD fd;
|
||||
|
|
@ -1519,6 +1529,136 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
(void)ier;
|
||||
return ret;
|
||||
}
|
||||
#else /* USE_WINDOWS_API */
|
||||
{
|
||||
WS_SFTP_FILEATRB atr;
|
||||
HANDLE fileHandle;
|
||||
word32 sz;
|
||||
char* dir;
|
||||
word32 reason;
|
||||
word32 idx = 0;
|
||||
DWORD desiredAccess = 0;
|
||||
DWORD shareMode = 0;
|
||||
DWORD creationDisp = 0;
|
||||
DWORD flagsAndAttrs = 0;
|
||||
int ret = WS_SUCCESS;
|
||||
|
||||
word32 outSz = sizeof(HANDLE) + UINT32_SZ + WOLFSSH_SFTP_HEADER;
|
||||
byte* out = NULL;
|
||||
|
||||
char* res = NULL;
|
||||
char ier[] = "Internal Failure";
|
||||
char oer[] = "Open File Error";
|
||||
|
||||
if (ssh == NULL) {
|
||||
return WS_BAD_ARGUMENT;
|
||||
}
|
||||
|
||||
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_OPEN");
|
||||
|
||||
if (sizeof(HANDLE) > WOLFSSH_MAX_HANDLE) {
|
||||
WLOG(WS_LOG_SFTP, "Handle size is too large");
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
ato32(data + idx, &sz); idx += UINT32_SZ;
|
||||
if (sz + idx > maxSz) {
|
||||
return WS_BUFFER_E;
|
||||
}
|
||||
|
||||
/* plus one to make sure is null terminated */
|
||||
dir = (char*)WMALLOC(sz + 1, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
if (dir == NULL) {
|
||||
return WS_MEMORY_E;
|
||||
}
|
||||
WMEMCPY(dir, data + idx, sz);
|
||||
dir[sz] = '\0';
|
||||
idx += sz;
|
||||
|
||||
/* get reason for opening file */
|
||||
ato32(data + idx, &reason); idx += UINT32_SZ;
|
||||
|
||||
|
||||
#if 0
|
||||
/* @TODO handle attributes */
|
||||
SFTP_ParseAtributes_buffer(ssh, &atr, data, &idx, maxSz);
|
||||
#endif
|
||||
|
||||
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
|
||||
if (reason & WOLFSSH_FXF_READ)
|
||||
desiredAccess |= GENERIC_READ;
|
||||
if (reason & WOLFSSH_FXF_WRITE)
|
||||
desiredAccess |= GENERIC_WRITE;
|
||||
if (reason & WOLFSSH_FXF_APPEND)
|
||||
desiredAccess |= FILE_APPEND_DATA;
|
||||
|
||||
if (reason & WOLFSSH_FXF_CREAT)
|
||||
creationDisp |= CREATE_ALWAYS;
|
||||
if (reason & WOLFSSH_FXF_TRUNC)
|
||||
creationDisp |= TRUNCATE_EXISTING;
|
||||
if (reason & WOLFSSH_FXF_EXCL)
|
||||
creationDisp |= CREATE_NEW;
|
||||
|
||||
#if 0
|
||||
/* if file permissions not set then use default */
|
||||
if (!(atr.flags & WOLFSSH_FILEATRB_PERM)) {
|
||||
atr.per = 0644;
|
||||
}
|
||||
#endif
|
||||
atr.per = FILE_ATTRIBUTE_NORMAL;
|
||||
|
||||
clean_path(dir);
|
||||
fileHandle = CreateFileA(dir, desiredAccess, shareMode, NULL, creationDisp,
|
||||
atr.per, NULL);
|
||||
if (fileHandle == INVALID_HANDLE_VALUE) {
|
||||
WLOG(WS_LOG_SFTP, "Error opening file %s", dir);
|
||||
res = oer;
|
||||
if (wolfSSH_SFTP_CreateStatus(ssh, WOLFSSH_FTP_FAILURE, reqId, res,
|
||||
"English", NULL, &outSz) != WS_SIZE_ONLY) {
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
ret = WS_BAD_FILE_E;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSH_STOREHANDLE
|
||||
if (SFTP_AddHandleNode(ssh,
|
||||
(byte*)&fileHandle, sizeof(HANDLE), dir) != WS_SUCCESS) {
|
||||
WLOG(WS_LOG_SFTP, "Unable to store handle");
|
||||
res = ier;
|
||||
if (wolfSSH_SFTP_CreateStatus(ssh, WOLFSSH_FTP_FAILURE, reqId, res,
|
||||
"English", NULL, &outSz) != WS_SIZE_ONLY) {
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
ret = WS_FATAL_ERROR;
|
||||
}
|
||||
#endif
|
||||
WFREE(dir, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
|
||||
/* create packet */
|
||||
out = (byte*)WMALLOC(outSz, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
if (out == NULL) {
|
||||
return WS_MEMORY_E;
|
||||
}
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (SFTP_CreatePacket(ssh, WOLFSSH_FTP_HANDLE, out, outSz,
|
||||
(byte*)&fileHandle, sizeof(HANDLE)) != WS_SUCCESS) {
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (wolfSSH_SFTP_CreateStatus(ssh, WOLFSSH_FTP_FAILURE, reqId, res,
|
||||
"English", out, &outSz) != WS_SUCCESS) {
|
||||
WFREE(out, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
wolfSSH_SFTP_RecvSetSend(ssh, out, outSz);
|
||||
|
||||
(void)ier;
|
||||
return ret;
|
||||
}
|
||||
#endif /* USE_WINDOWS_API */
|
||||
|
||||
|
||||
#ifndef NO_WOLFSSH_DIR
|
||||
|
|
@ -1536,13 +1676,12 @@ static word64 idCount = 0;
|
|||
/* @TODO add locking for thread safety */
|
||||
|
||||
|
||||
#ifndef USE_WINDOWS_API
|
||||
|
||||
/* Handles packet to open a directory
|
||||
*
|
||||
* returns WS_SUCCESS on success
|
||||
*/
|
||||
int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
||||
#ifndef USE_WINDOWS_API
|
||||
{
|
||||
WDIR ctx;
|
||||
word32 sz;
|
||||
|
|
@ -1636,23 +1775,18 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else /* USE_WINDOWS_API */
|
||||
|
||||
/* Handles packet to open a directory
|
||||
*
|
||||
* returns WS_SUCCESS on success
|
||||
*/
|
||||
int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
||||
{
|
||||
word32 sz;
|
||||
char* dirName;
|
||||
word32 idx = 0;
|
||||
HANDLE findHandle;
|
||||
WIN32_FIND_DATAA findData;
|
||||
int ret = WS_SUCCESS;
|
||||
|
||||
byte* out = NULL;
|
||||
word32 outSz = 0;
|
||||
word32 outSz = sizeof(word64) + WOLFSSH_SFTP_HEADER + UINT32_SZ;
|
||||
byte* out = NULL;
|
||||
word64 id;
|
||||
|
||||
if (ssh == NULL) {
|
||||
return WS_BAD_ARGUMENT;
|
||||
|
|
@ -1660,6 +1794,11 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
|
||||
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_OPENDIR");
|
||||
|
||||
if (sizeof(HANDLE) > WOLFSSH_MAX_HANDLE) {
|
||||
WLOG(WS_LOG_SFTP, "Handle size is too large");
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* get directory name */
|
||||
ato32(data + idx, &sz);
|
||||
idx += UINT32_SZ;
|
||||
|
|
@ -1684,16 +1823,19 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
WLOG(WS_LOG_SFTP, "Error with opening directory");
|
||||
WFREE(dirName, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
|
||||
wolfSSH_SFTP_SendStatus(ssh, WOLFSSH_FTP_NOFILE, reqId,
|
||||
"Unable To Open Directory", "English");
|
||||
if (findHandle != INVALID_HANDLE_VALUE)
|
||||
FindClose(findHandle);
|
||||
return WS_BAD_FILE_E;
|
||||
if (wolfSSH_SFTP_CreateStatus(ssh, WOLFSSH_FTP_NOFILE, reqId,
|
||||
"Unable To Open Directory", "English", NULL, &outSz)
|
||||
!= WS_SIZE_ONLY) {
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
ret = WS_BAD_FILE_E;
|
||||
}
|
||||
FindClose(findHandle);
|
||||
|
||||
(void)reqId;
|
||||
|
||||
/* add to directory list @TODO locking for thread safety */
|
||||
{
|
||||
if (ret == WS_SUCCESS) {
|
||||
DIR_HANDLE* cur = (DIR_HANDLE*)WMALLOC(sizeof(DIR_HANDLE),
|
||||
ssh->ctx->heap, DYNTYPE_SFTP);
|
||||
if (cur == NULL) {
|
||||
|
|
@ -1707,20 +1849,31 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
cur->next = dirList;
|
||||
dirList = cur;
|
||||
|
||||
outSz = sizeof(word64) + UINT32_SZ + WOLFSSH_SFTP_HEADER;
|
||||
out = (byte*)WMALLOC(outSz, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
if (out == NULL) {
|
||||
return WS_MEMORY_E;
|
||||
}
|
||||
SFTP_CreatePacket(ssh, WOLFSSH_FTP_HANDLE, out, outSz, (byte*)&cur->id,
|
||||
sizeof(word64));
|
||||
wolfSSH_SFTP_RecvSetSend(ssh, out, outSz);
|
||||
}
|
||||
|
||||
return WS_SUCCESS;
|
||||
}
|
||||
out = (byte*)WMALLOC(outSz, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
if (out == NULL) {
|
||||
return WS_MEMORY_E;
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
SFTP_CreatePacket(ssh, WOLFSSH_FTP_HANDLE, out, outSz,
|
||||
(byte*)&id, sizeof(word64));
|
||||
}
|
||||
else {
|
||||
if (wolfSSH_SFTP_CreateStatus(ssh, WOLFSSH_FTP_NOFILE, reqId,
|
||||
"Unable To Open Directory", "English", out, &outSz)
|
||||
!= WS_SUCCESS) {
|
||||
WFREE(out, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
wolfSSH_SFTP_RecvSetSend(ssh, out, outSz);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* USE_WINDOWS_API */
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_NUCLEUS
|
||||
/* For Nucleus port
|
||||
|
|
@ -2223,6 +2376,7 @@ int wolfSSH_SFTP_RecvCloseDir(WOLFSSH* ssh, byte* handle, word32 handleSz)
|
|||
* returns WS_SUCCESS on success
|
||||
*/
|
||||
int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
||||
#ifndef USE_WINDOWS_API
|
||||
{
|
||||
WFD fd;
|
||||
word32 sz;
|
||||
|
|
@ -2299,6 +2453,86 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
wolfSSH_SFTP_RecvSetSend(ssh, out, outSz);
|
||||
return WS_SUCCESS;
|
||||
}
|
||||
#else /* USE_WINDOWS_API */
|
||||
{
|
||||
OVERLAPPED offset;
|
||||
HANDLE fd;
|
||||
DWORD bytesWritten;
|
||||
word32 sz;
|
||||
int ret = WS_SUCCESS;
|
||||
word32 idx = 0;
|
||||
|
||||
word32 outSz = 0;
|
||||
byte* out = NULL;
|
||||
|
||||
char suc[] = "Write File Success";
|
||||
char err[] = "Write File Error";
|
||||
char* res = suc;
|
||||
byte type = WOLFSSH_FTP_OK;
|
||||
|
||||
if (ssh == NULL) {
|
||||
return WS_BAD_ARGUMENT;
|
||||
}
|
||||
|
||||
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_WRITE");
|
||||
|
||||
/* get file handle */
|
||||
ato32(data + idx, &sz);
|
||||
idx += UINT32_SZ;
|
||||
if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE) {
|
||||
WLOG(WS_LOG_SFTP, "Error with file handle size");
|
||||
res = err;
|
||||
type = WOLFSSH_FTP_FAILURE;
|
||||
ret = WS_BAD_FILE_E;
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
WMEMSET((byte*)&fd, 0, sizeof(HANDLE));
|
||||
WMEMCPY((byte*)&fd, data + idx, sz);
|
||||
idx += sz;
|
||||
|
||||
/* get offset into file */
|
||||
WMEMSET(&offset, 0, sizeof(OVERLAPPED));
|
||||
ato32(data + idx, &sz);
|
||||
idx += UINT32_SZ;
|
||||
offset.OffsetHigh = (DWORD)sz;
|
||||
ato32(data + idx, &sz);
|
||||
idx += UINT32_SZ;
|
||||
offset.Offset = (DWORD)sz;
|
||||
|
||||
/* get length to be written */
|
||||
ato32(data + idx, &sz);
|
||||
idx += UINT32_SZ;
|
||||
|
||||
if (WriteFile(fd, data, sz, &bytesWritten, &offset) == 0) {
|
||||
WLOG(WS_LOG_SFTP, "Error writing to file");
|
||||
res = err;
|
||||
type = WOLFSSH_FTP_FAILURE;
|
||||
ret = WS_INVALID_STATE_E;
|
||||
}
|
||||
else {
|
||||
ret = WS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (wolfSSH_SFTP_CreateStatus(ssh, type, reqId, res, "English", NULL,
|
||||
&outSz) != WS_SIZE_ONLY) {
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
out = (byte*)WMALLOC(outSz, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
if (out == NULL) {
|
||||
return WS_MEMORY_E;
|
||||
}
|
||||
if (wolfSSH_SFTP_CreateStatus(ssh, type, reqId, res, "English", out,
|
||||
&outSz) != WS_SUCCESS) {
|
||||
WFREE(out, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
wolfSSH_SFTP_RecvSetSend(ssh, out, outSz);
|
||||
return WS_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* USE_WINDOWS_API */
|
||||
|
||||
|
||||
/* Handles packet to read a file
|
||||
|
|
@ -2306,6 +2540,7 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
* returns WS_SUCCESS on success
|
||||
*/
|
||||
int wolfSSH_SFTP_RecvRead(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
||||
#ifndef USE_WINDOWS_API
|
||||
{
|
||||
WFD fd;
|
||||
word32 sz;
|
||||
|
|
@ -2396,6 +2631,113 @@ int wolfSSH_SFTP_RecvRead(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
wolfSSH_SFTP_RecvSetSend(ssh, out, outSz);
|
||||
return ret;
|
||||
}
|
||||
#else /* USE_WINDOWS_API */
|
||||
{
|
||||
OVERLAPPED offset;
|
||||
HANDLE fd;
|
||||
DWORD bytesRead;
|
||||
word32 sz;
|
||||
int ret;
|
||||
word32 idx = 0;
|
||||
|
||||
byte* out;
|
||||
word32 outSz;
|
||||
|
||||
char* res = NULL;
|
||||
char err[] = "Read File Error";
|
||||
char eof[] = "Read EOF";
|
||||
byte type = WOLFSSH_FTP_FAILURE;
|
||||
|
||||
if (ssh == NULL) {
|
||||
return WS_BAD_ARGUMENT;
|
||||
}
|
||||
|
||||
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_READ");
|
||||
|
||||
/* get file handle */
|
||||
ato32(data + idx, &sz); idx += UINT32_SZ;
|
||||
if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE) {
|
||||
return WS_BUFFER_E;
|
||||
}
|
||||
WMEMSET((byte*)&fd, 0, sizeof(HANDLE));
|
||||
WMEMCPY((byte*)&fd, data + idx, sz); idx += sz;
|
||||
|
||||
WMEMSET(&offset, 0, sizeof(OVERLAPPED));
|
||||
|
||||
/* get offset into file */
|
||||
ato32(data + idx, &sz);
|
||||
idx += UINT32_SZ;
|
||||
offset.OffsetHigh = (DWORD)sz;
|
||||
ato32(data + idx, &sz);
|
||||
idx += UINT32_SZ;
|
||||
offset.Offset = (DWORD)sz;
|
||||
|
||||
/* get length to be read */
|
||||
ato32(data + idx, &sz);
|
||||
|
||||
/* read from handle and send data back to client */
|
||||
out = (byte*)WMALLOC(sz + WOLFSSH_SFTP_HEADER + UINT32_SZ,
|
||||
ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
if (out == NULL) {
|
||||
return WS_MEMORY_E;
|
||||
}
|
||||
|
||||
if (ReadFile(fd, data, sz, &bytesRead, &offset) == 0) {
|
||||
if (GetLastError() == ERROR_HANDLE_EOF) {
|
||||
ret = 0; /* return 0 for end of file */
|
||||
}
|
||||
else {
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = (int)bytesRead;
|
||||
outSz = (word32)ret + WOLFSSH_SFTP_HEADER + UINT32_SZ;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
WLOG(WS_LOG_SFTP, "Error reading from file");
|
||||
res = err;
|
||||
type = WOLFSSH_FTP_FAILURE;
|
||||
ret = WS_BAD_FILE_E;
|
||||
}
|
||||
|
||||
/* eof */
|
||||
if (ret == 0) {
|
||||
WLOG(WS_LOG_SFTP, "Error reading from file");
|
||||
res = eof;
|
||||
type = WOLFSSH_FTP_EOF;
|
||||
ret = WS_SUCCESS; /* end of file is not fatal error */
|
||||
}
|
||||
|
||||
if (res != NULL) {
|
||||
if (wolfSSH_SFTP_CreateStatus(ssh, type, reqId, res, "English", NULL,
|
||||
&outSz) != WS_SIZE_ONLY) {
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
if (outSz > sz) {
|
||||
/* need to increase buffer size for holding status packet */
|
||||
WFREE(out, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
out = (byte*)WMALLOC(outSz, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
if (out == NULL) {
|
||||
return WS_MEMORY_E;
|
||||
}
|
||||
}
|
||||
if (wolfSSH_SFTP_CreateStatus(ssh, type, reqId, res, "English", out,
|
||||
&outSz) != WS_SUCCESS) {
|
||||
WFREE(out, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
SFTP_CreatePacket(ssh, WOLFSSH_FTP_DATA, out, outSz, NULL, 0);
|
||||
}
|
||||
|
||||
wolfSSH_SFTP_RecvSetSend(ssh, out, outSz);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* USE_WINDOWS_API */
|
||||
|
||||
|
||||
/* Handles packet to close a file
|
||||
|
|
@ -2403,6 +2745,7 @@ int wolfSSH_SFTP_RecvRead(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
* returns WS_SUCCESS on success
|
||||
*/
|
||||
int wolfSSH_SFTP_RecvClose(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
||||
#ifndef USE_WINDOWS_API
|
||||
{
|
||||
WFD fd;
|
||||
word32 sz;
|
||||
|
|
@ -2478,6 +2821,76 @@ int wolfSSH_SFTP_RecvClose(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
wolfSSH_SFTP_RecvSetSend(ssh, out, outSz);
|
||||
return ret;
|
||||
}
|
||||
#else /* USE_WINDOWS_API */
|
||||
{
|
||||
HANDLE fd;
|
||||
word32 sz;
|
||||
word32 idx = 0;
|
||||
int ret;
|
||||
|
||||
byte* out = NULL;
|
||||
word32 outSz = 0;
|
||||
|
||||
char* res = NULL;
|
||||
char suc[] = "Closed File";
|
||||
char err[] = "Close File Error";
|
||||
byte type = WOLFSSH_FTP_FAILURE;
|
||||
|
||||
if (ssh == NULL) {
|
||||
return WS_BAD_ARGUMENT;
|
||||
}
|
||||
|
||||
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_CLOSE");
|
||||
|
||||
/* get file handle */
|
||||
ato32(data + idx, &sz); idx += UINT32_SZ;
|
||||
if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE) {
|
||||
return WS_BUFFER_E;
|
||||
}
|
||||
|
||||
if (sz == sizeof(HANDLE)) {
|
||||
WMEMSET((byte*)&fd, 0, sizeof(HANDLE));
|
||||
WMEMCPY((byte*)&fd, data + idx, sz);
|
||||
CloseHandle(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;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
WLOG(WS_LOG_SFTP, "Error closing file");
|
||||
res = err;
|
||||
ret = WS_BAD_FILE_E;
|
||||
}
|
||||
else {
|
||||
res = suc;
|
||||
type = WOLFSSH_FTP_OK;
|
||||
ret = WS_SUCCESS;
|
||||
}
|
||||
|
||||
if (wolfSSH_SFTP_CreateStatus(ssh, type, reqId, res, "English", NULL,
|
||||
&outSz) != WS_SIZE_ONLY) {
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
out = (byte*)WMALLOC(outSz, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
if (out == NULL) {
|
||||
return WS_MEMORY_E;
|
||||
}
|
||||
if (wolfSSH_SFTP_CreateStatus(ssh, type, reqId, res, "English", out,
|
||||
&outSz) != WS_SUCCESS) {
|
||||
WFREE(out, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
wolfSSH_SFTP_RecvSetSend(ssh, out, outSz);
|
||||
return ret;
|
||||
}
|
||||
#endif /* USE_WINDOWS_API */
|
||||
|
||||
|
||||
|
||||
|
|
@ -2519,6 +2932,7 @@ int wolfSSH_SFTP_RecvRemove(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
name[sz] = '\0';
|
||||
|
||||
clean_path(name);
|
||||
#if 0
|
||||
if ((ret = WREMOVE(name)) < 0) {
|
||||
WLOG(WS_LOG_SFTP, "Error removing file");
|
||||
#if defined(WOLFSSL_NUCLEUS) && defined(DEBUG_WOLFSSH)
|
||||
|
|
@ -2536,6 +2950,8 @@ int wolfSSH_SFTP_RecvRemove(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
else {
|
||||
ret = WS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
ret = WS_BAD_FILE_E;
|
||||
|
||||
/* Let the client know the results from trying to remove the file */
|
||||
WFREE(name, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
|
|
@ -2618,10 +3034,13 @@ int wolfSSH_SFTP_RecvRename(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
|
||||
clean_path(old);
|
||||
clean_path(nw);
|
||||
#if 0
|
||||
if (ret == WS_SUCCESS && WRENAME(old, nw) < 0) {
|
||||
WLOG(WS_LOG_SFTP, "Error renaming file");
|
||||
ret = WS_BAD_FILE_E;
|
||||
}
|
||||
#endif
|
||||
ret = WS_BAD_FILE_E;
|
||||
|
||||
/* Let the client know the results from trying to rename the file */
|
||||
WFREE(old, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
|
|
@ -2921,6 +3340,48 @@ int SFTP_GetAttributes_Handle(WOLFSSH* ssh, byte* handle, int handleSz,
|
|||
NU_Done(&stats);
|
||||
return WS_SUCCESS;
|
||||
}
|
||||
|
||||
#elif defined(USE_WINDOWS_API)
|
||||
|
||||
/* @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)
|
||||
{
|
||||
BOOL error;
|
||||
WIN32_FILE_ATTRIBUTE_DATA stats;
|
||||
|
||||
(void)link;
|
||||
/* @TODO add proper Windows link support */
|
||||
/* Note, for windows, we treat WSTAT and WLSTAT the same. */
|
||||
error = !GetFileAttributesExA(fileName, GetFileExInfoStandard, &stats);
|
||||
if (error)
|
||||
return WS_BAD_FILE_E;
|
||||
|
||||
WMEMSET(atr, 0, sizeof(WS_SFTP_FILEATRB));
|
||||
|
||||
atr->flags |= WOLFSSH_FILEATRB_SIZE;
|
||||
atr->sz = (((word64)stats.nFileSizeHigh << 32) | stats.nFileSizeLow);
|
||||
|
||||
#if 0
|
||||
atr->flags |= WOLFSSH_FILEATRB_PERM;
|
||||
atr->per = (word32)stats.dwFileAttributes;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* @TODO handle the constellation of possible Windows FILETIMEs */
|
||||
atr->flags |= WOLFSSH_FILEATRB_TIME;
|
||||
atr->atime = (word32)stats.ftLastAccessTime;
|
||||
atr->mtime = (word32)stats.ftLastWriteTime;
|
||||
#endif
|
||||
|
||||
/* @TODO handle attribute extensions */
|
||||
|
||||
return WS_SUCCESS;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* @TODO can be overriden by user for portability
|
||||
|
|
@ -3009,6 +3470,7 @@ int SFTP_GetAttributes_Handle(WOLFSSH* ssh, byte* handle, int handleSz,
|
|||
#endif
|
||||
|
||||
|
||||
#ifndef USE_WINDOWS_API
|
||||
/* Handles receiving fstat packet
|
||||
* returns WS_SUCCESS on success
|
||||
*/
|
||||
|
|
@ -3072,8 +3534,11 @@ int wolfSSH_SFTP_RecvFSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
wolfSSH_SFTP_RecvSetSend(ssh, out, outSz);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
|
||||
/* Handles receiving stat packet
|
||||
* returns WS_SUCCESS on success
|
||||
*/
|
||||
|
|
@ -3226,7 +3691,10 @@ int wolfSSH_SFTP_RecvLSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#endif /* _WIN32_WCE */
|
||||
|
||||
|
||||
#ifndef USE_WINDOWS_API
|
||||
/* Set the files mode
|
||||
* return WS_SUCCESS on success */
|
||||
static int SFTP_SetMode(WOLFSSH* ssh, char* name, word32 mode) {
|
||||
|
|
@ -3236,8 +3704,11 @@ static int SFTP_SetMode(WOLFSSH* ssh, char* name, word32 mode) {
|
|||
}
|
||||
return WS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
|
||||
/* sets a files attributes
|
||||
* returns WS_SUCCESS on success */
|
||||
static int SFTP_SetFileAttributes(WOLFSSH* ssh, char* name, WS_SFTP_FILEATRB* atr)
|
||||
|
|
@ -3254,10 +3725,12 @@ static int SFTP_SetFileAttributes(WOLFSSH* ssh, char* name, WS_SFTP_FILEATRB* at
|
|||
/* @TODO set group and user id */
|
||||
}
|
||||
|
||||
#ifndef USE_WINDOWS_API
|
||||
/* check if permissions attribute present */
|
||||
if (atr->flags & WOLFSSH_FILEATRB_PERM) {
|
||||
ret = SFTP_SetMode(ssh, name, atr->per);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check if time attribute present */
|
||||
if (atr->flags & WOLFSSH_FILEATRB_TIME) {
|
||||
|
|
@ -3282,7 +3755,7 @@ int wolfSSH_SFTP_RecvSetSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
{
|
||||
WS_SFTP_FILEATRB atr;
|
||||
char* name = NULL;
|
||||
int ret;
|
||||
int ret = WS_SUCCESS;
|
||||
|
||||
word32 sz;
|
||||
word32 idx = 0;
|
||||
|
|
@ -3349,6 +3822,8 @@ int wolfSSH_SFTP_RecvSetSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
|
|||
wolfSSH_SFTP_RecvSetSend(ssh, out, outSz);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* _WIN32_WCE */
|
||||
#endif /* !NO_WOLFSSH_SERVER */
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -120,6 +120,9 @@ extern "C" {
|
|||
#define WCHMOD(f,m) wChmod((f),(m))
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#ifndef _WIN32_WCE
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#define WFILE FILE
|
||||
WOLFSSH_API int wfopen(WFILE**, const char*, const char*);
|
||||
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ typedef enum {
|
|||
WOLFSSH_SESSION_UNKNOWN = 0,
|
||||
WOLFSSH_SESSION_SHELL,
|
||||
WOLFSSH_SESSION_EXEC,
|
||||
WOLFSSH_SESSION_SUBSYSTEM,
|
||||
WOLFSSH_SESSION_SUBSYSTEM
|
||||
} WS_SessionType;
|
||||
|
||||
WOLFSSH_API WS_SessionType wolfSSH_GetSessionType(const WOLFSSH*);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,10 @@
|
|||
|
||||
#include <wolfssh/ssh.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Packet Types */
|
||||
enum WS_PacketTypes {
|
||||
WOLFSSH_FTP_INIT = 1,
|
||||
|
|
@ -79,7 +83,7 @@ enum WS_SFTPConnectStates {
|
|||
SFTP_BEGIN = 20,
|
||||
SFTP_RECV,
|
||||
SFTP_EXT,
|
||||
SFTP_DONE,
|
||||
SFTP_DONE
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -233,3 +237,8 @@ WOLFSSH_LOCAL int wolfSSH_SFTP_RecvCloseDir(WOLFSSH* ssh, byte* handle,
|
|||
WOLFSSL_LOCAL int wolfSSH_SFTP_free(WOLFSSH* ssh);
|
||||
WOLFSSL_LOCAL int SFTP_AddHandleNode(WOLFSSH* ssh, byte* handle, word32 handleSz, char* name);
|
||||
WOLFSSL_LOCAL int SFTP_RemoveHandleNode(WOLFSSH* ssh, byte* handle, word32 handleSz);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue