mirror of https://github.com/wolfSSL/wolfssh.git
commit
3b61ea2ab8
|
@ -5246,6 +5246,16 @@ static int DoPacket(WOLFSSH* ssh)
|
|||
case MSGID_KEXINIT:
|
||||
WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXINIT");
|
||||
ret = DoKexInit(ssh, buf + idx, payloadSz, &payloadIdx);
|
||||
if (ssh->isKeying == 1 &&
|
||||
ssh->connectState == CONNECT_SERVER_CHANNEL_REQUEST_DONE) {
|
||||
if (ssh->handshake->kexId == ID_DH_GEX_SHA256) {
|
||||
#ifndef WOLFSSH_NO_DH
|
||||
ssh->error = SendKexDhGexRequest(ssh);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
ssh->error = SendKexDhInit(ssh);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSGID_NEWKEYS:
|
||||
|
@ -6780,6 +6790,11 @@ int SendKexDhReply(WOLFSSH* ssh)
|
|||
ret = wc_HashUpdate(&ssh->handshake->hash, enmhashId,
|
||||
ssh->handshake->e, ssh->handshake->eSz);
|
||||
|
||||
/* reset size here because a previous shared secret could potentially be
|
||||
* smaller by a byte than usual and cause buffer issues with re-key */
|
||||
if (ret == 0)
|
||||
ssh->kSz = MAX_KEX_KEY_SZ;
|
||||
|
||||
/* Make the server's DH f-value and the shared secret K. */
|
||||
/* Or make the server's ECDH private value, and the shared secret K. */
|
||||
if (ret == 0) {
|
||||
|
@ -6806,8 +6821,9 @@ int SendKexDhReply(WOLFSSH* ssh)
|
|||
else {
|
||||
ecc_key pubKey;
|
||||
ecc_key privKey;
|
||||
int primeId = wcPrimeForId(ssh->handshake->kexId);
|
||||
int primeId;
|
||||
|
||||
primeId = wcPrimeForId(ssh->handshake->kexId);
|
||||
if (primeId == ECC_CURVE_INVALID)
|
||||
ret = WS_INVALID_PRIME_CURVE;
|
||||
|
||||
|
|
105
src/ssh.c
105
src/ssh.c
|
@ -968,8 +968,56 @@ int wolfSSH_stream_peek(WOLFSSH* ssh, byte* buf, word32 bufSz)
|
|||
}
|
||||
|
||||
|
||||
/* moves the window for more room
|
||||
* returns WS_SUCCESS on success */
|
||||
static int wolfSSH_stream_adjust_window(WOLFSSH* ssh)
|
||||
{
|
||||
word32 usedSz;
|
||||
word32 bytesToAdd;
|
||||
int ret;
|
||||
Buffer* inputBuffer;
|
||||
|
||||
inputBuffer = &ssh->channelList->inputBuffer;
|
||||
usedSz = inputBuffer->length - inputBuffer->idx;
|
||||
bytesToAdd = inputBuffer->idx;
|
||||
|
||||
WLOG(WS_LOG_DEBUG, "Making more room: %u", usedSz);
|
||||
if (usedSz) {
|
||||
WLOG(WS_LOG_DEBUG, " ...moving data down");
|
||||
WMEMMOVE(inputBuffer->buffer, inputBuffer->buffer + bytesToAdd, usedSz);
|
||||
}
|
||||
|
||||
ret = SendChannelWindowAdjust(ssh, ssh->channelList->channel,
|
||||
bytesToAdd);
|
||||
if (ret != WS_SUCCESS) {
|
||||
WLOG(WS_LOG_ERROR, "Error adjusting window");
|
||||
}
|
||||
else {
|
||||
WLOG(WS_LOG_INFO, " bytesToAdd = %u", bytesToAdd);
|
||||
WLOG(WS_LOG_INFO, " windowSz = %u", ssh->channelList->windowSz);
|
||||
ssh->channelList->windowSz += bytesToAdd;
|
||||
WLOG(WS_LOG_INFO, " update windowSz = %u", ssh->channelList->windowSz);
|
||||
inputBuffer->length = usedSz;
|
||||
inputBuffer->idx = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Wrapper function for ease of use to get data after it has been decrypted from
|
||||
* the SSH connection. This function handles low level operations in addition to
|
||||
* the read, such as window adjustment and high water checking.
|
||||
*
|
||||
* In non blocking mode use the function wolfSSH_get_error(ssh) to check for
|
||||
* WS_WANT_READ / WS_WANT_WRITE after a fail case was hit with
|
||||
* wolfSSH_stream_read().
|
||||
*
|
||||
* Returns the number of bytes read on success, negative values on fail
|
||||
*/
|
||||
int wolfSSH_stream_read(WOLFSSH* ssh, byte* buf, word32 bufSz)
|
||||
{
|
||||
int ret = WS_SUCCESS;
|
||||
Buffer* inputBuffer;
|
||||
|
||||
WLOG(WS_LOG_DEBUG, "Entering wolfSSH_stream_read()");
|
||||
|
@ -979,52 +1027,41 @@ int wolfSSH_stream_read(WOLFSSH* ssh, byte* buf, word32 bufSz)
|
|||
|
||||
inputBuffer = &ssh->channelList->inputBuffer;
|
||||
|
||||
/* check if the window needs updated before attempting to read */
|
||||
if ((ssh->channelList->windowSz == 0) || (!ssh->isKeying &&
|
||||
(inputBuffer->length > inputBuffer->bufferSz / 2)))
|
||||
ret = wolfSSH_stream_adjust_window(ssh);
|
||||
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
while (inputBuffer->length - inputBuffer->idx == 0) {
|
||||
int ret = DoReceive(ssh);
|
||||
ret = DoReceive(ssh);
|
||||
if (ssh->channelList == NULL || ssh->channelList->receivedEof)
|
||||
ret = WS_EOF;
|
||||
if (ret < 0 && ret != WS_CHAN_RXD) {
|
||||
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_stream_read(), ret = %d", ret);
|
||||
return ret;
|
||||
break;
|
||||
}
|
||||
if (ssh->error == WS_CHAN_RXD &&
|
||||
ssh->lastRxId != ssh->channelList->channel) {
|
||||
return WS_ERROR;
|
||||
ret = WS_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bufSz = min(bufSz, inputBuffer->length - inputBuffer->idx);
|
||||
WMEMCPY(buf, inputBuffer->buffer + inputBuffer->idx, bufSz);
|
||||
inputBuffer->idx += bufSz;
|
||||
|
||||
if (!ssh->isKeying && (inputBuffer->length > inputBuffer->bufferSz / 2)) {
|
||||
|
||||
word32 usedSz = inputBuffer->length - inputBuffer->idx;
|
||||
word32 bytesToAdd = inputBuffer->idx;
|
||||
int sendResult;
|
||||
|
||||
WLOG(WS_LOG_DEBUG, "Making more room: %u", usedSz);
|
||||
if (usedSz) {
|
||||
WLOG(WS_LOG_DEBUG, " ...moving data down");
|
||||
WMEMMOVE(inputBuffer->buffer,
|
||||
inputBuffer->buffer + bytesToAdd, usedSz);
|
||||
/* update internal input buffer based on data read */
|
||||
if (ret == WS_SUCCESS) {
|
||||
ret = min(bufSz, inputBuffer->length - inputBuffer->idx);
|
||||
if (ret <= 0)
|
||||
ret = WS_BUFFER_E;
|
||||
else {
|
||||
WMEMCPY(buf, inputBuffer->buffer + inputBuffer->idx, ret);
|
||||
inputBuffer->idx += ret;
|
||||
}
|
||||
}
|
||||
|
||||
sendResult = SendChannelWindowAdjust(ssh, ssh->channelList->channel,
|
||||
bytesToAdd);
|
||||
if (sendResult != WS_SUCCESS)
|
||||
bufSz = sendResult;
|
||||
|
||||
WLOG(WS_LOG_INFO, " bytesToAdd = %u", bytesToAdd);
|
||||
WLOG(WS_LOG_INFO, " windowSz = %u", ssh->channelList->windowSz);
|
||||
ssh->channelList->windowSz += bytesToAdd;
|
||||
WLOG(WS_LOG_INFO, " update windowSz = %u", ssh->channelList->windowSz);
|
||||
|
||||
inputBuffer->length = usedSz;
|
||||
inputBuffer->idx = 0;
|
||||
}
|
||||
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_stream_read(), rxd = %d", bufSz);
|
||||
return bufSz;
|
||||
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_stream_read(), rxd = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -572,7 +572,7 @@ int DoScpSource(WOLFSSH* ssh)
|
|||
|
||||
ret = wolfSSH_stream_send(ssh, ssh->scpFileBuffer,
|
||||
ssh->scpBufferedSz);
|
||||
if (ret == WS_WINDOW_FULL) {
|
||||
if (ret == WS_WINDOW_FULL || ret == WS_REKEYING) {
|
||||
ret = wolfSSH_worker(ssh, NULL);
|
||||
if (ret == WS_SUCCESS)
|
||||
continue;
|
||||
|
|
|
@ -504,7 +504,7 @@ static int wolfSSH_SFTP_buffer_send(WOLFSSH* ssh, WS_SFTP_BUFFER* buffer)
|
|||
do {
|
||||
ret = wolfSSH_stream_send(ssh, buffer->data + buffer->idx,
|
||||
buffer->sz - buffer->idx);
|
||||
if (ret == WS_WINDOW_FULL) {
|
||||
if (ret == WS_WINDOW_FULL || ret == WS_REKEYING) {
|
||||
ret = wolfSSH_worker(ssh, NULL);
|
||||
if (ret == WS_SUCCESS)
|
||||
continue; /* skip past increment and send more */
|
||||
|
@ -786,8 +786,8 @@ static int SFTP_GetHeader(WOLFSSH* ssh, word32* reqId, byte* type,
|
|||
ato32(buffer->data + UINT32_SZ + MSG_ID_SZ, reqId);
|
||||
|
||||
wolfSSH_SFTP_buffer_free(ssh, buffer);
|
||||
WLOG(WS_LOG_SFTP, "Leaving SFTP_GetHeader(), %d",
|
||||
len - UINT32_SZ - MSG_ID_SZ);
|
||||
WLOG(WS_LOG_SFTP, "Leaving SFTP_GetHeader(), packet length = %d id = %d"
|
||||
" type = %d", len - UINT32_SZ - MSG_ID_SZ, *reqId, *type);
|
||||
return len - UINT32_SZ - MSG_ID_SZ;
|
||||
}
|
||||
|
||||
|
@ -1258,7 +1258,7 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
|||
int maxSz, ret = WS_SUCCESS;
|
||||
WS_SFTP_RECV_STATE* state = NULL;
|
||||
|
||||
WLOG(WS_LOG_DEBUG, "Entering wolfSSH_SFTP_read()");
|
||||
WLOG(WS_LOG_SFTP, "Entering wolfSSH_SFTP_read()");
|
||||
|
||||
if (ssh == NULL)
|
||||
return WS_BAD_ARGUMENT;
|
||||
|
@ -1459,6 +1459,7 @@ int wolfSSH_SFTP_read(WOLFSSH* ssh)
|
|||
if (ret < 0) {
|
||||
if (ssh->error != WS_WANT_READ &&
|
||||
ssh->error != WS_WANT_WRITE &&
|
||||
ssh->error != WS_REKEYING &&
|
||||
ssh->error != WS_WINDOW_FULL)
|
||||
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RECV);
|
||||
return WS_FATAL_ERROR;
|
||||
|
@ -4935,7 +4936,7 @@ int SendPacketType(WOLFSSH* ssh, byte type, byte* buf, word32 bufSz)
|
|||
|
||||
/* check for adjust window packet */
|
||||
err = wolfSSH_get_error(ssh);
|
||||
if (err == WS_WINDOW_FULL)
|
||||
if (err == WS_WINDOW_FULL || err == WS_REKEYING)
|
||||
ret = wolfSSH_worker(ssh, NULL);
|
||||
ssh->error = err; /* don't save potential want read here */
|
||||
} while (ret > 0 &&
|
||||
|
@ -6406,7 +6407,8 @@ 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) {
|
||||
if (state->sentSz == WS_WINDOW_FULL ||
|
||||
state->sentSz == WS_REKEYING) {
|
||||
ret = wolfSSH_worker(ssh, NULL);
|
||||
if (ret == WS_SUCCESS)
|
||||
continue; /* skip past rest and send more */
|
||||
|
|
Loading…
Reference in New Issue