mirror of https://github.com/wolfSSL/wolfssh.git
Merge pull request #793 from JacobBarthelmeh/rekey
sanity checks on message types during rekeypull/841/head
commit
50aa10d717
|
|
@ -342,6 +342,9 @@ static THREAD_RET readInput(void* in)
|
|||
ret = wolfSSH_stream_send(args->ssh, buf, sz);
|
||||
wc_UnLockMutex(&args->lock);
|
||||
if (ret <= 0) {
|
||||
if (ret == WS_REKEYING) {
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr, "Couldn't send data\n");
|
||||
return THREAD_RET_SUCCESS;
|
||||
}
|
||||
|
|
@ -472,8 +475,16 @@ static THREAD_RET readPeer(void* in)
|
|||
continue;
|
||||
}
|
||||
#endif /* WOLFSSH_AGENT */
|
||||
else if (ret == WS_REKEYING) {
|
||||
wolfSSH_worker(args->ssh, NULL);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else if (ret != WS_EOF) {
|
||||
if (ret == 0) {
|
||||
bytes = 0;
|
||||
continue;
|
||||
}
|
||||
err_sys("Stream read failed.");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1416,8 +1416,11 @@ static int sftp_worker(thread_ctx_t* threadCtx)
|
|||
}
|
||||
else if (ret < 0) {
|
||||
error = wolfSSH_get_error(ssh);
|
||||
if (error == WS_EOF)
|
||||
if (error == WS_EOF) {
|
||||
/* shutdown is happening, clear peek error */
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WS_FATAL_ERROR && error == 0) {
|
||||
|
|
|
|||
|
|
@ -747,6 +747,13 @@ static int doCmds(func_args* args)
|
|||
|
||||
/* check directory is valid */
|
||||
do {
|
||||
while (ret == WS_REKEYING || ssh->error == WS_REKEYING) {
|
||||
ret = wolfSSH_worker(ssh, NULL);
|
||||
if (ret != WS_SUCCESS && ret == WS_FATAL_ERROR) {
|
||||
ret = wolfSSH_get_error(ssh);
|
||||
}
|
||||
}
|
||||
|
||||
ret = wolfSSH_SFTP_STAT(ssh, pt, &atrb);
|
||||
err = wolfSSH_get_error(ssh);
|
||||
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE)
|
||||
|
|
@ -828,6 +835,13 @@ static int doCmds(func_args* args)
|
|||
|
||||
/* update permissions */
|
||||
do {
|
||||
while (ret == WS_REKEYING || ssh->error == WS_REKEYING) {
|
||||
ret = wolfSSH_worker(ssh, NULL);
|
||||
if (ret != WS_SUCCESS && ret == WS_FATAL_ERROR) {
|
||||
ret = wolfSSH_get_error(ssh);
|
||||
}
|
||||
}
|
||||
|
||||
ret = wolfSSH_SFTP_CHMOD(ssh, pt, mode);
|
||||
err = wolfSSH_get_error(ssh);
|
||||
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE)
|
||||
|
|
@ -878,6 +892,13 @@ static int doCmds(func_args* args)
|
|||
}
|
||||
|
||||
do {
|
||||
while (ret == WS_REKEYING || ssh->error == WS_REKEYING) {
|
||||
ret = wolfSSH_worker(ssh, NULL);
|
||||
if (ret != WS_SUCCESS && ret == WS_FATAL_ERROR) {
|
||||
ret = wolfSSH_get_error(ssh);
|
||||
}
|
||||
}
|
||||
|
||||
ret = wolfSSH_SFTP_RMDIR(ssh, pt);
|
||||
err = wolfSSH_get_error(ssh);
|
||||
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE)
|
||||
|
|
@ -924,6 +945,13 @@ static int doCmds(func_args* args)
|
|||
}
|
||||
|
||||
do {
|
||||
while (ret == WS_REKEYING || ssh->error == WS_REKEYING) {
|
||||
ret = wolfSSH_worker(ssh, NULL);
|
||||
if (ret != WS_SUCCESS && ret == WS_FATAL_ERROR) {
|
||||
ret = wolfSSH_get_error(ssh);
|
||||
}
|
||||
}
|
||||
|
||||
ret = wolfSSH_SFTP_Remove(ssh, pt);
|
||||
err = wolfSSH_get_error(ssh);
|
||||
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE)
|
||||
|
|
@ -1119,7 +1147,7 @@ static int doCmds(func_args* args)
|
|||
/* alternate main loop for the autopilot get/receive */
|
||||
static int doAutopilot(int cmd, char* local, char* remote)
|
||||
{
|
||||
int err;
|
||||
int err = 0;
|
||||
int ret = WS_SUCCESS;
|
||||
char fullpath[128] = ".";
|
||||
WS_SFTPNAME* name = NULL;
|
||||
|
|
@ -1156,6 +1184,12 @@ static int doAutopilot(int cmd, char* local, char* remote)
|
|||
}
|
||||
|
||||
do {
|
||||
if (err == WS_REKEYING || err == WS_WINDOW_FULL) { /* handle rekeying state */
|
||||
do {
|
||||
ret = wolfSSH_worker(ssh, NULL);
|
||||
} while (ret == WS_REKEYING);
|
||||
}
|
||||
|
||||
if (cmd == AUTOPILOT_PUT) {
|
||||
ret = wolfSSH_SFTP_Put(ssh, local, fullpath, 0, NULL);
|
||||
}
|
||||
|
|
@ -1164,7 +1198,8 @@ static int doAutopilot(int cmd, char* local, char* remote)
|
|||
}
|
||||
err = wolfSSH_get_error(ssh);
|
||||
} while ((err == WS_WANT_READ || err == WS_WANT_WRITE ||
|
||||
err == WS_CHAN_RXD || err == WS_REKEYING) &&
|
||||
err == WS_CHAN_RXD || err == WS_REKEYING ||
|
||||
err == WS_WINDOW_FULL) &&
|
||||
ret == WS_FATAL_ERROR);
|
||||
|
||||
if (ret != WS_SUCCESS) {
|
||||
|
|
@ -1452,14 +1487,52 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
|
|||
|
||||
WFREE(workingDir, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (wolfSSH_shutdown(ssh) != WS_SUCCESS) {
|
||||
int rc;
|
||||
rc = wolfSSH_get_error(ssh);
|
||||
int err;
|
||||
ret = wolfSSH_shutdown(ssh);
|
||||
|
||||
if (rc != WS_SOCKET_ERROR_E && rc != WS_EOF)
|
||||
printf("error with wolfSSH_shutdown()\n");
|
||||
/* peer hung up, stop trying to shutdown */
|
||||
if (ret == WS_SOCKET_ERROR_E) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
err = wolfSSH_get_error(ssh);
|
||||
if (err != WS_SOCKET_ERROR_E &&
|
||||
(err == WS_WANT_READ || err == WS_WANT_WRITE)) {
|
||||
int maxAttempt = 10; /* make 10 attempts max before giving up */
|
||||
int attempt;
|
||||
|
||||
for (attempt = 0; attempt < maxAttempt; attempt++) {
|
||||
ret = wolfSSH_worker(ssh, NULL);
|
||||
err = wolfSSH_get_error(ssh);
|
||||
|
||||
/* peer successfully closed down gracefully */
|
||||
if (ret == WS_CHANNEL_CLOSED) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* peer hung up, stop shutdown */
|
||||
if (ret == WS_SOCKET_ERROR_E) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (err == WS_WANT_READ || err == WS_WANT_WRITE) {
|
||||
/* Wanting read or wanting write. Clear ret. */
|
||||
ret = 0;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (attempt == maxAttempt) {
|
||||
printf("SFTP client gave up on gracefull shutdown,"
|
||||
"closing the socket\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WCLOSESOCKET(sockFd);
|
||||
wolfSSH_free(ssh);
|
||||
wolfSSH_CTX_free(ctx);
|
||||
|
|
|
|||
|
|
@ -595,6 +595,40 @@ static void HandshakeInfoFree(HandshakeInfo* hs, void* heap)
|
|||
}
|
||||
|
||||
|
||||
/* RFC 4253 section 7.1, Once having sent SSH_MSG_KEXINIT the only messages
|
||||
* that can be sent are 1-19 (except SSH_MSG_SERVICE_REQUEST and
|
||||
* SSH_MSG_SERVICE_ACCEPT), 20-29 (except SSH_MSG_KEXINIT again), and 30-49
|
||||
*/
|
||||
INLINE static int IsMessageAllowedKeying(WOLFSSH *ssh, byte msg)
|
||||
{
|
||||
if (ssh->isKeying == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* case of service request or accept in 1-19 */
|
||||
if (msg == MSGID_SERVICE_REQUEST || msg == MSGID_SERVICE_ACCEPT) {
|
||||
WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by during rekeying", msg);
|
||||
ssh->error = WS_REKEYING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* case of resending SSH_MSG_KEXINIT */
|
||||
if (msg == MSGID_KEXINIT) {
|
||||
WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by during rekeying", msg);
|
||||
ssh->error = WS_REKEYING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* case where message id greater than 49 */
|
||||
if (msg >= MSGID_USERAUTH_REQUEST) {
|
||||
WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by during rekeying", msg);
|
||||
ssh->error = WS_REKEYING;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_WOLFSSH_SERVER
|
||||
INLINE static int IsMessageAllowedServer(WOLFSSH *ssh, byte msg)
|
||||
{
|
||||
|
|
@ -673,8 +707,14 @@ INLINE static int IsMessageAllowedClient(WOLFSSH *ssh, byte msg)
|
|||
#endif /* NO_WOLFSSH_CLIENT */
|
||||
|
||||
|
||||
INLINE static int IsMessageAllowed(WOLFSSH *ssh, byte msg)
|
||||
/* 'state' argument is for if trying to send a message or receive one.
|
||||
* Returns 1 if allowed 0 if not allowed. */
|
||||
INLINE static int IsMessageAllowed(WOLFSSH *ssh, byte msg, byte state)
|
||||
{
|
||||
if (state == WS_MSG_SEND && !IsMessageAllowedKeying(ssh, msg)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef NO_WOLFSSH_SERVER
|
||||
if (ssh->ctx->side == WOLFSSH_ENDPOINT_SERVER) {
|
||||
return IsMessageAllowedServer(ssh, msg);
|
||||
|
|
@ -5905,7 +5945,6 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
|
|||
HandshakeInfoFree(ssh->handshake, ssh->ctx->heap);
|
||||
ssh->handshake = NULL;
|
||||
WLOG(WS_LOG_DEBUG, "Keying completed");
|
||||
|
||||
if (ssh->ctx->keyingCompletionCb)
|
||||
ssh->ctx->keyingCompletionCb(ssh->keyingCompletionCtx);
|
||||
}
|
||||
|
|
@ -9322,7 +9361,7 @@ static int DoPacket(WOLFSSH* ssh, byte* bufferConsumed)
|
|||
return WS_OVERFLOW_E;
|
||||
}
|
||||
|
||||
if (!IsMessageAllowed(ssh, msg)) {
|
||||
if (!IsMessageAllowed(ssh, msg, WS_MSG_RECV)) {
|
||||
return WS_MSGID_NOT_ALLOWED_E;
|
||||
}
|
||||
|
||||
|
|
@ -15662,6 +15701,12 @@ int SendChannelEof(WOLFSSH* ssh, word32 peerChannelId)
|
|||
if (ssh == NULL)
|
||||
ret = WS_BAD_ARGUMENT;
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (!IsMessageAllowed(ssh, MSGID_CHANNEL_EOF, WS_MSG_SEND)) {
|
||||
ret = WS_MSGID_NOT_ALLOWED_E;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
channel = ChannelFind(ssh, peerChannelId, WS_CHANNEL_ID_PEER);
|
||||
if (channel == NULL)
|
||||
|
|
@ -16090,6 +16135,12 @@ int SendChannelWindowAdjust(WOLFSSH* ssh, word32 channelId,
|
|||
if (ssh == NULL)
|
||||
ret = WS_BAD_ARGUMENT;
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (!IsMessageAllowed(ssh, MSGID_CHANNEL_WINDOW_ADJUST, WS_MSG_SEND)) {
|
||||
ret = WS_MSGID_NOT_ALLOWED_E;
|
||||
}
|
||||
}
|
||||
|
||||
channel = ChannelFind(ssh, channelId, WS_CHANNEL_ID_SELF);
|
||||
if (channel == NULL) {
|
||||
WLOG(WS_LOG_DEBUG, "Invalid channel");
|
||||
|
|
|
|||
14
src/ssh.c
14
src/ssh.c
|
|
@ -1135,6 +1135,11 @@ int wolfSSH_stream_read(WOLFSSH* ssh, byte* buf, word32 bufSz)
|
|||
return WS_ERROR;
|
||||
}
|
||||
|
||||
if (ssh->isKeying) {
|
||||
ssh->error = WS_REKEYING;
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
inputBuffer = &ssh->channelList->inputBuffer;
|
||||
ssh->error = WS_SUCCESS;
|
||||
|
||||
|
|
@ -1164,7 +1169,7 @@ int wolfSSH_stream_read(WOLFSSH* ssh, byte* buf, word32 bufSz)
|
|||
}
|
||||
|
||||
/* update internal input buffer based on data read */
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (ret == WS_SUCCESS && !ssh->isKeying) {
|
||||
int n;
|
||||
|
||||
n = min(bufSz, inputBuffer->length - inputBuffer->idx);
|
||||
|
|
@ -1196,7 +1201,7 @@ int wolfSSH_stream_send(WOLFSSH* ssh, byte* buf, word32 bufSz)
|
|||
|
||||
if (ssh->isKeying) {
|
||||
ssh->error = WS_REKEYING;
|
||||
return WS_REKEYING;
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
bytesTxd = SendChannelData(ssh, ssh->channelList->channel, buf, bufSz);
|
||||
|
|
@ -2901,6 +2906,11 @@ int wolfSSH_ChannelRead(WOLFSSH_CHANNEL* channel, byte* buf, word32 bufSz)
|
|||
if (channel == NULL || buf == NULL || bufSz == 0)
|
||||
return WS_BAD_ARGUMENT;
|
||||
|
||||
if (channel->ssh->isKeying) {
|
||||
channel->ssh->error = WS_REKEYING;
|
||||
return WS_REKEYING;
|
||||
}
|
||||
|
||||
bufSz = _ChannelRead(channel, buf, bufSz);
|
||||
|
||||
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_ChannelRead(), bytesRxd = %d",
|
||||
|
|
|
|||
|
|
@ -416,6 +416,7 @@ static INLINE int NoticeError(WOLFSSH* ssh)
|
|||
return (ssh->error == WS_WANT_READ ||
|
||||
ssh->error == WS_WANT_WRITE ||
|
||||
ssh->error == WS_CHAN_RXD ||
|
||||
ssh->error == WS_WINDOW_FULL ||
|
||||
ssh->error == WS_REKEYING);
|
||||
}
|
||||
|
||||
|
|
@ -1170,8 +1171,9 @@ int wolfSSH_SFTP_accept(WOLFSSH* ssh)
|
|||
case SFTP_EXT:
|
||||
ret = SFTP_ServerRecvInit(ssh);
|
||||
if (ret != WS_SUCCESS) {
|
||||
if (ssh->error != WS_WANT_READ && ssh->error != WS_WANT_WRITE)
|
||||
if (!NoticeError(ssh)) {
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_ALL);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
ssh->sftpState = SFTP_RECV;
|
||||
|
|
@ -1418,7 +1420,11 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
|||
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer,
|
||||
state->buffer.sz);
|
||||
if (ret < 0) {
|
||||
if (!NoticeError(ssh)) {
|
||||
if (NoticeError(ssh)) {
|
||||
/* keep state for returning to */
|
||||
ret = WS_FATAL_ERROR;
|
||||
}
|
||||
else {
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RECV);
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -1569,8 +1575,9 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
|||
|
||||
/* break out if encountering an error with nothing stored to send */
|
||||
if (ret < 0 && !state->toSend) {
|
||||
if (ssh->error != WS_WANT_READ && ssh->error != WS_WANT_WRITE)
|
||||
if (!NoticeError(ssh)) {
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RECV);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
state->buffer.idx = 0;
|
||||
|
|
@ -7468,8 +7475,7 @@ int wolfSSH_SFTP_SendWritePacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
/* send header and type specific data */
|
||||
ret = wolfSSH_SFTP_buffer_send(ssh, &state->buffer);
|
||||
if (ret < 0) {
|
||||
if (ssh->error == WS_WANT_READ ||
|
||||
ssh->error == WS_WANT_WRITE) {
|
||||
if (NoticeError(ssh)) {
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
state->state = STATE_SEND_WRITE_CLEANUP;
|
||||
|
|
@ -7481,16 +7487,15 @@ int wolfSSH_SFTP_SendWritePacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
case STATE_SEND_WRITE_SEND_BODY:
|
||||
WLOG(WS_LOG_SFTP, "SFTP SEND_WRITE STATE: SEND_BODY");
|
||||
state->sentSz = wolfSSH_stream_send(ssh, in, inSz);
|
||||
if (state->sentSz == WS_WINDOW_FULL ||
|
||||
state->sentSz == WS_REKEYING ||
|
||||
state->sentSz == WS_WANT_READ ||
|
||||
state->sentSz == WS_WANT_WRITE) {
|
||||
ret = wolfSSH_worker(ssh, NULL);
|
||||
continue; /* skip past rest and send more */
|
||||
}
|
||||
if (state->sentSz <= 0) {
|
||||
ssh->error = state->sentSz;
|
||||
ret = WS_FATAL_ERROR;
|
||||
if (NoticeError(ssh)) {
|
||||
ret = wolfSSH_worker(ssh,NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if it was not a notice error then clean up the state and
|
||||
* exit out */
|
||||
state->state = STATE_SEND_WRITE_CLEANUP;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -7512,8 +7517,7 @@ int wolfSSH_SFTP_SendWritePacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
state->maxSz = SFTP_GetHeader(ssh, &state->reqId, &type,
|
||||
&state->buffer);
|
||||
if (state->maxSz <= 0) {
|
||||
if (ssh->error == WS_WANT_READ ||
|
||||
ssh->error == WS_WANT_WRITE) {
|
||||
if (NoticeError(ssh)) {
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
ssh->error = WS_SFTP_BAD_HEADER;
|
||||
|
|
@ -7692,8 +7696,8 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
/* send header and type specific data */
|
||||
ret = wolfSSH_SFTP_buffer_send(ssh, &state->buffer);
|
||||
if (ret < 0) {
|
||||
if (ret == WS_REKEYING) {
|
||||
return ret;
|
||||
if (NoticeError(ssh)) {
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
if (ssh->error != WS_WANT_READ &&
|
||||
ssh->error != WS_WANT_WRITE) {
|
||||
|
|
@ -7711,14 +7715,12 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
/* Get response */
|
||||
if ((ret = SFTP_GetHeader(ssh, &state->reqId, &state->type,
|
||||
&state->buffer)) <= 0) {
|
||||
if (ssh->error != WS_WANT_READ &&
|
||||
ssh->error != WS_WANT_WRITE) {
|
||||
if (!NoticeError(ssh)) {
|
||||
state->state = STATE_SEND_READ_CLEANUP;
|
||||
continue;
|
||||
}
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
ret = wolfSSH_SFTP_buffer_create(ssh, &state->buffer, ret);
|
||||
if (ret != WS_SUCCESS) {
|
||||
state->state = STATE_SEND_READ_CLEANUP;
|
||||
|
|
@ -7736,8 +7738,9 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
state->state = STATE_SEND_READ_CLEANUP;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
else {
|
||||
ssh->reqId++;
|
||||
}
|
||||
|
||||
if (state->type == WOLFSSH_FTP_DATA)
|
||||
state->state = STATE_SEND_READ_FTP_DATA;
|
||||
|
|
@ -7755,8 +7758,7 @@ int wolfSSH_SFTP_SendReadPacket(WOLFSSH* ssh, byte* handle, word32 handleSz,
|
|||
/* get size of string and place it into out buffer */
|
||||
ret = wolfSSH_stream_read(ssh, szFlat, UINT32_SZ);
|
||||
if (ret < 0) {
|
||||
if (ssh->error != WS_WANT_READ &&
|
||||
ssh->error != WS_WANT_WRITE) {
|
||||
if (!NoticeError(ssh)) {
|
||||
state->state = STATE_SEND_READ_CLEANUP;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -7935,8 +7937,9 @@ int wolfSSH_SFTP_MKDIR(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr)
|
|||
/* send header and type specific data */
|
||||
ret = wolfSSH_SFTP_buffer_send(ssh, &state->buffer);
|
||||
if (ret < 0) {
|
||||
if (ssh->error != WS_WANT_READ && ssh->error != WS_WANT_WRITE)
|
||||
if (!NoticeError(ssh)) {
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_MKDIR);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -7949,8 +7952,9 @@ int wolfSSH_SFTP_MKDIR(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr)
|
|||
/* Get response */
|
||||
if ((ret = SFTP_GetHeader(ssh, &state->reqId, &type,
|
||||
&state->buffer)) <= 0) {
|
||||
if (ssh->error != WS_WANT_READ && ssh->error != WS_WANT_WRITE)
|
||||
if (!NoticeError(ssh)) {
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_MKDIR);
|
||||
}
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -7981,8 +7985,9 @@ int wolfSSH_SFTP_MKDIR(WOLFSSH* ssh, char* dir, WS_SFTP_FILEATRB* atr)
|
|||
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)
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_MKDIR);
|
||||
if (!NoticeError(ssh)) {
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_MKDIR);
|
||||
}
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -8049,8 +8054,7 @@ WS_SFTPNAME* wolfSSH_SFTP_ReadDir(WOLFSSH* ssh, byte* handle,
|
|||
case STATE_READDIR_NAME:
|
||||
name = wolfSSH_SFTP_DoName(ssh);
|
||||
if (name == NULL) {
|
||||
if (ssh->error != WS_WANT_READ
|
||||
&& ssh->error != WS_WANT_WRITE) {
|
||||
if (!NoticeError(ssh)) {
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_READDIR);
|
||||
}
|
||||
return NULL;
|
||||
|
|
@ -9183,10 +9187,9 @@ int wolfSSH_SFTP_Put(WOLFSSH* ssh, char* from, char* to, byte resume,
|
|||
state->handle, state->handleSz, state->pOfst,
|
||||
state->r, state->rSz);
|
||||
if (sz <= 0) {
|
||||
if (ssh->error == WS_WANT_READ ||
|
||||
ssh->error == WS_WANT_WRITE ||
|
||||
ssh->error == WS_WINDOW_FULL)
|
||||
if (NoticeError(ssh)) {
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
AddAssign64(state->pOfst, sz);
|
||||
|
|
|
|||
13
tests/api.c
13
tests/api.c
|
|
@ -1057,14 +1057,16 @@ static void test_wolfSSH_SFTP_SendReadPacket(void)
|
|||
outSz = WOLFSSH_MAX_SFTP_RW / 2;
|
||||
rxSz = wolfSSH_SFTP_SendReadPacket(ssh, handle, handleSz,
|
||||
ofst, out, outSz);
|
||||
AssertIntGT(rxSz, 0);
|
||||
AssertIntLE(rxSz, outSz);
|
||||
if (wolfSSH_get_error(ssh) != WS_REKEYING) {
|
||||
AssertIntGT(rxSz, 0);
|
||||
AssertIntLE(rxSz, outSz);
|
||||
}
|
||||
|
||||
/* read all */
|
||||
outSz = WOLFSSH_MAX_SFTP_RW;
|
||||
rxSz = wolfSSH_SFTP_SendReadPacket(ssh, handle, handleSz,
|
||||
ofst, out, outSz);
|
||||
if (rxSz != WS_REKEYING) {
|
||||
if (wolfSSH_get_error(ssh) != WS_REKEYING) {
|
||||
AssertIntGT(rxSz, 0);
|
||||
AssertIntLE(rxSz, outSz);
|
||||
}
|
||||
|
|
@ -1075,6 +1077,11 @@ static void test_wolfSSH_SFTP_SendReadPacket(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* take care of re-keying state before shutdown call */
|
||||
while (wolfSSH_get_error(ssh) == WS_REKEYING) {
|
||||
wolfSSH_worker(ssh, NULL);
|
||||
}
|
||||
|
||||
argsCount = wolfSSH_shutdown(ssh);
|
||||
if (argsCount == WS_SOCKET_ERROR_E) {
|
||||
/* If the socket is closed on shutdown, peer is gone, this is OK. */
|
||||
|
|
|
|||
|
|
@ -1250,6 +1250,10 @@ enum WS_MessageIds {
|
|||
|
||||
#define CHANNEL_EXTENDED_DATA_STDERR WOLFSSH_EXT_DATA_STDERR
|
||||
|
||||
/* Used when checking IsMessageAllowed() to determine if creating and sending
|
||||
* the message or receiving the message is allowed */
|
||||
#define WS_MSG_SEND 1
|
||||
#define WS_MSG_RECV 2
|
||||
|
||||
/* dynamic memory types */
|
||||
enum WS_DynamicTypes {
|
||||
|
|
@ -1443,4 +1447,3 @@ enum TerminalModes {
|
|||
#endif
|
||||
|
||||
#endif /* _WOLFSSH_INTERNAL_H_ */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue