Skip to content

Commit

Permalink
Merge pull request wolfSSL#630 from ejohnstown/sftp-zero
Browse files Browse the repository at this point in the history
SFTP Regular Files
  • Loading branch information
JacobBarthelmeh authored Dec 7, 2023
2 parents 3905a05 + 59e7b37 commit bb62158
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 14 deletions.
12 changes: 12 additions & 0 deletions examples/sftpclient/sftpclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,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 getting file\n") < 0) {
err_msg("fputs error");
return -1;
Expand Down Expand Up @@ -628,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
3 changes: 3 additions & 0 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,9 @@ const char* GetErrorString(int err)
case WS_KEY_FORMAT_E:
return "key format wrong error";

case WS_SFTP_NOT_FILE_E:
return "not a regular file";

default:
return "Unknown error code";
}
Expand Down
70 changes: 57 additions & 13 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 @@ -4708,9 +4729,9 @@ static int PopulateAttributes(WS_SFTP_FILEATRB* atr, WSTAT_T* stats)
atr->per = 0755;
/* Mimic S_IFMT */
if (stats->type == FS_DIR_ENTRY_FILE)
atr->per |= 0040000;
atr->per |= FILEATRB_PER_FILE;
else if (stats->type == FS_DIR_ENTRY_DIR)
atr->per |= 0100000;
atr->per |= FILEATRB_PER_DIR;
else
return WS_BAD_FILE_E;

Expand Down Expand Up @@ -8481,6 +8502,14 @@ int wolfSSH_SFTP_Get(WOLFSSH* ssh, char* from,
state->state = STATE_GET_CLEANUP;
continue;
}
if ((state->attrib.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_GET_CLEANUP;
continue;
}
state->handleSz = WOLFSSH_MAX_HANDLE;
state->state = STATE_GET_OPEN_REMOTE;
NO_BREAK;
Expand Down Expand Up @@ -8714,6 +8743,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
3 changes: 2 additions & 1 deletion wolfssh/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,9 @@ enum WS_ErrorCodes {
WS_KEY_AUTH_MAGIC_E = -1090, /* OpenSSH key auth magic check fail */
WS_KEY_CHECK_VAL_E = -1091, /* OpenSSH key check value fail */
WS_KEY_FORMAT_E = -1092, /* OpenSSH key format fail */
WS_SFTP_NOT_FILE_E = -1093, /* Not a regular file */

WS_LAST_E = -1092 /* Update this to indicate last error */
WS_LAST_E = -1093 /* Update this to indicate last error */
};


Expand Down
7 changes: 7 additions & 0 deletions wolfssh/wolfsftp.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ struct WS_SFTP_FILEATRB_EX {
WS_SFTP_FILEATRB_EX* next;
};

#define FILEATRB_PER_MASK_TYPE 0770000
#define FILEATRB_PER_FILE 0100000
#define FILEATRB_PER_DEV_CHAR 0020000
#define FILEATRB_PER_DIR 0040000
#define FILEATRB_PER_DEV_BLOCK 0060000
#define FILEATRB_PER_MASK_PERM 0000777

typedef struct WS_SFTP_FILEATRB {
word32 flags;
word32 sz[2]; /* sz[0] being the lower and sz[1] being the upper */
Expand Down

0 comments on commit bb62158

Please sign in to comment.