Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions apps/wolfsshd/wolfsshd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2851,11 +2851,12 @@ static int StartSSHD(int argc, char** argv)
if (cmdArgs == NULL) {
ret = WS_FATAL_ERROR;
}
argc = cmdArgC;

if (ret == WS_SUCCESS) {
for (i = 0; i < argc; i++) {
if (WSTRCMP((char*)(cmdArgs[i]), "-D") == 0) {
for (i = 0; i < (DWORD)cmdArgC; i++) {
/* cmdArgs entries are wide strings (CommandLineToArgvW); compare
* as such instead of reinterpreting as narrow char data. */
if (wcscmp(cmdArgs[i], L"-D") == 0) {
Comment thread
miyazakh marked this conversation as resolved.
isDaemon = 0;
}
}
Expand All @@ -2866,6 +2867,10 @@ static int StartSSHD(int argc, char** argv)
wolfSSH_SetLoggingCb(ServiceDebugCb);

if (ret == WS_SUCCESS) {
/* argv is being rebuilt from cmdArgs here, so argc must match
* cmdArgC, the count CommandLineToArgvW gave for that array. */
argc = (DWORD)cmdArgC;

/* we want the arguments to be normal char strings not wchar_t */
argv = (char**)WMALLOC(argc * sizeof(char*), NULL, DYNTYPE_SSHD);
if (argv == NULL) {
Expand All @@ -2880,6 +2885,9 @@ static int StartSSHD(int argc, char** argv)
}
}
else {
/* argc is left as the caller-supplied value here: it already
* matches wargv, which comes from the CRT's own command-line
* parser and is independent of CommandLineToArgvW's cmdArgC. */
argv = (char**)wargv;
}
#endif
Expand Down
94 changes: 71 additions & 23 deletions src/wolfsftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ static int SFTP_AddFileHandle(WOLFSSH* ssh,
#else
WFD fd,
#endif
const char* fileName, word32 id[2]);
const char* fileName, word32 id[2], int isAppend);
static int SFTP_RemoveFileHandle(WOLFSSH* ssh, word32 id[2]);
static int SFTP_FileHandleCapped(WOLFSSH* ssh);
#endif /* !NO_WOLFSSH_SERVER */
Expand Down Expand Up @@ -2326,6 +2326,35 @@ static void SFTP_HandleIdNext(WOLFSSH* ssh, word32 id[2])

#endif /* !NO_WOLFSSH_SERVER */

#ifdef USE_WINDOWS_API
/* dwCreationDisposition takes one enumerated value, not a bitmask, so
* resolve CREAT/EXCL/TRUNC to a single disposition here. */
static DWORD SFTP_WinCreationDisp(word32 reason)
{
DWORD disp;

if (reason & WOLFSSH_FXF_CREAT) {
if (reason & WOLFSSH_FXF_EXCL)
disp = CREATE_NEW;
else if (reason & WOLFSSH_FXF_TRUNC)
disp = CREATE_ALWAYS;
else
disp = OPEN_ALWAYS;
}
else {
/* TRUNCATE_EXISTING requires GENERIC_WRITE in dwDesiredAccess or
* CreateFile() fails with ERROR_INVALID_PARAMETER; without WRITE
* there is no way to truncate, so fall back to OPEN_EXISTING. */
if ((reason & WOLFSSH_FXF_TRUNC) && (reason & WOLFSSH_FXF_WRITE))
disp = TRUNCATE_EXISTING;
Comment thread
miyazakh marked this conversation as resolved.
else
disp = OPEN_EXISTING;
}

return disp;
}
#endif /* USE_WINDOWS_API */

/* Handles packet to open a file
*
* returns WS_SUCCESS on success
Expand Down Expand Up @@ -2505,7 +2534,8 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
/* Generate unique file handle ID and add to tracking list */
SFTP_HandleIdNext(ssh, id);

if ((ret = SFTP_AddFileHandle(ssh, fd, dir, id)) != WS_SUCCESS) {
if ((ret = SFTP_AddFileHandle(ssh, fd, dir, id,
(reason & WOLFSSH_FXF_APPEND) ? 1 : 0)) != WS_SUCCESS) {
WLOG(WS_LOG_SFTP, "Unable to store handle");
res = ier;
if (wolfSSH_SFTP_CreateStatus(ssh, WOLFSSH_FTP_FAILURE, reqId, res,
Expand Down Expand Up @@ -2651,23 +2681,14 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
}
#endif

if (reason & WOLFSSH_FXF_READ) {
if (reason & WOLFSSH_FXF_READ)
desiredAccess |= GENERIC_READ;
creationDisp |= OPEN_EXISTING;
}
if (reason & WOLFSSH_FXF_WRITE) {
if (reason & WOLFSSH_FXF_WRITE)
desiredAccess |= GENERIC_WRITE;
if (reason & WOLFSSH_FXF_CREAT)
creationDisp |= CREATE_ALWAYS;
#if 0
if (reason & WOLFSSH_FXF_TRUNC)
creationDisp |= TRUNCATE_EXISTING;
if (reason & WOLFSSH_FXF_EXCL)
creationDisp |= CREATE_NEW;
if (reason & WOLFSSH_FXF_APPEND)
desiredAccess |= FILE_APPEND_DATA;
#endif
}
if (reason & WOLFSSH_FXF_APPEND)
desiredAccess |= FILE_APPEND_DATA;
Comment thread
miyazakh marked this conversation as resolved.
Comment thread
miyazakh marked this conversation as resolved.

creationDisp = SFTP_WinCreationDisp(reason);
Comment thread
miyazakh marked this conversation as resolved.

#if 0
/* if file permissions not set then use default */
Expand Down Expand Up @@ -2697,7 +2718,8 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
/* Generate unique file handle ID and add to tracking list */
SFTP_HandleIdNext(ssh, id);

if (SFTP_AddFileHandle(ssh, fileHandle, dir, id) != WS_SUCCESS) {
if (SFTP_AddFileHandle(ssh, fileHandle, dir, id,
(reason & WOLFSSH_FXF_APPEND) ? 1 : 0) != WS_SUCCESS) {
WLOG(WS_LOG_SFTP, "Unable to store handle");
res = ier;
if (wolfSSH_SFTP_CreateStatus(ssh, WOLFSSH_FTP_FAILURE, reqId, res,
Expand Down Expand Up @@ -2766,6 +2788,7 @@ struct WS_FILE_LIST {
char* fileName; /* cleaned full path of the open file */
word32 id[2]; /* handle ID */
struct WS_FILE_LIST* next;
unsigned int isAppend:1; /* WOLFSSH_FXF_APPEND was requested at open */
};

#ifndef NO_WOLFSSH_DIR
Expand Down Expand Up @@ -4089,7 +4112,7 @@ static int SFTP_AddFileHandle(WOLFSSH* ssh,
#else
WFD fd,
#endif
const char* fileName, word32 id[2])
const char* fileName, word32 id[2], int isAppend)
{
WS_FILE_LIST* cur = NULL;
char* fileNameCopy = NULL;
Expand Down Expand Up @@ -4130,6 +4153,7 @@ static int SFTP_AddFileHandle(WOLFSSH* ssh,
cur->fileName = fileNameCopy;
cur->id[0] = id[0];
cur->id[1] = id[1];
cur->isAppend = (isAppend != 0) ? 1 : 0;
cur->next = ssh->fileList;
ssh->fileList = cur;

Expand Down Expand Up @@ -4348,8 +4372,10 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
OVERLAPPED offset;
HANDLE fd;
DWORD bytesWritten;
LARGE_INTEGER fileSize;
int ret = WS_SUCCESS;
int rc;
int isAppend = 0;
word32 idx = 0;

const byte* str;
Expand Down Expand Up @@ -4397,6 +4423,7 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
}
else {
fd = fileEntry->fd;
isAppend = fileEntry->isAppend;
}
}
}
Expand All @@ -4413,6 +4440,25 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
}
offset.Offset = (DWORD)strSz;

/* WOLFSSH_FXF_APPEND was requested at open: FILE_APPEND_DATA alone
* does not force writes to EOF once the handle also carries
* FILE_WRITE_DATA (granted implicitly by GENERIC_WRITE), so the
* client-supplied offset must be overridden with the current EOF. */
if (isAppend) {
if (GetFileSizeEx(fd, &fileSize) == 0) {
WLOG(WS_LOG_SFTP, "Error getting file size for append");
res = err;
type = WOLFSSH_FTP_FAILURE;
ret = WS_INVALID_STATE_E;
}
else {
offset.Offset = fileSize.LowPart;
offset.OffsetHigh = (DWORD)fileSize.HighPart;
}
}
}

if (ret == WS_SUCCESS) {
/* get length to be written */
if (GetStringRef(&strSz, &str, data, maxSz, &idx) != WS_SUCCESS) {
return WS_BUFFER_E;
Expand Down Expand Up @@ -6332,8 +6378,7 @@ int wolfSSH_SFTP_RecvFSetSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)

#endif /* _WIN32_WCE */

#if defined(WOLFSSH_TEST_INTERNAL) && !defined(USE_WINDOWS_API) && \
!defined(NO_FILESYSTEM)
#if defined(WOLFSSH_TEST_INTERNAL) && !defined(NO_FILESYSTEM)
/* Test-only plumbing for the forged-handle regression test in tests/regress.c.
*
* The SFTP request handlers buffer their status/handle reply into ssh->recvState
Expand Down Expand Up @@ -6416,10 +6461,12 @@ int wolfSSH_SFTP_TestDirHandleCount(WOLFSSH* ssh)
}
#endif /* NO_WOLFSSH_DIR */

#ifndef USE_WINDOWS_API
/* Close the underlying descriptor of the head tracked file handle out of band,
* leaving the node in the list with a now-stale fd. The next RecvClose on that
* handle will see its close() fail, exercising the path that must still drop
* the handle from the tracking list. Returns WS_SUCCESS if a node was found. */
* the handle from the tracking list. Returns WS_SUCCESS if a node was found.
* Not provided for Windows, where fd is a HANDLE, not a WCLOSE-able fd. */
int wolfSSH_SFTP_TestInvalidateHeadFd(WOLFSSH* ssh)
{
if (ssh == NULL || ssh->fileList == NULL) {
Expand All @@ -6432,7 +6479,8 @@ int wolfSSH_SFTP_TestInvalidateHeadFd(WOLFSSH* ssh)
#endif
return WS_SUCCESS;
}
#endif /* WOLFSSH_TEST_INTERNAL && !USE_WINDOWS_API && !NO_FILESYSTEM */
#endif /* !USE_WINDOWS_API */
#endif /* WOLFSSH_TEST_INTERNAL && !NO_FILESYSTEM */

#endif /* !NO_WOLFSSH_SERVER */

Expand Down
Loading
Loading