Skip to content

Commit

Permalink
SFTP Zero Byte Files
Browse files Browse the repository at this point in the history
1. When putting a file with SFTP, the client should check that the
   requested file is a regular file based on its attributes.
 2. Add the attributes to check in the permissions.
 3. Add server checking for non-regular files and not allowing them to
    be opened for reading or writing.
  • Loading branch information
ejohnstown committed Dec 5, 2023
1 parent 6aad26d commit 66ebc1e
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 11 deletions.
6 changes: 6 additions & 0 deletions examples/sftpclient/sftpclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,12 @@ static int doCmds(func_args* args)
#endif

if (ret != WS_SUCCESS) {
if (wolfSSH_get_error(ssh) == WS_SFTP_NOT_FILE_E) {
if (SFTP_FPUTS(args, "Not a regular file\n") < 0) {
err_msg("fputs error");
return -1;
}
}
if (SFTP_FPUTS(args, "Error pushing file\n") < 0) {
err_msg("fputs error");
return -1;
Expand Down
58 changes: 47 additions & 11 deletions src/wolfsftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1977,6 +1977,7 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
char* res = NULL;
char ier[] = "Internal Failure";
char oer[] = "Open File Error";
char naf[] = "Not A File";

if (ssh == NULL) {
return WS_BAD_ARGUMENT;
Expand Down Expand Up @@ -2036,20 +2037,40 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
m |= WOLFSSH_O_EXCL;
}

/* if file permissions not set then use default */
if (!(atr.flags & WOLFSSH_FILEATRB_PERM)) {
atr.per = 0644;
{
WS_SFTP_FILEATRB fileAtr = { 0 };
if (SFTP_GetAttributes(ssh->fs,
dir, &fileAtr, 1, ssh->ctx->heap) == WS_SUCCESS) {
if ((fileAtr.per & FILEATRB_PER_MASK_TYPE) != FILEATRB_PER_FILE) {
WLOG(WS_LOG_SFTP, "Not a file");
ssh->error = WS_SFTP_NOT_FILE_E;

res = naf;
if (wolfSSH_SFTP_CreateStatus(ssh, WOLFSSH_FTP_FAILURE, reqId,
res, "English", NULL, &outSz) != WS_SIZE_ONLY) {
return WS_FATAL_ERROR;
}
ret = WS_FATAL_ERROR;
}
}
}

fd = WOPEN(ssh->fs, dir, m, atr.per);
if (fd < 0) {
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;
if (ret == WS_SUCCESS) {
/* if file permissions not set then use default */
if (!(atr.flags & WOLFSSH_FILEATRB_PERM)) {
atr.per = 0644;
}

fd = WOPEN(ssh->fs, dir, m, atr.per);
if (fd < 0) {
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;
}
ret = WS_BAD_FILE_E;
}

#ifdef WOLFSSH_STOREHANDLE
Expand Down Expand Up @@ -8714,6 +8735,21 @@ int wolfSSH_SFTP_Put(WOLFSSH* ssh, char* from, char* to, byte resume,
case STATE_PUT_OPEN_LOCAL:
WLOG(WS_LOG_SFTP, "SFTP PUT STATE: OPEN LOCAL");
#ifndef USE_WINDOWS_API
{
WS_SFTP_FILEATRB fileAtr = { 0 };
if (SFTP_GetAttributes(ssh->fs,
from, &fileAtr, 1, ssh->ctx->heap)
== WS_SUCCESS) {
if ((fileAtr.per & FILEATRB_PER_MASK_TYPE)
!= FILEATRB_PER_FILE) {
WLOG(WS_LOG_SFTP, "Not a file");
ssh->error = WS_SFTP_NOT_FILE_E;
ret = WS_FATAL_ERROR;
state->state = STATE_PUT_CLEANUP;
continue;
}
}
}
ret = WFOPEN(ssh->fs, &state->fl, from, "rb");
if (ret != 0) {
WLOG(WS_LOG_SFTP, "Unable to open input file");
Expand Down

0 comments on commit 66ebc1e

Please sign in to comment.