Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SFTP Regular Files #630

Merged
merged 3 commits into from
Dec 7, 2023
Merged
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
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
Loading