mirror of https://github.com/wolfSSL/wolfssh.git
remove accessing WS_SFTP_BUFFER directly
parent
bc6a51888c
commit
64d8d21209
512
src/wolfsftp.c
512
src/wolfsftp.c
|
@ -140,6 +140,8 @@ enum WS_SFTP_LSTAT_STATE_ID {
|
|||
STATE_LSTAT_CLEANUP
|
||||
};
|
||||
|
||||
/* This structure is to help with nonblocking and keeping track of state.
|
||||
* If adding any read/writes use the wolfSSH_SFTP_buffer_read/send functions */
|
||||
typedef struct WS_SFTP_BUFFER {
|
||||
byte* data;
|
||||
word32 sz;
|
||||
|
@ -405,6 +407,23 @@ static byte* wolfSSH_SFTP_buffer_data(WS_SFTP_BUFFER* buffer)
|
|||
}
|
||||
|
||||
|
||||
/* sets the size of internal buffer, can not set to larger size than internal
|
||||
* buffer (the buffer should be recreated in that case)
|
||||
* returns a negative value on fail, WS_SUCCESS on success
|
||||
*/
|
||||
static int wolfSSH_SFTP_buffer_set_size(WS_SFTP_BUFFER* buffer, word32 sz)
|
||||
{
|
||||
if (buffer == NULL || sz > buffer->sz) {
|
||||
WLOG(WS_LOG_SFTP, "Error setting size, buffer null or increase in sz");
|
||||
return WS_BAD_ARGUMENT;
|
||||
}
|
||||
|
||||
buffer->sz = sz;
|
||||
return WS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* returns the size of the buffer */
|
||||
static word32 wolfSSH_SFTP_buffer_size(WS_SFTP_BUFFER* buffer)
|
||||
{
|
||||
word32 ret = 0;
|
||||
|
@ -415,12 +434,83 @@ static word32 wolfSSH_SFTP_buffer_size(WS_SFTP_BUFFER* buffer)
|
|||
}
|
||||
|
||||
|
||||
/* sets the current idx into the buffer */
|
||||
static void wolfSSH_SFTP_buffer_seek(WS_SFTP_BUFFER* buffer,
|
||||
word32 start, word32 ofst)
|
||||
{
|
||||
if (buffer != NULL) {
|
||||
buffer->idx = start + ofst;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* c32toa function and advance idx */
|
||||
static void wolfSSH_SFTP_buffer_c32toa(WS_SFTP_BUFFER* buffer,
|
||||
word32 value)
|
||||
{
|
||||
if (buffer != NULL) {
|
||||
c32toa(value, buffer->data + buffer->idx);
|
||||
buffer->idx += UINT32_SZ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* returns WS_SUCCESS on success */
|
||||
static int wolfSSH_SFTP_buffer_ato32(WS_SFTP_BUFFER* buffer, word32* out)
|
||||
{
|
||||
if (buffer == NULL || out == NULL ||
|
||||
buffer->idx + UINT32_SZ > buffer->sz) {
|
||||
return WS_BAD_ARGUMENT;
|
||||
}
|
||||
ato32(buffer->data + buffer->idx, out);
|
||||
buffer->idx += UINT32_SZ;
|
||||
return WS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* getter function for current buffer idx */
|
||||
static word32 wolfSSH_SFTP_buffer_idx(WS_SFTP_BUFFER* buffer)
|
||||
{
|
||||
word32 ret = 0;
|
||||
if (buffer != NULL) {
|
||||
ret = buffer->idx;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* rewinds reading the buffer, resetting it idx value to 0 */
|
||||
static void wolfSSH_SFTP_buffer_rewind(WS_SFTP_BUFFER* buffer)
|
||||
{
|
||||
if (buffer != NULL)
|
||||
buffer->idx = 0;
|
||||
}
|
||||
|
||||
|
||||
/* try to send the rest of the buffer (buffer.sz - buffer.idx)
|
||||
* increments idx with amount sent */
|
||||
static int wolfSSH_SFTP_buffer_send(WOLFSSH* ssh, WS_SFTP_BUFFER* buffer)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (buffer == NULL) {
|
||||
return WS_BAD_ARGUMENT;
|
||||
}
|
||||
|
||||
if (buffer->idx > buffer->sz) {
|
||||
return WS_BUFFER_E;
|
||||
}
|
||||
|
||||
ret = wolfSSH_stream_send(ssh, buffer->data + buffer->idx,
|
||||
buffer->sz - buffer->idx);
|
||||
if (ret > 0) {
|
||||
buffer->idx += ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* returns the amount read on success */
|
||||
static int wolfSSH_SFTP_buffer_read(WOLFSSH* ssh, WS_SFTP_BUFFER* buffer,
|
||||
int readSz)
|
||||
|
@ -471,7 +561,8 @@ static void wolfSSH_SFTP_buffer_free(WOLFSSH* ssh, WS_SFTP_BUFFER* buffer)
|
|||
}
|
||||
|
||||
|
||||
/* return 0 on success, creates a new buffer if one does not already exist */
|
||||
/* return WS_SUCCESS on success, creates a new buffer if one does not already
|
||||
* exist */
|
||||
static int wolfSSH_SFTP_buffer_create(WOLFSSH* ssh, WS_SFTP_BUFFER* buffer,
|
||||
word32 sz)
|
||||
{
|
||||
|
@ -488,9 +579,10 @@ static int wolfSSH_SFTP_buffer_create(WOLFSSH* ssh, WS_SFTP_BUFFER* buffer,
|
|||
buffer->idx = 0;
|
||||
buffer->sz = sz;
|
||||
}
|
||||
return 0;
|
||||
return WS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Used to clear and free all states. Should be when returning errors or success
|
||||
* Must be called when free'ing the SFTP. For now static since only used in
|
||||
* wolfsftp.c
|
||||
|
@ -1155,7 +1247,8 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
|||
if (ret <= 0) {
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer, ret) != 0) {
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer, ret) !=
|
||||
WS_SUCCESS) {
|
||||
return WS_MEMORY_E;
|
||||
}
|
||||
ssh->reqId = state->reqId;
|
||||
|
@ -1282,15 +1375,24 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
|||
|
||||
if (maxSz > (int)wolfSSH_SFTP_buffer_size(&state->buffer)) {
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer,
|
||||
maxSz) != 0) {
|
||||
maxSz) != WS_SUCCESS) {
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RECV);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
maxSz = (int)wolfSSH_SFTP_buffer_size(&state->buffer);
|
||||
ret = wolfSSH_SFTP_CreateStatus(ssh, WOLFSSH_FTP_FAILURE,
|
||||
state->reqId,
|
||||
"Unknown/Unsupported packet type", "English",
|
||||
state->buffer.data, (word32*)&state->buffer.sz);
|
||||
wolfSSH_SFTP_buffer_data(&state->buffer),
|
||||
(word32*)(&maxSz));
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
ret = wolfSSH_SFTP_buffer_set_size(&state->buffer,
|
||||
(word32)maxSz);
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
/* set send out buffer, "state->data" is taken by ssh */
|
||||
wolfSSH_SFTP_RecvSetSend(ssh,
|
||||
|
@ -1314,9 +1416,7 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
|||
if (state->toSend) {
|
||||
do {
|
||||
if (state->toSend != 2) {
|
||||
ret = wolfSSH_stream_send(ssh, state->buffer.data +
|
||||
state->buffer.idx,
|
||||
state->buffer.sz - state->buffer.idx);
|
||||
ret = wolfSSH_SFTP_buffer_send(ssh, &state->buffer);
|
||||
if (ret < 0) {
|
||||
if (ssh->error != WS_WANT_READ &&
|
||||
ssh->error != WS_WANT_WRITE &&
|
||||
|
@ -1324,14 +1424,11 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
|||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RECV);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
/* check if there is more to be sent. This could be due to
|
||||
* limit on channel size when sending / receiving files */
|
||||
state->buffer.idx += ret;
|
||||
}
|
||||
state->toSend = 1;
|
||||
|
||||
if (state->buffer.idx < state->buffer.sz) {
|
||||
if (wolfSSH_SFTP_buffer_idx(&state->buffer)
|
||||
< wolfSSH_SFTP_buffer_size(&state->buffer)) {
|
||||
ret = wolfSSH_worker(ssh, NULL);
|
||||
if (ret != WS_SUCCESS && ssh->error == WS_WANT_READ) {
|
||||
/* was something there to read, try again */
|
||||
|
@ -1339,7 +1436,8 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
|||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
} while (state->buffer.idx < state->buffer.sz);
|
||||
} while (wolfSSH_SFTP_buffer_idx(&state->buffer)
|
||||
< wolfSSH_SFTP_buffer_size(&state->buffer));
|
||||
ret = WS_SUCCESS;
|
||||
state->toSend = 0;
|
||||
}
|
||||
|
@ -4688,22 +4786,27 @@ int SendPacketType(WOLFSSH* ssh, byte type, byte* buf, word32 bufSz)
|
|||
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer,
|
||||
bufSz + WOLFSSH_SFTP_HEADER + UINT32_SZ) != 0) {
|
||||
bufSz + WOLFSSH_SFTP_HEADER + UINT32_SZ) !=
|
||||
WS_SUCCESS) {
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_SEND);
|
||||
return WS_MEMORY_E;
|
||||
}
|
||||
|
||||
if (SFTP_SetHeader(ssh, ssh->reqId, type, bufSz + UINT32_SZ,
|
||||
state->buffer.data) != WS_SUCCESS) {
|
||||
wolfSSH_SFTP_buffer_data(&state->buffer))
|
||||
!= WS_SUCCESS) {
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_SEND);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
state->buffer.idx = WOLFSSH_SFTP_HEADER;
|
||||
c32toa(bufSz, state->buffer.data + state->buffer.idx);
|
||||
state->buffer.idx += UINT32_SZ;
|
||||
WMEMCPY(state->buffer.data + state->buffer.idx, buf, bufSz);
|
||||
state->buffer.idx = 0; /* reset state for sending data */
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer, 0,WOLFSSH_SFTP_HEADER);
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, bufSz);
|
||||
WMEMCPY(wolfSSH_SFTP_buffer_data(&state->buffer)
|
||||
+ wolfSSH_SFTP_buffer_idx(&state->buffer),
|
||||
buf, bufSz);
|
||||
|
||||
/* reset state for sending data */
|
||||
wolfSSH_SFTP_buffer_rewind(&state->buffer);
|
||||
}
|
||||
state->state = SFTP_SEND_PACKET;
|
||||
FALL_THROUGH;
|
||||
|
@ -4715,17 +4818,16 @@ int SendPacketType(WOLFSSH* ssh, byte type, byte* buf, word32 bufSz)
|
|||
* state->data can be sent at one time */
|
||||
do {
|
||||
int err;
|
||||
ret = wolfSSH_stream_send(ssh, state->buffer.data +
|
||||
state->buffer.idx, state->buffer.sz - state->buffer.idx);
|
||||
ret = wolfSSH_SFTP_buffer_send(ssh, &state->buffer);
|
||||
|
||||
/* check for adjust window packet */
|
||||
err = wolfSSH_get_error(ssh);
|
||||
if (err == WS_WINDOW_FULL)
|
||||
ret = wolfSSH_worker(ssh, NULL);
|
||||
ssh->error = err; /* don't save potential want read here */
|
||||
if (ret > 0)
|
||||
state->buffer.idx += (word32)ret;
|
||||
} while (ret > 0 && state->buffer.idx < state->buffer.sz);
|
||||
} while (ret > 0 &&
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer) <
|
||||
wolfSSH_SFTP_buffer_size(&state->buffer));
|
||||
|
||||
if (ret > 0) {
|
||||
ret = WS_SUCCESS;
|
||||
|
@ -4760,9 +4862,9 @@ static int wolfSSH_SFTP_DoStatus(WOLFSSH* ssh, word32 reqId,
|
|||
{
|
||||
word32 sz;
|
||||
word32 status = WOLFSSH_FTP_FAILURE;
|
||||
word32 localIdx = buffer->idx;
|
||||
word32 maxIdx = buffer->sz;
|
||||
byte* buf = buffer->data;
|
||||
word32 localIdx = wolfSSH_SFTP_buffer_idx(buffer);
|
||||
word32 maxIdx = wolfSSH_SFTP_buffer_size(buffer);
|
||||
byte* buf = wolfSSH_SFTP_buffer_data(buffer);
|
||||
|
||||
(void)reqId;
|
||||
if (localIdx + UINT32_SZ > maxIdx) {
|
||||
|
@ -4823,7 +4925,7 @@ static int wolfSSH_SFTP_DoStatus(WOLFSSH* ssh, word32 reqId,
|
|||
localIdx += sz;
|
||||
}
|
||||
|
||||
buffer->idx = localIdx;
|
||||
wolfSSH_SFTP_buffer_seek(buffer, 0, localIdx);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -5109,7 +5211,7 @@ static WS_SFTPNAME* wolfSSH_SFTP_DoName(WOLFSSH* ssh)
|
|||
WS_SFTP_NAME_STATE* state = NULL;
|
||||
WS_SFTPNAME* n = NULL;
|
||||
int maxSz;
|
||||
word32 count;
|
||||
word32 count, localIdx;
|
||||
word32 reqId = 0;
|
||||
byte type = WOLFSSH_FTP_STATUS;
|
||||
int ret;
|
||||
|
@ -5158,7 +5260,8 @@ static WS_SFTPNAME* wolfSSH_SFTP_DoName(WOLFSSH* ssh)
|
|||
state->state = SFTP_NAME_GET_PACKET;
|
||||
}
|
||||
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer, maxSz) != 0) {
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer, maxSz) !=
|
||||
WS_SUCCESS) {
|
||||
WLOG(WS_LOG_SFTP, "Could not malloc memory");
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_NAME);
|
||||
return NULL;
|
||||
|
@ -5189,7 +5292,8 @@ static WS_SFTPNAME* wolfSSH_SFTP_DoName(WOLFSSH* ssh)
|
|||
/* get number of files */
|
||||
/* using idx as an offset for partial reads */
|
||||
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
|
||||
state->buffer.sz - state->buffer.idx);
|
||||
wolfSSH_SFTP_buffer_size(&state->buffer) -
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer));
|
||||
if (ret <= 0) {
|
||||
if (ssh->error != WS_WANT_READ) {
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_NAME);
|
||||
|
@ -5199,12 +5303,13 @@ static WS_SFTPNAME* wolfSSH_SFTP_DoName(WOLFSSH* ssh)
|
|||
|
||||
/* Reset idx back to 0 for parsing the buffer. */
|
||||
wolfSSH_SFTP_buffer_rewind(&state->buffer);
|
||||
if (state->buffer.idx + UINT32_SZ > state->buffer.sz) {
|
||||
if (wolfSSH_SFTP_buffer_ato32(&state->buffer, &count) !=
|
||||
WS_SUCCESS) {
|
||||
ssh->error = WS_BUFFER_E;
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_NAME);
|
||||
return NULL;
|
||||
}
|
||||
ato32(state->buffer.data, &count); state->buffer.idx += UINT32_SZ;
|
||||
|
||||
while (count > 0) {
|
||||
word32 sz;
|
||||
WS_SFTPNAME* tmp = wolfSSH_SFTPNAME_new(ssh->ctx->heap);
|
||||
|
@ -5222,12 +5327,11 @@ static WS_SFTPNAME* wolfSSH_SFTP_DoName(WOLFSSH* ssh)
|
|||
n = tmp;
|
||||
|
||||
/* get filename size and name */
|
||||
if (state->buffer.idx + UINT32_SZ > state->buffer.sz) {
|
||||
if (wolfSSH_SFTP_buffer_ato32(&state->buffer, &sz) !=
|
||||
WS_SUCCESS) {
|
||||
ret = WS_BUFFER_E;
|
||||
break;
|
||||
}
|
||||
ato32(state->buffer.data + state->buffer.idx, &sz);
|
||||
state->buffer.idx += UINT32_SZ;
|
||||
tmp->fSz = sz;
|
||||
if (sz > 0) {
|
||||
tmp->fName = (char*)WMALLOC(sz + 1, tmp->heap, DYNTYPE_SFTP);
|
||||
|
@ -5236,23 +5340,26 @@ static WS_SFTPNAME* wolfSSH_SFTP_DoName(WOLFSSH* ssh)
|
|||
break;
|
||||
}
|
||||
|
||||
if (state->buffer.idx + sz > state->buffer.sz) {
|
||||
if (wolfSSH_SFTP_buffer_idx(&state->buffer) + sz >
|
||||
wolfSSH_SFTP_buffer_size(&state->buffer)) {
|
||||
ret = WS_FATAL_ERROR;
|
||||
break;
|
||||
}
|
||||
WMEMCPY(tmp->fName, state->buffer.data + state->buffer.idx,
|
||||
WMEMCPY(tmp->fName,
|
||||
wolfSSH_SFTP_buffer_data(&state->buffer) +
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer),
|
||||
sz);
|
||||
state->buffer.idx += sz;
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer,
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer), sz);
|
||||
tmp->fName[sz] = '\0';
|
||||
}
|
||||
|
||||
/* get longname size and name */
|
||||
if (state->buffer.idx + UINT32_SZ > state->buffer.sz) {
|
||||
if (wolfSSH_SFTP_buffer_ato32(&state->buffer, &sz) !=
|
||||
WS_SUCCESS) {
|
||||
ret = WS_BUFFER_E;
|
||||
break;
|
||||
}
|
||||
ato32(state->buffer.data + state->buffer.idx, &sz);
|
||||
state->buffer.idx += UINT32_SZ;
|
||||
tmp->lSz = sz;
|
||||
if (sz > 0) {
|
||||
tmp->lName = (char*)WMALLOC(sz + 1,
|
||||
|
@ -5262,20 +5369,27 @@ static WS_SFTPNAME* wolfSSH_SFTP_DoName(WOLFSSH* ssh)
|
|||
break;
|
||||
}
|
||||
|
||||
if (state->buffer.idx + sz > state->buffer.sz) {
|
||||
if (wolfSSH_SFTP_buffer_idx(&state->buffer) + sz >
|
||||
wolfSSH_SFTP_buffer_size(&state->buffer)) {
|
||||
ret = WS_FATAL_ERROR;
|
||||
break;
|
||||
}
|
||||
WMEMCPY(tmp->lName, state->buffer.data + state->buffer.idx,
|
||||
WMEMCPY(tmp->lName,
|
||||
wolfSSH_SFTP_buffer_data(&state->buffer) +
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer),
|
||||
sz);
|
||||
state->buffer.idx += sz;
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer,
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer), sz);
|
||||
tmp->lName[sz] = '\0';
|
||||
}
|
||||
|
||||
/* get attributes */
|
||||
localIdx = wolfSSH_SFTP_buffer_idx(&state->buffer);
|
||||
ret = SFTP_ParseAtributes_buffer(ssh, &tmp->atrb,
|
||||
state->buffer.data, &state->buffer.idx,
|
||||
state->buffer.sz);
|
||||
wolfSSH_SFTP_buffer_data(&state->buffer),
|
||||
&localIdx,
|
||||
wolfSSH_SFTP_buffer_size(&state->buffer));
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer, 0, localIdx);
|
||||
if (ret != WS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
@ -5311,6 +5425,7 @@ static int wolfSSH_SFTP_GetHandle(WOLFSSH* ssh, byte* handle, word32* handleSz)
|
|||
byte* data = NULL;
|
||||
int ret = WS_SUCCESS;
|
||||
byte type = 0;
|
||||
word32 sz;
|
||||
|
||||
WLOG(WS_LOG_SFTP, "Entering wolfSSH_SFTP_GetHandle");
|
||||
|
||||
|
@ -5351,7 +5466,8 @@ static int wolfSSH_SFTP_GetHandle(WOLFSSH* ssh, byte* handle, word32* handleSz)
|
|||
}
|
||||
}
|
||||
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer, ret) != 0) {
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer, ret) !=
|
||||
WS_SUCCESS) {
|
||||
state->state = STATE_GET_HANDLE_CLEANUP;
|
||||
ret = WS_MEMORY_E;
|
||||
continue;
|
||||
|
@ -5374,7 +5490,7 @@ static int wolfSSH_SFTP_GetHandle(WOLFSSH* ssh, byte* handle, word32* handleSz)
|
|||
WLOG(WS_LOG_SFTP, "SFTP GET HANDLE STATE: DO_STATUS");
|
||||
|
||||
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
|
||||
state->buffer.sz);
|
||||
wolfSSH_SFTP_buffer_size(&state->buffer));
|
||||
if (ret < 0) {
|
||||
WFREE(data, ssh->ctx->heap, DYNTYPE_BUFFER);
|
||||
return WS_FATAL_ERROR;
|
||||
|
@ -5408,17 +5524,17 @@ static int wolfSSH_SFTP_GetHandle(WOLFSSH* ssh, byte* handle, word32* handleSz)
|
|||
case STATE_GET_HANDLE_READ:
|
||||
WLOG(WS_LOG_SFTP, "SFTP GET HANDLE STATE: READ");
|
||||
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
|
||||
state->buffer.sz);
|
||||
if (ret != (int)state->buffer.sz) {
|
||||
wolfSSH_SFTP_buffer_size(&state->buffer));
|
||||
if (ret != (int)wolfSSH_SFTP_buffer_size(&state->buffer)) {
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
ret = WS_SUCCESS;
|
||||
|
||||
/* RFC specifies that handle size should not be larger than
|
||||
* max size */
|
||||
ato32(state->buffer.data, &state->buffer.sz);
|
||||
if (state->buffer.sz > WOLFSSH_MAX_HANDLE ||
|
||||
*handleSz < state->buffer.sz) {
|
||||
wolfSSH_SFTP_buffer_rewind(&state->buffer);
|
||||
if (wolfSSH_SFTP_buffer_ato32(&state->buffer, &sz) != WS_SUCCESS
|
||||
|| sz > WOLFSSH_MAX_HANDLE || *handleSz < sz) {
|
||||
WLOG(WS_LOG_SFTP, "Handle size found was too big");
|
||||
WLOG(WS_LOG_SFTP, "Check size set in input handleSz");
|
||||
ssh->error = WS_BUFFER_E;
|
||||
|
@ -5426,8 +5542,10 @@ static int wolfSSH_SFTP_GetHandle(WOLFSSH* ssh, byte* handle, word32* handleSz)
|
|||
state->state = STATE_GET_HANDLE_CLEANUP;
|
||||
continue;
|
||||
}
|
||||
*handleSz = state->buffer.sz;
|
||||
WMEMCPY(handle, (state->buffer.data + UINT32_SZ), *handleSz);
|
||||
*handleSz = sz;
|
||||
WMEMCPY(handle,
|
||||
(wolfSSH_SFTP_buffer_data(&state->buffer) + UINT32_SZ),
|
||||
*handleSz);
|
||||
state->state = STATE_GET_HANDLE_CLEANUP;
|
||||
FALL_THROUGH;
|
||||
|
||||
|
@ -5632,6 +5750,7 @@ static int SFTP_STAT(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr, byte type)
|
|||
{
|
||||
WS_SFTP_LSTAT_STATE* state = NULL;
|
||||
int ret;
|
||||
word32 localIdx;
|
||||
|
||||
WLOG(WS_LOG_SFTP, "Entering SFTP_STAT()");
|
||||
if (ssh == NULL || dir == NULL)
|
||||
|
@ -5695,7 +5814,8 @@ static int SFTP_STAT(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr, byte type)
|
|||
}
|
||||
|
||||
state->state = STATE_LSTAT_CHECK_REQ_ID;
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer, ret) != 0) {
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer, ret) !=
|
||||
WS_SUCCESS) {
|
||||
ssh->error = WS_MEMORY_E;
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
|
@ -5715,7 +5835,7 @@ static int SFTP_STAT(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr, byte type)
|
|||
|
||||
case STATE_LSTAT_PARSE_REPLY:
|
||||
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
|
||||
state->buffer.sz);
|
||||
wolfSSH_SFTP_buffer_size(&state->buffer));
|
||||
if (ret < 0) {
|
||||
if (ssh->error != WS_WANT_READ) {
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_LSTAT);
|
||||
|
@ -5724,9 +5844,11 @@ static int SFTP_STAT(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr, byte type)
|
|||
}
|
||||
WLOG(WS_LOG_SFTP, "SFTP LSTAT STATE: PARSE_REPLY");
|
||||
if (state->type == WOLFSSH_FTP_ATTRS) {
|
||||
localIdx = wolfSSH_SFTP_buffer_idx(&state->buffer);
|
||||
ret = SFTP_ParseAtributes_buffer(ssh, atr,
|
||||
state->buffer.data, &state->buffer.idx,
|
||||
state->buffer.sz);
|
||||
wolfSSH_SFTP_buffer_data(&state->buffer),
|
||||
&localIdx,
|
||||
wolfSSH_SFTP_buffer_size(&state->buffer));
|
||||
if (ret != WS_SUCCESS) {
|
||||
if (ssh->error == WS_WANT_READ ||
|
||||
ssh->error == WS_WANT_WRITE)
|
||||
|
@ -5812,7 +5934,6 @@ int wolfSSH_SFTP_SetSTAT(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr)
|
|||
struct WS_SFTP_SETATR_STATE* state = NULL;
|
||||
int dirSz, atrSz, status;
|
||||
int maxSz, ret = WS_FATAL_ERROR;
|
||||
word32 idx;
|
||||
byte type;
|
||||
|
||||
WLOG(WS_LOG_SFTP, "Entering wolfSSH_SFTP_SetSTAT()");
|
||||
|
@ -5839,34 +5960,46 @@ int wolfSSH_SFTP_SetSTAT(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr)
|
|||
dirSz = (int)WSTRLEN(dir);
|
||||
atrSz = SFTP_AtributesSz(ssh, atr);
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer,
|
||||
dirSz + atrSz + WOLFSSH_SFTP_HEADER + UINT32_SZ) != 0) {
|
||||
dirSz + atrSz + WOLFSSH_SFTP_HEADER + UINT32_SZ) !=
|
||||
WS_SUCCESS) {
|
||||
ret = WS_MEMORY_E;
|
||||
break;
|
||||
}
|
||||
|
||||
if (SFTP_SetHeader(ssh, ssh->reqId, WOLFSSH_FTP_SETSTAT, dirSz +
|
||||
atrSz + UINT32_SZ, state->buffer.data) != WS_SUCCESS) {
|
||||
atrSz + UINT32_SZ,
|
||||
wolfSSH_SFTP_buffer_data(&state->buffer)) !=
|
||||
WS_SUCCESS) {
|
||||
ret = WS_FATAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
idx = WOLFSSH_SFTP_HEADER;
|
||||
c32toa(dirSz, state->buffer.data + idx);
|
||||
idx += UINT32_SZ;
|
||||
WMEMCPY(state->buffer.data + idx, (byte*)dir, dirSz);
|
||||
idx += dirSz;
|
||||
SFTP_SetAttributes(ssh, state->buffer.data + idx, atrSz, atr);
|
||||
idx += atrSz;
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer, 0, WOLFSSH_SFTP_HEADER);
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, dirSz);
|
||||
WMEMCPY(wolfSSH_SFTP_buffer_data(&state->buffer) +
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer),
|
||||
(byte*)dir, dirSz);
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer,
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer), dirSz);
|
||||
|
||||
state->buffer.sz = idx;
|
||||
SFTP_SetAttributes(ssh,
|
||||
wolfSSH_SFTP_buffer_data(&state->buffer) +
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer), atrSz, atr);
|
||||
ret = wolfSSH_SFTP_buffer_set_size(&state->buffer,
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer) + atrSz);
|
||||
if (ret != WS_SUCCESS) {
|
||||
ret = WS_FATAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
wolfSSH_SFTP_buffer_rewind(&state->buffer);
|
||||
state->state = STATE_SET_ATR_SEND;
|
||||
FALL_THROUGH;
|
||||
/* no break */
|
||||
|
||||
/* send header and type specific data */
|
||||
case STATE_SET_ATR_SEND:
|
||||
if (wolfSSH_stream_send(ssh, state->buffer.data,
|
||||
state->buffer.sz) < 0) {
|
||||
if (wolfSSH_SFTP_buffer_send(ssh, &state->buffer) < 0) {
|
||||
if (ssh->error != WS_WANT_READ && ssh->error != WS_WANT_WRITE) {
|
||||
ret = WS_FATAL_ERROR;
|
||||
break;
|
||||
|
@ -5895,7 +6028,8 @@ int wolfSSH_SFTP_SetSTAT(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr)
|
|||
break;
|
||||
}
|
||||
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer, maxSz) != 0) {
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer, maxSz) !=
|
||||
WS_SUCCESS) {
|
||||
ret = WS_MEMORY_E;
|
||||
break;
|
||||
}
|
||||
|
@ -5906,7 +6040,8 @@ int wolfSSH_SFTP_SetSTAT(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr)
|
|||
|
||||
|
||||
case STATE_SET_ATR_STATUS:
|
||||
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer, state->buffer.sz);
|
||||
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
|
||||
wolfSSH_SFTP_buffer_size(&state->buffer));
|
||||
if (ret < 0) {
|
||||
if (ssh->error != WS_WANT_READ && ssh->error != WS_WANT_WRITE) {
|
||||
ret = WS_FATAL_ERROR;
|
||||
|
@ -5977,7 +6112,8 @@ int wolfSSH_SFTP_Open(WOLFSSH* ssh, char* dir, word32 reason,
|
|||
WLOG(WS_LOG_SFTP, "SFTP OPEN STATE: INIT");
|
||||
sz = (int)WSTRLEN(dir);
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer, sz +
|
||||
WOLFSSH_SFTP_HEADER + UINT32_SZ * 3) != 0) {
|
||||
WOLFSSH_SFTP_HEADER + UINT32_SZ * 3) !=
|
||||
WS_SUCCESS) {
|
||||
ssh->error = WS_MEMORY_E;
|
||||
ret = WS_FATAL_ERROR;
|
||||
state->state = STATE_OPEN_CLEANUP;
|
||||
|
@ -5985,24 +6121,33 @@ int wolfSSH_SFTP_Open(WOLFSSH* ssh, char* dir, word32 reason,
|
|||
}
|
||||
|
||||
ret = SFTP_SetHeader(ssh, ssh->reqId, WOLFSSH_FTP_OPEN,
|
||||
sz + UINT32_SZ * 3, state->buffer.data);
|
||||
sz + UINT32_SZ * 3,
|
||||
wolfSSH_SFTP_buffer_data(&state->buffer));
|
||||
if (ret != WS_SUCCESS) {
|
||||
state->state = STATE_OPEN_CLEANUP;
|
||||
continue;
|
||||
}
|
||||
|
||||
state->buffer.idx = WOLFSSH_SFTP_HEADER;
|
||||
c32toa(sz, state->buffer.data + state->buffer.idx);
|
||||
state->buffer.idx += UINT32_SZ;
|
||||
WMEMCPY(state->buffer.data + state->buffer.idx, (byte*)dir, sz);
|
||||
state->buffer.idx += sz;
|
||||
c32toa(reason, state->buffer.data + state->buffer.idx);
|
||||
state->buffer.idx += UINT32_SZ;
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer, 0,
|
||||
WOLFSSH_SFTP_HEADER);
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, sz);
|
||||
WMEMCPY(wolfSSH_SFTP_buffer_data(&state->buffer) +
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer),
|
||||
(byte*)dir, sz);
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer,
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer), sz);
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, reason);
|
||||
|
||||
/* @TODO handle adding attributes here */
|
||||
(void)atr;
|
||||
c32toa(0x00000000, state->buffer.data + state->buffer.idx);
|
||||
state->buffer.idx += UINT32_SZ;
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, 0x00000000);
|
||||
ret = wolfSSH_SFTP_buffer_set_size(&state->buffer,
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer));
|
||||
if (ret != WS_SUCCESS) {
|
||||
state->state = STATE_OPEN_CLEANUP;
|
||||
continue;
|
||||
}
|
||||
wolfSSH_SFTP_buffer_rewind(&state->buffer);
|
||||
|
||||
state->state = STATE_OPEN_SEND;
|
||||
FALL_THROUGH;
|
||||
|
@ -6010,8 +6155,7 @@ int wolfSSH_SFTP_Open(WOLFSSH* ssh, char* dir, word32 reason,
|
|||
case STATE_OPEN_SEND:
|
||||
WLOG(WS_LOG_SFTP, "SFTP OPEN STATE: SEND");
|
||||
/* send header and type specific data */
|
||||
ret = wolfSSH_stream_send(ssh, state->buffer.data,
|
||||
state->buffer.idx);
|
||||
ret = wolfSSH_SFTP_buffer_send(ssh, &state->buffer);
|
||||
if (ret < 0) {
|
||||
if (ssh->error == WS_WANT_READ ||
|
||||
ssh->error == WS_WANT_WRITE)
|
||||
|
@ -6102,7 +6246,8 @@ int wolfSSH_SFTP_SendWritePacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
WLOG(WS_LOG_SFTP, "SFTP SEND_WRITE STATE: INIT");
|
||||
state->sentSz = 0;
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer,
|
||||
handleSz + WOLFSSH_SFTP_HEADER + UINT32_SZ * 4) != 0) {
|
||||
handleSz + WOLFSSH_SFTP_HEADER + UINT32_SZ * 4) !=
|
||||
WS_SUCCESS) {
|
||||
ssh->error = WS_MEMORY_E;
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
|
@ -6114,22 +6259,28 @@ int wolfSSH_SFTP_SendWritePacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
continue;
|
||||
}
|
||||
|
||||
state->buffer.idx = WOLFSSH_SFTP_HEADER;
|
||||
c32toa(handleSz, state->buffer.data + state->buffer.idx);
|
||||
state->buffer.idx += UINT32_SZ;
|
||||
WMEMCPY(state->buffer.data + state->buffer.idx, (byte*)handle,
|
||||
handleSz);
|
||||
state->buffer.idx += handleSz;
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer, 0,
|
||||
WOLFSSH_SFTP_HEADER);
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, handleSz);
|
||||
WMEMCPY(wolfSSH_SFTP_buffer_data(&state->buffer) +
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer),
|
||||
(byte*)handle, handleSz);
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer,
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer), handleSz);
|
||||
|
||||
/* offset to start reading from */
|
||||
c32toa(ofst[1], state->buffer.data + state->buffer.idx);
|
||||
state->buffer.idx += UINT32_SZ;
|
||||
c32toa(ofst[0], state->buffer.data + state->buffer.idx);
|
||||
state->buffer.idx += UINT32_SZ;
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, ofst[1]);
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, ofst[0]);
|
||||
|
||||
/* buffer.data to be written */
|
||||
c32toa(inSz, state->buffer.data + state->buffer.idx);
|
||||
state->buffer.idx += UINT32_SZ;
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, inSz);
|
||||
ret = wolfSSH_SFTP_buffer_set_size(&state->buffer,
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer));
|
||||
if (ret != WS_SUCCESS) {
|
||||
state->state = STATE_SEND_WRITE_CLEANUP;
|
||||
continue;
|
||||
}
|
||||
wolfSSH_SFTP_buffer_rewind(&state->buffer);
|
||||
|
||||
state->state = STATE_SEND_WRITE_SEND_HEADER;
|
||||
FALL_THROUGH;
|
||||
|
@ -6137,8 +6288,7 @@ int wolfSSH_SFTP_SendWritePacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
case STATE_SEND_WRITE_SEND_HEADER:
|
||||
WLOG(WS_LOG_SFTP, "SFTP SEND_WRITE STATE: SEND_HEADER");
|
||||
/* send header and type specific data */
|
||||
ret = wolfSSH_stream_send(ssh, state->buffer.data,
|
||||
state->buffer.idx);
|
||||
ret = wolfSSH_SFTP_buffer_send(ssh, &state->buffer);
|
||||
if (ret < 0) {
|
||||
if (ssh->error == WS_WANT_READ ||
|
||||
ssh->error == WS_WANT_WRITE) {
|
||||
|
@ -6201,7 +6351,7 @@ int wolfSSH_SFTP_SendWritePacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
}
|
||||
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer,
|
||||
state->maxSz) != 0) {
|
||||
state->maxSz) != WS_SUCCESS) {
|
||||
ssh->error = WS_MEMORY_E;
|
||||
ret = WS_FATAL_ERROR;
|
||||
state->state = STATE_SEND_WRITE_CLEANUP;
|
||||
|
@ -6279,6 +6429,7 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
WS_SFTP_SEND_READ_STATE* state = NULL;
|
||||
byte szFlat[UINT32_SZ];
|
||||
int ret = WS_SUCCESS;
|
||||
word32 sz;
|
||||
|
||||
WLOG(WS_LOG_SFTP, "Entering wolfSSH_SFTP_SendReadPacket()");
|
||||
if (ssh == NULL || handle == NULL || out == NULL)
|
||||
|
@ -6304,35 +6455,42 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
case STATE_SEND_READ_INIT:
|
||||
WLOG(WS_LOG_SFTP, "SFTP SEND_READ STATE: INIT");
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer,
|
||||
handleSz + WOLFSSH_SFTP_HEADER + UINT32_SZ * 4) != 0) {
|
||||
handleSz + WOLFSSH_SFTP_HEADER + UINT32_SZ * 4) !=
|
||||
WS_SUCCESS) {
|
||||
ssh->error = WS_MEMORY_E;
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
ret = SFTP_SetHeader(ssh, ssh->reqId, WOLFSSH_FTP_READ,
|
||||
handleSz + UINT32_SZ * 4, state->buffer.data);
|
||||
handleSz + UINT32_SZ * 4,
|
||||
wolfSSH_SFTP_buffer_data(&state->buffer));
|
||||
if (ret != WS_SUCCESS) {
|
||||
state->state = STATE_SEND_READ_CLEANUP;
|
||||
continue;
|
||||
}
|
||||
|
||||
state->buffer.idx = WOLFSSH_SFTP_HEADER;
|
||||
c32toa(handleSz, state->buffer.data + state->buffer.idx);
|
||||
state->buffer.idx += UINT32_SZ;
|
||||
|
||||
WMEMCPY(state->buffer.data + state->buffer.idx, (byte*)handle,
|
||||
handleSz);
|
||||
state->buffer.idx += handleSz;
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer, 0,
|
||||
WOLFSSH_SFTP_HEADER);
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, handleSz);
|
||||
WMEMCPY(wolfSSH_SFTP_buffer_data(&state->buffer) +
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer),
|
||||
(byte*)handle, handleSz);
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer,
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer), handleSz);
|
||||
|
||||
/* offset to start reading from */
|
||||
c32toa(ofst[1], state->buffer.data + state->buffer.idx);
|
||||
state->buffer.idx += UINT32_SZ;
|
||||
c32toa(ofst[0], state->buffer.data + state->buffer.idx);
|
||||
state->buffer.idx += UINT32_SZ;
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, ofst[1]);
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, ofst[0]);
|
||||
|
||||
/* max length to read */
|
||||
c32toa(outSz, state->buffer.data + state->buffer.idx);
|
||||
state->buffer.idx += UINT32_SZ;
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, outSz);
|
||||
ret = wolfSSH_SFTP_buffer_set_size(&state->buffer,
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer));
|
||||
if (ret != WS_SUCCESS) {
|
||||
state->state = STATE_SEND_READ_CLEANUP;
|
||||
continue;
|
||||
}
|
||||
wolfSSH_SFTP_buffer_rewind(&state->buffer);
|
||||
|
||||
state->state = STATE_SEND_READ_SEND_REQ;
|
||||
|
||||
|
@ -6341,8 +6499,7 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
case STATE_SEND_READ_SEND_REQ:
|
||||
WLOG(WS_LOG_SFTP, "SFTP SEND_READ STATE: SEND_REQ");
|
||||
/* send header and type specific data */
|
||||
ret = wolfSSH_stream_send(ssh, state->buffer.data,
|
||||
state->buffer.idx);
|
||||
ret = wolfSSH_SFTP_buffer_send(ssh, &state->buffer);
|
||||
if (ret < 0) {
|
||||
if (ssh->error != WS_WANT_READ &&
|
||||
ssh->error != WS_WANT_WRITE) {
|
||||
|
@ -6368,7 +6525,11 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
return WS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
state->buffer.sz = ret;
|
||||
ret = wolfSSH_SFTP_buffer_create(ssh, &state->buffer, ret);
|
||||
if (ret != WS_SUCCESS) {
|
||||
state->state = STATE_SEND_READ_CLEANUP;
|
||||
continue;
|
||||
}
|
||||
state->state = STATE_SEND_READ_CHECK_REQ_ID;
|
||||
FALL_THROUGH;
|
||||
|
||||
|
@ -6407,8 +6568,9 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
ato32(szFlat, &state->buffer.sz);
|
||||
if (state->buffer.sz > outSz) {
|
||||
ato32(szFlat, &sz);
|
||||
wolfSSH_SFTP_buffer_create(ssh, &state->buffer, sz);
|
||||
if (wolfSSH_SFTP_buffer_size(&state->buffer) > outSz) {
|
||||
WLOG(WS_LOG_SFTP, "Server sent more data then expected");
|
||||
ret = WS_FATAL_ERROR;
|
||||
state->state = STATE_SEND_READ_CLEANUP;
|
||||
|
@ -6422,7 +6584,8 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
WLOG(WS_LOG_SFTP, "SFTP SEND_READ STATE: READ_REMAINDER");
|
||||
do {
|
||||
ret = wolfSSH_stream_read(ssh,
|
||||
out + state->recvSz, state->buffer.sz);
|
||||
out + state->recvSz,
|
||||
wolfSSH_SFTP_buffer_size(&state->buffer));
|
||||
if (ret < 0) {
|
||||
if (ssh->error == WS_WANT_READ ||
|
||||
ssh->error == WS_WANT_WRITE) {
|
||||
|
@ -6434,8 +6597,9 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
}
|
||||
|
||||
state->recvSz += ret;
|
||||
state->buffer.sz -= ret;
|
||||
} while (state->buffer.sz != 0);
|
||||
wolfSSH_SFTP_buffer_set_size(&state->buffer,
|
||||
wolfSSH_SFTP_buffer_size(&state->buffer) - ret);
|
||||
} while (wolfSSH_SFTP_buffer_size(&state->buffer) != 0);
|
||||
|
||||
ret = state->recvSz;
|
||||
|
||||
|
@ -6446,14 +6610,15 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
WLOG(WS_LOG_SFTP, "SFTP SEND_READ STATE: READ_FTP_STATUS");
|
||||
{
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer,
|
||||
state->buffer.sz) != 0) {
|
||||
wolfSSH_SFTP_buffer_size(&state->buffer))
|
||||
!= 0) {
|
||||
ret = WS_MEMORY_E;
|
||||
state->state = STATE_SEND_READ_CLEANUP;
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
|
||||
state->buffer.sz);
|
||||
wolfSSH_SFTP_buffer_size(&state->buffer));
|
||||
if (ret < 0) {
|
||||
if (ssh->error != WS_WANT_READ &&
|
||||
ssh->error != WS_WANT_WRITE) {
|
||||
|
@ -6505,7 +6670,6 @@ int wolfSSH_SFTP_MKDIR(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr)
|
|||
struct WS_SFTP_MKDIR_STATE* state;
|
||||
int ret;
|
||||
byte type;
|
||||
word32 idx;
|
||||
|
||||
WLOG(WS_LOG_SFTP, "Sending WOLFSSH_FTP_MKDIR");
|
||||
if (ssh == NULL || dir == NULL) {
|
||||
|
@ -6527,7 +6691,8 @@ int wolfSSH_SFTP_MKDIR(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr)
|
|||
|
||||
switch (state->state) {
|
||||
case STATE_MKDIR_SEND:
|
||||
if (state->buffer.sz == 0) { /* packet not created yet */
|
||||
if (wolfSSH_SFTP_buffer_size(&state->buffer) == 0) {
|
||||
/* packet not created yet */
|
||||
int sz = (int)WSTRLEN(dir);
|
||||
if (wolfSSH_SFTP_buffer_create(ssh, &state->buffer, sz +
|
||||
WOLFSSH_SFTP_HEADER + UINT32_SZ * 3) != 0) {
|
||||
|
@ -6535,28 +6700,37 @@ int wolfSSH_SFTP_MKDIR(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr)
|
|||
}
|
||||
|
||||
if (SFTP_SetHeader(ssh, ssh->reqId, WOLFSSH_FTP_MKDIR,
|
||||
sz + UINT32_SZ * 3, state->buffer.data) != WS_SUCCESS) {
|
||||
sz + UINT32_SZ * 3,
|
||||
wolfSSH_SFTP_buffer_data(&state->buffer)) != WS_SUCCESS) {
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
idx = WOLFSSH_SFTP_HEADER;
|
||||
c32toa(sz, state->buffer.data + idx);
|
||||
idx += UINT32_SZ;
|
||||
WMEMCPY(state->buffer.data + idx, (byte*)dir, sz);
|
||||
idx += sz;
|
||||
c32toa(UINT32_SZ, state->buffer.data + idx);
|
||||
idx += UINT32_SZ;
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer, 0,
|
||||
WOLFSSH_SFTP_HEADER);
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, sz);
|
||||
WMEMCPY(wolfSSH_SFTP_buffer_data(&state->buffer) +
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer),
|
||||
(byte*)dir, sz);
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer,
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer), sz);
|
||||
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, UINT32_SZ);
|
||||
|
||||
/* @TODO handle setting attributes */
|
||||
(void)atr;
|
||||
c32toa(0x000001FF, state->buffer.data + idx);
|
||||
idx += UINT32_SZ;
|
||||
state->buffer.sz = idx;
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, 0x000001FF);
|
||||
|
||||
ret = wolfSSH_SFTP_buffer_set_size(&state->buffer,
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer));
|
||||
if (ret != WS_SUCCESS) {
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_MKDIR);
|
||||
return ret;
|
||||
}
|
||||
wolfSSH_SFTP_buffer_rewind(&state->buffer);
|
||||
}
|
||||
|
||||
/* send header and type specific data */
|
||||
ret = wolfSSH_stream_send(ssh, state->buffer.data,
|
||||
state->buffer.sz);
|
||||
ret = wolfSSH_SFTP_buffer_send(ssh, &state->buffer);
|
||||
if (ret < 0) {
|
||||
if (ssh->error != WS_WANT_READ && ssh->error != WS_WANT_WRITE)
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_MKDIR);
|
||||
|
@ -6927,28 +7101,41 @@ int wolfSSH_SFTP_Rename(WOLFSSH* ssh, const char* old, const char* nw)
|
|||
}
|
||||
|
||||
ret = SFTP_SetHeader(ssh, ssh->reqId, WOLFSSH_FTP_RENAME,
|
||||
sz + UINT32_SZ * 2, state->buffer.data);
|
||||
sz + UINT32_SZ * 2,
|
||||
wolfSSH_SFTP_buffer_data(&state->buffer));
|
||||
if (ret != WS_SUCCESS) {
|
||||
state->state = STATE_RENAME_CLEANUP;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* add old name to the packet */
|
||||
state->buffer.idx = WOLFSSH_SFTP_HEADER;
|
||||
c32toa((word32)WSTRLEN(old),
|
||||
state->buffer.data + state->buffer.idx);
|
||||
state->buffer.idx += UINT32_SZ;
|
||||
WMEMCPY(state->buffer.data + state->buffer.idx, (byte*)old,
|
||||
WSTRLEN(old));
|
||||
state->buffer.idx += (word32)WSTRLEN(old);
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer, 0,
|
||||
WOLFSSH_SFTP_HEADER);
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, (word32)WSTRLEN(old));
|
||||
WMEMCPY(wolfSSH_SFTP_buffer_data(&state->buffer) +
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer),
|
||||
(byte*)old, WSTRLEN(old));
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer,
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer),
|
||||
(word32)WSTRLEN(old));
|
||||
|
||||
/* add new name to the packet */
|
||||
c32toa((word32)WSTRLEN(nw),
|
||||
state->buffer.data + state->buffer.idx);
|
||||
state->buffer.idx += UINT32_SZ;
|
||||
WMEMCPY(state->buffer.data + state->buffer.idx, (byte*)nw,
|
||||
WSTRLEN(nw));
|
||||
state->buffer.idx += (word32)WSTRLEN(nw);
|
||||
wolfSSH_SFTP_buffer_c32toa(&state->buffer, (word32)WSTRLEN(nw));
|
||||
WMEMCPY(wolfSSH_SFTP_buffer_data(&state->buffer) +
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer),
|
||||
(byte*)nw, WSTRLEN(nw));
|
||||
wolfSSH_SFTP_buffer_seek(&state->buffer,
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer),
|
||||
(word32)WSTRLEN(nw));
|
||||
|
||||
/* reset size and rewind */
|
||||
ret = wolfSSH_SFTP_buffer_set_size(&state->buffer,
|
||||
wolfSSH_SFTP_buffer_idx(&state->buffer));
|
||||
if (ret != WS_SUCCESS) {
|
||||
state->state = STATE_RENAME_CLEANUP;
|
||||
continue;
|
||||
}
|
||||
wolfSSH_SFTP_buffer_rewind(&state->buffer);
|
||||
|
||||
state->state = STATE_RENAME_SEND;
|
||||
FALL_THROUGH;
|
||||
|
@ -6956,8 +7143,7 @@ int wolfSSH_SFTP_Rename(WOLFSSH* ssh, const char* old, const char* nw)
|
|||
case STATE_RENAME_SEND:
|
||||
WLOG(WS_LOG_SFTP, "SFTP RENAME STATE: SEND");
|
||||
/* send header and type specific data */
|
||||
ret = wolfSSH_stream_send(ssh, state->buffer.data,
|
||||
state->buffer.idx);
|
||||
ret = wolfSSH_SFTP_buffer_send(ssh, &state->buffer);
|
||||
if (ret <= 0) {
|
||||
if (ssh->error == WS_WANT_READ ||
|
||||
ssh->error == WS_WANT_WRITE) {
|
||||
|
@ -7013,7 +7199,7 @@ int wolfSSH_SFTP_Rename(WOLFSSH* ssh, const char* old, const char* nw)
|
|||
|
||||
case STATE_RENAME_READ_STATUS:
|
||||
WLOG(WS_LOG_SFTP, "SFTP RENAME STATE: READ_STATUS");
|
||||
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
|
||||
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
|
||||
wolfSSH_SFTP_buffer_size(&state->buffer));
|
||||
if (ret <= 0) {
|
||||
if (ssh->error == WS_WANT_READ ||
|
||||
|
|
Loading…
Reference in New Issue