Skip to content

Commit f1b6a99

Browse files
yosuke-wolfsslejohnstown
authored andcommitted
wolfsftp, port: apply the attributes SETSTAT and FSETSTAT acknowledge
- SFTP_SetFileAttributes() and SFTP_SetFileAttributesHandle() carry out the size, ownership, permission and timestamp requests while ret is WS_SUCCESS, bound the size with wResolveOffset() against WOLFSSH_MAX_FILE_OFFSET, and set WS_UNIMPLEMENTED_E where the port defines no wrapper. - wolfSSH_SFTP_RecvSetSTAT() and wolfSSH_SFTP_RecvFSetSTAT() answer WOLFSSH_FTP_UNSUPPORTED for WS_UNIMPLEMENTED_E; wolfSSH_SFTP_CHMOD() sets the attribute flags to WOLFSSH_FILEATRB_PERM before sending. - port.h adds WTRUNCATE, WFTRUNCATE, WCHOWN and WFCHOWN for the POSIX port, and defines WSETTIME and WFSETTIME over the existing WUTIMES and WFUTIMES helpers in place of their (0) definitions. - SFTP_SetMode() guards on _WIN32_WCE in place of USE_WINDOWS_API, and port.c adds WS_ChmodA(), which trims the SFTP leading root and calls _wchmod(); it and the WCHMOD mapping to it are left out under _WIN32_WCE, which keeps the _chmod mapping. - tests/regress.c adds TestSftpSetStatAttributes(); tests/sftp.c adds a chmod of a directory and installs SFTP_TEST_UMASK in place of the sftpTestUmask static; the STATE_SET_ATR_SEND case in tests/api.c sets atr.flags to WOLFSSH_FILEATRB_PERM. Issue: F-11658
1 parent a472f1e commit f1b6a99

6 files changed

Lines changed: 485 additions & 37 deletions

File tree

src/port.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,44 @@ int WS_DeleteFileA(const char* fileName, void* heap)
542542
}
543543

544544

545+
546+
#ifndef _WIN32_WCE
547+
548+
int WS_ChmodA(const char* fileName, int mode, void* heap)
549+
{
550+
int ret = -1;
551+
wchar_t* unicodeFileName;
552+
size_t unicodeFileNameSz = 0;
553+
size_t returnSz = 0;
554+
size_t fileNameSz = 0;
555+
errno_t error;
556+
557+
fileNameSz = WSTRLEN(fileName);
558+
fileName = TrimFileName(fileName, &fileNameSz);
559+
560+
error = mbstowcs_s(&unicodeFileNameSz, NULL, 0, fileName, 0);
561+
if (error != 0)
562+
return -1;
563+
564+
unicodeFileName = (wchar_t*)WMALLOC((unicodeFileNameSz+1)*sizeof(wchar_t),
565+
heap, PORT_DYNTYPE_STRING);
566+
if (unicodeFileName == NULL)
567+
return -1;
568+
569+
error = mbstowcs_s(&returnSz, unicodeFileName, unicodeFileNameSz,
570+
fileName, fileNameSz);
571+
572+
if (error == 0) {
573+
ret = _wchmod(unicodeFileName, mode);
574+
}
575+
576+
WFREE(unicodeFileName, heap, PORT_DYNTYPE_STRING);
577+
578+
return ret;
579+
}
580+
581+
#endif /* !_WIN32_WCE */
582+
545583
#endif /* USE_WINDOWS_API WOLFSSH_SFTP WOLFSSH_SCP */
546584

547585
#if !defined(NO_FILESYSTEM) && \

src/wolfsftp.c

Lines changed: 80 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6061,7 +6061,7 @@ int wolfSSH_SFTP_RecvLSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
60616061
return ret;
60626062
}
60636063

6064-
#if !defined(USE_WINDOWS_API) && !defined(WOLFSSH_ZEPHYR) \
6064+
#if !defined(_WIN32_WCE) && !defined(WOLFSSH_ZEPHYR) \
60656065
&& !defined(WOLFSSH_SFTP_SETMODE) && !defined(WOLFSSH_FATFS)
60666066
/* Set the files mode
60676067
* return WS_SUCCESS on success */
@@ -6097,29 +6097,47 @@ static int SFTP_SetFileAttributes(WOLFSSH* ssh,
60976097
char* name, WS_SFTP_FILEATRB* atr)
60986098
{
60996099
int ret = WS_SUCCESS;
6100+
#ifdef WTRUNCATE
6101+
word64 sz;
6102+
#endif
61006103

61016104
/* check if size attribute present */
6102-
if (atr->flags & WOLFSSH_FILEATRB_SIZE) {
6103-
/* @TODO set file size */
6105+
if (ret == WS_SUCCESS && (atr->flags & WOLFSSH_FILEATRB_SIZE)) {
6106+
#ifdef WTRUNCATE
6107+
if (wResolveOffset(atr->sz, WOLFSSH_MAX_FILE_OFFSET, &sz) != 0
6108+
|| WTRUNCATE(ssh->fs, name, sz) != 0) {
6109+
ret = WS_BAD_FILE_E;
6110+
}
6111+
#else
6112+
ret = WS_UNIMPLEMENTED_E;
6113+
#endif
61046114
}
61056115

61066116
/* check if uid and gid attribute present */
6107-
if (atr->flags & WOLFSSH_FILEATRB_UIDGID) {
6108-
/* @TODO set group and user id */
6117+
if (ret == WS_SUCCESS && (atr->flags & WOLFSSH_FILEATRB_UIDGID)) {
6118+
#ifdef WCHOWN
6119+
if (WCHOWN(ssh->fs, name, atr->uid, atr->gid) != 0) {
6120+
ret = WS_BAD_FILE_E;
6121+
}
6122+
#else
6123+
ret = WS_UNIMPLEMENTED_E;
6124+
#endif
61096125
}
61106126

6111-
#if !defined(USE_WINDOWS_API) && !defined(WOLFSSH_ZEPHYR)
61126127
/* check if permissions attribute present */
6113-
if (atr->flags & WOLFSSH_FILEATRB_PERM) {
6128+
if (ret == WS_SUCCESS && (atr->flags & WOLFSSH_FILEATRB_PERM)) {
61146129
ret = SFTP_SetMode(ssh->fs, name, WOLFSSH_SFTP_SAFE_MODE(atr->per));
61156130
}
6116-
#endif
61176131

61186132
/* check if time attribute present */
61196133
if (ret == WS_SUCCESS && (atr->flags & WOLFSSH_FILEATRB_TIME)) {
6134+
#ifdef WSETTIME
61206135
if (WSETTIME(ssh->fs, name, atr->atime, atr->mtime) != 0) {
61216136
ret = WS_BAD_FILE_E;
61226137
}
6138+
#else
6139+
ret = WS_UNIMPLEMENTED_E;
6140+
#endif
61236141
}
61246142

61256143
/* check if extended attributes are present */
@@ -6143,29 +6161,52 @@ static int SFTP_SetFileAttributesHandle(WOLFSSH* ssh,
61436161
WS_SFTP_FILEATRB* atr)
61446162
{
61456163
int ret = WS_SUCCESS;
6164+
#ifdef WFTRUNCATE
6165+
word64 sz;
6166+
#endif
61466167

61476168
/* check if size attribute present */
6148-
if (atr->flags & WOLFSSH_FILEATRB_SIZE) {
6149-
/* @TODO set file size */
6169+
if (ret == WS_SUCCESS && (atr->flags & WOLFSSH_FILEATRB_SIZE)) {
6170+
#ifdef WFTRUNCATE
6171+
if (wResolveOffset(atr->sz, WOLFSSH_MAX_FILE_OFFSET, &sz) != 0
6172+
|| WFTRUNCATE(ssh->fs, handle, sz) != 0) {
6173+
ret = WS_BAD_FILE_E;
6174+
}
6175+
#else
6176+
ret = WS_UNIMPLEMENTED_E;
6177+
#endif
61506178
}
61516179

61526180
/* check if uid and gid attribute present */
6153-
if (atr->flags & WOLFSSH_FILEATRB_UIDGID) {
6154-
/* @TODO set group and user id */
6181+
if (ret == WS_SUCCESS && (atr->flags & WOLFSSH_FILEATRB_UIDGID)) {
6182+
#ifdef WFCHOWN
6183+
if (WFCHOWN(ssh->fs, handle, atr->uid, atr->gid) != 0) {
6184+
ret = WS_BAD_FILE_E;
6185+
}
6186+
#else
6187+
ret = WS_UNIMPLEMENTED_E;
6188+
#endif
61556189
}
61566190

6157-
#ifndef USE_WINDOWS_API
61586191
/* check if permissions attribute present */
6159-
if (atr->flags & WOLFSSH_FILEATRB_PERM) {
6160-
ret = SFTP_SetModeHandle(ssh->fs, handle, WOLFSSH_SFTP_SAFE_MODE(atr->per));
6161-
}
6192+
if (ret == WS_SUCCESS && (atr->flags & WOLFSSH_FILEATRB_PERM)) {
6193+
#ifndef USE_WINDOWS_API
6194+
ret = SFTP_SetModeHandle(ssh->fs, handle,
6195+
WOLFSSH_SFTP_SAFE_MODE(atr->per));
6196+
#else
6197+
ret = WS_UNIMPLEMENTED_E;
61626198
#endif
6199+
}
61636200

61646201
/* check if time attribute present */
61656202
if (ret == WS_SUCCESS && (atr->flags & WOLFSSH_FILEATRB_TIME)) {
6203+
#ifdef WFSETTIME
61666204
if (WFSETTIME(ssh->fs, handle, atr->atime, atr->mtime) != 0) {
61676205
ret = WS_BAD_FILE_E;
61686206
}
6207+
#else
6208+
ret = WS_UNIMPLEMENTED_E;
6209+
#endif
61696210
}
61706211

61716212
/* check if extended attributes are present */
@@ -6174,9 +6215,9 @@ static int SFTP_SetFileAttributesHandle(WOLFSSH* ssh,
61746215
}
61756216

61766217
(void)ssh;
6177-
#ifdef USE_WINDOWS_API
6178-
/* On Windows the only consumers (SFTP_SetModeHandle / WFSETTIME) are
6179-
* compiled out or no-ops, so the handle goes unused here. */
6218+
#if defined(USE_WINDOWS_API) && !defined(WFTRUNCATE) && !defined(WFCHOWN) \
6219+
&& !defined(WFSETTIME)
6220+
/* no consumer of the handle is compiled in on this port */
61806221
(void)handle;
61816222
#endif
61826223
return ret ;
@@ -6201,6 +6242,7 @@ int wolfSSH_SFTP_RecvSetSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
62016242
char ser[] = "Unable to set attributes error";
62026243
char per[] = "Unable to parse attributes error";
62036244
char pdn[] = "Permission denied";
6245+
char uns[] = "Attribute not supported";
62046246
char* res = suc;
62056247
byte type = WOLFSSH_FTP_OK;
62066248

@@ -6239,8 +6281,14 @@ int wolfSSH_SFTP_RecvSetSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
62396281
!= WS_SUCCESS) {
62406282
/* tell peer that was not ok */
62416283
WLOG(WS_LOG_SFTP, "Unable to get set attributes of file/directory");
6242-
type = WOLFSSH_FTP_FAILURE;
6243-
res = ser;
6284+
if (ret == WS_UNIMPLEMENTED_E) {
6285+
type = WOLFSSH_FTP_UNSUPPORTED;
6286+
res = uns;
6287+
}
6288+
else {
6289+
type = WOLFSSH_FTP_FAILURE;
6290+
res = ser;
6291+
}
62446292
ret = WS_BAD_FILE_E;
62456293
}
62466294

@@ -6276,6 +6324,7 @@ int wolfSSH_SFTP_RecvFSetSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
62766324
char suc[] = "Set Attributes";
62776325
char ser[] = "Unable to set attributes error";
62786326
char per[] = "Unable to parse attributes error";
6327+
char uns[] = "Attribute not supported";
62796328
char* res = suc;
62806329
byte type = WOLFSSH_FTP_OK;
62816330

@@ -6330,8 +6379,14 @@ int wolfSSH_SFTP_RecvFSetSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
63306379
!= WS_SUCCESS) {
63316380
/* tell peer that was not ok */
63326381
WLOG(WS_LOG_SFTP, "Unable to get set attributes of open file");
6333-
type = WOLFSSH_FTP_FAILURE;
6334-
res = ser;
6382+
if (ret == WS_UNIMPLEMENTED_E) {
6383+
type = WOLFSSH_FTP_UNSUPPORTED;
6384+
res = uns;
6385+
}
6386+
else {
6387+
type = WOLFSSH_FTP_FAILURE;
6388+
res = ser;
6389+
}
63356390
ret = WS_BAD_FILE_E;
63366391
}
63376392

@@ -7680,7 +7735,8 @@ int wolfSSH_SFTP_CHMOD(WOLFSSH* ssh, char* n, char* oct)
76807735
break;
76817736
}
76827737

7683-
/* update permissions */
7738+
/* only the permissions change here */
7739+
state->atr.flags = WOLFSSH_FILEATRB_PERM;
76847740
state->atr.per = mode;
76857741
state->state = STATE_CHMOD_SEND;
76867742
FALL_THROUGH;

tests/api.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4848,6 +4848,9 @@ static void test_wolfSSH_SFTP_PartialSend(void)
48484848
wolfSSH_SFTP_Close(ssh, handle, handleSz);
48494849

48504850
if (wolfSSH_SFTP_STAT(ssh, atrName, &atr) == WS_SUCCESS) {
4851+
/* Send only the permissions back. A port without WTRUNCATE
4852+
* answers a size request with SSH_FX_OP_UNSUPPORTED. */
4853+
atr.flags = WOLFSSH_FILEATRB_PERM;
48514854
AssertIntEQ(wolfSSH_TestSftpSendCap(ssh, 1), WS_SUCCESS);
48524855
ret = WS_FATAL_ERROR;
48534856
sawPartial = 0;

0 commit comments

Comments
 (0)