Moved functions to internal.c that belong there.

pull/1/head
John Safranek 2014-08-11 14:03:00 -07:00
parent e03a1011d2
commit a96a764bc0
3 changed files with 453 additions and 454 deletions

View File

@ -29,6 +29,13 @@
#include <wolfssh/log.h>
/* convert opaque to 32 bit integer */
static /*INLINE*/ void ato32(const uint8_t* c, uint32_t* u32)
{
*u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
}
typedef struct {
uint8_t id;
const char* name;
@ -185,3 +192,448 @@ void ShrinkBuffer(Buffer* buf)
}
static int Receive(WOLFSSH* ssh, uint8_t* buf, uint32_t sz)
{
int recvd;
if (ssh->ctx->ioRecvCb == NULL) {
WLOG(WS_LOG_DEBUG, "Your IO Recv callback is null, please set");
return -1;
}
retry:
recvd = ssh->ctx->ioRecvCb(ssh, buf, sz, ssh->ioReadCtx);
WLOG(WS_LOG_DEBUG, "Receive: recvd = %d", recvd);
if (recvd < 0)
switch (recvd) {
case WS_CBIO_ERR_GENERAL: /* general/unknown error */
return -1;
case WS_CBIO_ERR_WANT_READ: /* want read, would block */
return WS_WANT_READ;
case WS_CBIO_ERR_CONN_RST: /* connection reset */
ssh->connReset = 1;
return -1;
case WS_CBIO_ERR_ISR: /* interrupt */
goto retry;
case WS_CBIO_ERR_CONN_CLOSE: /* peer closed connection */
ssh->isClosed = 1;
return -1;
case WS_CBIO_ERR_TIMEOUT:
return -1;
default:
return recvd;
}
return recvd;
}
static int GetInputText(WOLFSSH* ssh)
{
int gotLine = 0;
int inSz = 255;
int in;
if (GrowBuffer(ssh->inputBuffer, inSz, 0) < 0)
return WS_MEMORY_E;
do {
in = Receive(ssh,
ssh->inputBuffer->buffer + ssh->inputBuffer->length, inSz);
if (in == -1)
return WS_SOCKET_ERROR_E;
if (in == WS_WANT_READ)
return WS_WANT_READ;
if (in > inSz)
return WS_RECV_OVERFLOW_E;
ssh->inputBuffer->length += in;
inSz -= in;
if (ssh->inputBuffer->length > 2) {
if (ssh->inputBuffer->buffer[ssh->inputBuffer->length - 2] == '\r' &&
ssh->inputBuffer->buffer[ssh->inputBuffer->length - 1] == '\n') {
gotLine = 1;
}
}
} while (!gotLine);
return WS_SUCCESS;
}
static int SendBuffer(WOLFSSH* ssh)
{
if (ssh->ctx->ioSendCb == NULL) {
WLOG(WS_LOG_DEBUG, "Your IO Send callback is null, please set");
return -1;
}
while (ssh->outputBuffer->length > 0) {
int sent = ssh->ctx->ioSendCb(ssh,
ssh->outputBuffer->buffer + ssh->outputBuffer->idx,
ssh->outputBuffer->length, ssh->ioWriteCtx);
if (sent < 0) {
return WS_SOCKET_ERROR_E;
}
if (sent > (int)ssh->outputBuffer->length) {
WLOG(WS_LOG_DEBUG, "Out of bounds read");
return WS_SEND_OOB_READ_E;
}
ssh->outputBuffer->idx += sent;
ssh->outputBuffer->length -= sent;
}
ssh->outputBuffer->idx = 0;
ShrinkBuffer(ssh->outputBuffer);
return WS_SUCCESS;
}
static int SendText(WOLFSSH* ssh, const char* text, uint32_t textLen)
{
GrowBuffer(ssh->outputBuffer, textLen, 0);
WMEMCPY(ssh->outputBuffer->buffer, text, textLen);
ssh->outputBuffer->length = textLen;
return SendBuffer(ssh);
}
static int GetInputData(WOLFSSH* ssh, uint32_t size)
{
int in;
int inSz;
int maxLength;
int usedLength;
/* check max input length */
usedLength = ssh->inputBuffer->length - ssh->inputBuffer->idx;
maxLength = ssh->inputBuffer->bufferSz - usedLength;
inSz = (int)(size - usedLength); /* from last partial read */
WLOG(WS_LOG_DEBUG, "GID: size = %d", size);
WLOG(WS_LOG_DEBUG, "GID: usedLength = %d", usedLength);
WLOG(WS_LOG_DEBUG, "GID: maxLength = %d", maxLength);
WLOG(WS_LOG_DEBUG, "GID: inSz = %d", inSz);
/*
* usedLength - how much untouched data is in the buffer
* maxLength - how much empty space is in the buffer
* inSz - difference between requested data and empty space in the buffer
* how much more we need to allocate
*/
if (inSz <= 0)
return WS_BUFFER_E;
/*
* If we need more space than there is left in the buffer grow buffer.
* Growing the buffer also compresses empty space at the head of the
* buffer and resets idx to 0.
*/
if (inSz > maxLength) {
if (GrowBuffer(ssh->inputBuffer, size, usedLength) < 0)
return WS_MEMORY_E;
}
/* Put buffer data at start if not there */
/* Compress the buffer if needed, i.e. buffer idx is non-zero */
if (usedLength > 0 && ssh->inputBuffer->idx != 0) {
WMEMMOVE(ssh->inputBuffer->buffer,
ssh->inputBuffer->buffer + ssh->inputBuffer->idx,
usedLength);
}
/* remove processed data */
ssh->inputBuffer->idx = 0;
ssh->inputBuffer->length = usedLength;
/* read data from network */
do {
in = Receive(ssh,
ssh->inputBuffer->buffer + ssh->inputBuffer->length, inSz);
if (in == -1)
return WS_SOCKET_ERROR_E;
if (in == WS_WANT_READ)
return WS_WANT_READ;
if (in > inSz)
return WS_RECV_OVERFLOW_E;
ssh->inputBuffer->length += in;
inSz -= in;
} while (ssh->inputBuffer->length < size);
return 0;
}
static int DoNameList(uint8_t* list, uint8_t* listSz,
uint8_t* buf, uint32_t len, uint32_t* idx)
{
uint8_t i = 0;
uint32_t nameListSz;
uint32_t begin = *idx;
(void)list;
if (begin >= len || begin + 4 >= len)
return -1;
ato32(buf + begin, &nameListSz);
begin += 4;
if (begin + nameListSz > len)
return -1;
begin += nameListSz;
/* list[0] = NameToId(nextName, 0); */
*listSz = i;
*idx = begin;
return WS_SUCCESS;
}
static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx)
{
uint8_t list[3];
uint8_t listSz;
uint32_t skipSz;
uint32_t begin = *idx;
/*
* I don't need to save what the client sends here. I should decode
* each list into a local array of IDs, and pick the one the peer is
* using that's on my known list, or verify that the one the peer can
* support the other direction is on my known list. All I need to do
* is save the actual values.
*
* Save the cookie for now. Maybe that is used in KEX.
*
* byte[16] cookie
* name-list kex_algorithms (2)
* name-list server_host_key_algorithms (1)
* name-list encryption_algorithms_client_to_server (3)
* name-list encryption_algorithms_server_to_client (3)
* name-list mac_algorithms_client_to_server (2)
* name-list mac_algorithms_server_to_client (2)
* name-list compression_algorithms_client_to_server (1)
* name-list compression_algorithms_server_to_client (1)
* name-list languages_client_to_server (0, skip)
* name-list languages_server_to_client (0, skip)
* boolean first_kex_packet_follows
* uint32 0 (reserved for future extension)
*/
/* Check that the cookie exists inside the message */
if (begin + COOKIE_SZ > len) {
/* error, out of bounds */
return -1;
}
/* Move past the cookie. */
begin += COOKIE_SZ;
/* KEX Algorithms */
listSz = 2;
DoNameList(list, &listSz, buf, len, &begin);
/* Server Host Key Algorithms */
listSz = 1;
DoNameList(list, &listSz, buf, len, &begin);
/* Enc Algorithms - Client to Server */
listSz = 3;
DoNameList(list, &listSz, buf, len, &begin);
/* Enc Algorithms - Server to Client */
listSz = 3;
DoNameList(list, &listSz, buf, len, &begin);
/* MAC Algorithms - Client to Server */
listSz = 2;
DoNameList(list, &listSz, buf, len, &begin);
/* MAC Algorithms - Server to Client */
listSz = 2;
DoNameList(list, &listSz, buf, len, &begin);
/* Compression Algorithms - Client to Server */
listSz = 1;
DoNameList(list, &listSz, buf, len, &begin);
/* verify the list contains "none" */
/* Compression Algorithms - Server to Client */
listSz = 1;
DoNameList(list, &listSz, buf, len, &begin);
/* verify the list contains "none" */
/* Languages - Client to Server, skip */
ato32(buf + begin, &skipSz);
begin += 4 + skipSz;
/* Languages - Server to Client, skip */
ato32(buf + begin, &skipSz);
begin += 4 + skipSz;
/* First KEX Packet Follows */
ssh->kexPacketFollows = buf[begin];
begin += 1;
/* Skip the "for future use" length. */
ato32(buf + begin, &skipSz);
begin += 4 + skipSz;
*idx = begin;
return WS_SUCCESS;
}
static int DoPacket(WOLFSSH* ssh)
{
uint8_t* buf = (uint8_t*)ssh->inputBuffer->buffer;
uint32_t idx = ssh->inputBuffer->idx;
uint32_t len = ssh->inputBuffer->length;
uint8_t msg;
uint8_t padSz;
padSz = buf[idx++];
msg = buf[idx++];
switch (msg) {
case SSH_MSG_KEXINIT:
WLOG(WS_LOG_DEBUG, "Decoding SSH_MSG_KEXINIT (len = %d)", len);
DoKexInit(ssh, buf, len, &idx);
break;
default:
WLOG(WS_LOG_DEBUG, "Unsupported message ID (%d)", msg);
break;
}
if (idx + padSz > len) {
return -1;
}
idx += padSz;
ssh->inputBuffer->idx = idx;
return WS_SUCCESS;
}
int ProcessReply(WOLFSSH* ssh)
{
int ret = WS_FATAL_ERROR;
int readSz;
(void)readSz;
for (;;) {
switch (ssh->processReplyState) {
case PROCESS_INIT:
readSz = ssh->blockSz;
WLOG(WS_LOG_DEBUG, "PR1: size = %d", readSz);
if ((ret = GetInputData(ssh, readSz)) < 0) {
return ret;
}
ssh->processReplyState = PROCESS_PACKET_LENGTH;
/* Decrypt first block if encrypted */
case PROCESS_PACKET_LENGTH:
ato32(ssh->inputBuffer->buffer + ssh->inputBuffer->idx, &ssh->curSz);
ssh->inputBuffer->idx += LENGTH_SZ;
ssh->processReplyState = PROCESS_PACKET_FINISH;
case PROCESS_PACKET_FINISH:
WLOG(WS_LOG_DEBUG, "PR2: size = %d", ssh->curSz);
if ((ret = GetInputData(ssh, ssh->curSz)) < 0) {
return ret;
}
ssh->processReplyState = PROCESS_PACKET;
/* Decrypt rest of packet here */
/* Check MAC here. */
case PROCESS_PACKET:
if ( (ret = DoPacket(ssh)) < 0) {
return ret;
}
break;
default:
WLOG(WS_LOG_DEBUG, "Bad process input state, programming error");
return WS_INPUT_CASE_E;
}
ssh->processReplyState = PROCESS_INIT;
return WS_SUCCESS;
}
}
static const char sshIdStr[] = "SSH-2.0-wolfSSHv" LIBWOLFSSH_VERSION_STRING "\r\n";
int ProcessClientVersion(WOLFSSH* ssh)
{
int error;
size_t protoLen = 7; /* Length of the SSH-2.0 portion of the ID str */
if ( (error = GetInputText(ssh)) < 0) {
WLOG(WS_LOG_DEBUG, "get input text failed");
return error;
}
if (WSTRNCASECMP((char*)ssh->inputBuffer->buffer,
sshIdStr, protoLen) == 0) {
ssh->clientState = CLIENT_VERSION_DONE;
}
else {
WLOG(WS_LOG_DEBUG, "SSH version mismatch");
return WS_VERSION_E;
}
ssh->peerId = (char*)WMALLOC(ssh->inputBuffer->length-1, ssh->ctx->heap, WOLFSSH_ID_TYPE);
if (ssh->peerId == NULL) {
return WS_MEMORY_E;
}
WMEMCPY(ssh->peerId, ssh->inputBuffer->buffer, ssh->inputBuffer->length-2);
ssh->peerId[ssh->inputBuffer->length - 1] = 0;
ssh->inputBuffer->idx += ssh->inputBuffer->length;
WLOG(WS_LOG_DEBUG, "%s", ssh->peerId);
return WS_SUCCESS;
}
int SendServerVersion(WOLFSSH* ssh)
{
(void)ssh;
WLOG(WS_LOG_DEBUG, "%s", sshIdStr);
SendText(ssh, sshIdStr, (uint32_t)WSTRLEN(sshIdStr));
return WS_FATAL_ERROR;
}

453
src/ssh.c
View File

@ -29,13 +29,6 @@
#include <wolfssh/log.h>
/* convert opaque to 32 bit integer */
static /*INLINE*/ void ato32(const uint8_t* c, uint32_t* u32)
{
*u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
}
int wolfSSH_Init(void)
{
WLOG(WS_LOG_DEBUG, "Enter wolfSSH_Init()");
@ -216,405 +209,6 @@ int wolfSSH_get_fd(const WOLFSSH* ssh)
}
static int Receive(WOLFSSH* ssh, uint8_t* buf, uint32_t sz)
{
int recvd;
if (ssh->ctx->ioRecvCb == NULL) {
WLOG(WS_LOG_DEBUG, "Your IO Recv callback is null, please set");
return -1;
}
retry:
recvd = ssh->ctx->ioRecvCb(ssh, buf, sz, ssh->ioReadCtx);
WLOG(WS_LOG_DEBUG, "Receive: recvd = %d", recvd);
if (recvd < 0)
switch (recvd) {
case WS_CBIO_ERR_GENERAL: /* general/unknown error */
return -1;
case WS_CBIO_ERR_WANT_READ: /* want read, would block */
return WS_WANT_READ;
case WS_CBIO_ERR_CONN_RST: /* connection reset */
ssh->connReset = 1;
return -1;
case WS_CBIO_ERR_ISR: /* interrupt */
goto retry;
case WS_CBIO_ERR_CONN_CLOSE: /* peer closed connection */
ssh->isClosed = 1;
return -1;
case WS_CBIO_ERR_TIMEOUT:
return -1;
default:
return recvd;
}
return recvd;
}
static int GetInputText(WOLFSSH* ssh)
{
int gotLine = 0;
int inSz = 255;
int in;
if (GrowBuffer(ssh->inputBuffer, inSz, 0) < 0)
return WS_MEMORY_E;
do {
in = Receive(ssh,
ssh->inputBuffer->buffer + ssh->inputBuffer->length, inSz);
if (in == -1)
return WS_SOCKET_ERROR_E;
if (in == WS_WANT_READ)
return WS_WANT_READ;
if (in > inSz)
return WS_RECV_OVERFLOW_E;
ssh->inputBuffer->length += in;
inSz -= in;
if (ssh->inputBuffer->length > 2) {
if (ssh->inputBuffer->buffer[ssh->inputBuffer->length - 2] == '\r' &&
ssh->inputBuffer->buffer[ssh->inputBuffer->length - 1] == '\n') {
gotLine = 1;
}
}
} while (!gotLine);
return WS_SUCCESS;
}
static int SendBuffer(WOLFSSH* ssh)
{
if (ssh->ctx->ioSendCb == NULL) {
WLOG(WS_LOG_DEBUG, "Your IO Send callback is null, please set");
return -1;
}
while (ssh->outputBuffer->length > 0) {
int sent = ssh->ctx->ioSendCb(ssh,
ssh->outputBuffer->buffer + ssh->outputBuffer->idx,
ssh->outputBuffer->length, ssh->ioWriteCtx);
if (sent < 0) {
return WS_SOCKET_ERROR_E;
}
if (sent > (int)ssh->outputBuffer->length) {
WLOG(WS_LOG_DEBUG, "Out of bounds read");
return WS_SEND_OOB_READ_E;
}
ssh->outputBuffer->idx += sent;
ssh->outputBuffer->length -= sent;
}
ssh->outputBuffer->idx = 0;
ShrinkBuffer(ssh->outputBuffer);
return WS_SUCCESS;
}
static int SendText(WOLFSSH* ssh, const char* text, uint32_t textLen)
{
GrowBuffer(ssh->outputBuffer, textLen, 0);
WMEMCPY(ssh->outputBuffer->buffer, text, textLen);
ssh->outputBuffer->length = textLen;
return SendBuffer(ssh);
}
static int GetInputData(WOLFSSH* ssh, uint32_t size)
{
int in;
int inSz;
int maxLength;
int usedLength;
/* check max input length */
usedLength = ssh->inputBuffer->length - ssh->inputBuffer->idx;
maxLength = ssh->inputBuffer->bufferSz - usedLength;
inSz = (int)(size - usedLength); /* from last partial read */
WLOG(WS_LOG_DEBUG, "GID: size = %d", size);
WLOG(WS_LOG_DEBUG, "GID: usedLength = %d", usedLength);
WLOG(WS_LOG_DEBUG, "GID: maxLength = %d", maxLength);
WLOG(WS_LOG_DEBUG, "GID: inSz = %d", inSz);
/*
* usedLength - how much untouched data is in the buffer
* maxLength - how much empty space is in the buffer
* inSz - difference between requested data and empty space in the buffer
* how much more we need to allocate
*/
if (inSz <= 0)
return WS_BUFFER_E;
/*
* If we need more space than there is left in the buffer grow buffer.
* Growing the buffer also compresses empty space at the head of the
* buffer and resets idx to 0.
*/
if (inSz > maxLength) {
if (GrowBuffer(ssh->inputBuffer, size, usedLength) < 0)
return WS_MEMORY_E;
}
/* Put buffer data at start if not there */
/* Compress the buffer if needed, i.e. buffer idx is non-zero */
if (usedLength > 0 && ssh->inputBuffer->idx != 0) {
WMEMMOVE(ssh->inputBuffer->buffer,
ssh->inputBuffer->buffer + ssh->inputBuffer->idx,
usedLength);
}
/* remove processed data */
ssh->inputBuffer->idx = 0;
ssh->inputBuffer->length = usedLength;
/* read data from network */
do {
in = Receive(ssh,
ssh->inputBuffer->buffer + ssh->inputBuffer->length, inSz);
if (in == -1)
return WS_SOCKET_ERROR_E;
if (in == WS_WANT_READ)
return WS_WANT_READ;
if (in > inSz)
return WS_RECV_OVERFLOW_E;
ssh->inputBuffer->length += in;
inSz -= in;
} while (ssh->inputBuffer->length < size);
return 0;
}
static int DoNameList(uint8_t* list, uint8_t* listSz,
uint8_t* buf, uint32_t len, uint32_t* idx)
{
uint8_t i = 0;
uint32_t nameListSz;
uint32_t begin = *idx;
(void)list;
if (begin >= len || begin + 4 >= len)
return -1;
ato32(buf + begin, &nameListSz);
begin += 4;
if (begin + nameListSz > len)
return -1;
begin += nameListSz;
/* list[0] = NameToId(nextName, 0); */
*listSz = i;
*idx = begin;
return WS_SUCCESS;
}
static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx)
{
uint8_t list[3];
uint8_t listSz;
uint32_t skipSz;
uint32_t begin = *idx;
/*
* I don't need to save what the client sends here. I should decode
* each list into a local array of IDs, and pick the one the peer is
* using that's on my known list, or verify that the one the peer can
* support the other direction is on my known list. All I need to do
* is save the actual values.
*
* Save the cookie for now. Maybe that is used in KEX.
*
* byte[16] cookie
* name-list kex_algorithms (2)
* name-list server_host_key_algorithms (1)
* name-list encryption_algorithms_client_to_server (3)
* name-list encryption_algorithms_server_to_client (3)
* name-list mac_algorithms_client_to_server (2)
* name-list mac_algorithms_server_to_client (2)
* name-list compression_algorithms_client_to_server (1)
* name-list compression_algorithms_server_to_client (1)
* name-list languages_client_to_server (0, skip)
* name-list languages_server_to_client (0, skip)
* boolean first_kex_packet_follows
* uint32 0 (reserved for future extension)
*/
/* Check that the cookie exists inside the message */
if (begin + COOKIE_SZ > len) {
/* error, out of bounds */
return -1;
}
/* Move past the cookie. */
begin += COOKIE_SZ;
/* KEX Algorithms */
listSz = 2;
DoNameList(list, &listSz, buf, len, &begin);
/* Server Host Key Algorithms */
listSz = 1;
DoNameList(list, &listSz, buf, len, &begin);
/* Enc Algorithms - Client to Server */
listSz = 3;
DoNameList(list, &listSz, buf, len, &begin);
/* Enc Algorithms - Server to Client */
listSz = 3;
DoNameList(list, &listSz, buf, len, &begin);
/* MAC Algorithms - Client to Server */
listSz = 2;
DoNameList(list, &listSz, buf, len, &begin);
/* MAC Algorithms - Server to Client */
listSz = 2;
DoNameList(list, &listSz, buf, len, &begin);
/* Compression Algorithms - Client to Server */
listSz = 1;
DoNameList(list, &listSz, buf, len, &begin);
/* verify the list contains "none" */
/* Compression Algorithms - Server to Client */
listSz = 1;
DoNameList(list, &listSz, buf, len, &begin);
/* verify the list contains "none" */
/* Languages - Client to Server, skip */
ato32(buf + begin, &skipSz);
begin += 4 + skipSz;
/* Languages - Server to Client, skip */
ato32(buf + begin, &skipSz);
begin += 4 + skipSz;
/* First KEX Packet Follows */
ssh->kexPacketFollows = buf[begin];
begin += 1;
/* Skip the "for future use" length. */
ato32(buf + begin, &skipSz);
begin += 4 + skipSz;
*idx = begin;
return WS_SUCCESS;
}
static int DoPacket(WOLFSSH* ssh)
{
uint8_t* buf = (uint8_t*)ssh->inputBuffer->buffer;
uint32_t idx = ssh->inputBuffer->idx;
uint32_t len = ssh->inputBuffer->length;
uint8_t msg;
uint8_t padSz;
padSz = buf[idx++];
msg = buf[idx++];
switch (msg) {
case SSH_MSG_KEXINIT:
WLOG(WS_LOG_DEBUG, "Decoding SSH_MSG_KEXINIT (len = %d)", len);
DoKexInit(ssh, buf, len, &idx);
break;
default:
WLOG(WS_LOG_DEBUG, "Unsupported message ID (%d)", msg);
break;
}
if (idx + padSz > len) {
return -1;
}
idx += padSz;
ssh->inputBuffer->idx = idx;
return WS_SUCCESS;
}
int ProcessReply(WOLFSSH* ssh)
{
int ret = WS_FATAL_ERROR;
int readSz;
(void)readSz;
for (;;) {
switch (ssh->processReplyState) {
case PROCESS_INIT:
readSz = ssh->blockSz;
WLOG(WS_LOG_DEBUG, "PR1: size = %d", readSz);
if ((ret = GetInputData(ssh, readSz)) < 0) {
return ret;
}
ssh->processReplyState = PROCESS_PACKET_LENGTH;
/* Decrypt first block if encrypted */
case PROCESS_PACKET_LENGTH:
ato32(ssh->inputBuffer->buffer + ssh->inputBuffer->idx, &ssh->curSz);
ssh->inputBuffer->idx += LENGTH_SZ;
ssh->processReplyState = PROCESS_PACKET_FINISH;
case PROCESS_PACKET_FINISH:
WLOG(WS_LOG_DEBUG, "PR2: size = %d", ssh->curSz);
if ((ret = GetInputData(ssh, ssh->curSz)) < 0) {
return ret;
}
ssh->processReplyState = PROCESS_PACKET;
/* Decrypt rest of packet here */
/* Check MAC here. */
case PROCESS_PACKET:
if ( (ret = DoPacket(ssh)) < 0) {
return ret;
}
break;
default:
WLOG(WS_LOG_DEBUG, "Bad process input state, programming error");
return WS_INPUT_CASE_E;
}
ssh->processReplyState = PROCESS_INIT;
return WS_SUCCESS;
}
}
int wolfSSH_accept(WOLFSSH* ssh)
{
switch (ssh->acceptState) {
@ -647,50 +241,3 @@ int wolfSSH_accept(WOLFSSH* ssh)
}
const char sshIdStr[] = "SSH-2.0-wolfSSHv" LIBWOLFSSH_VERSION_STRING "\r\n";
int ProcessClientVersion(WOLFSSH* ssh)
{
int error;
size_t protoLen = 7; /* Length of the SSH-2.0 portion of the ID str */
if ( (error = GetInputText(ssh)) < 0) {
WLOG(WS_LOG_DEBUG, "get input text failed");
return error;
}
if (WSTRNCASECMP((char*)ssh->inputBuffer->buffer,
sshIdStr, protoLen) == 0) {
ssh->clientState = CLIENT_VERSION_DONE;
}
else {
WLOG(WS_LOG_DEBUG, "SSH version mismatch");
return WS_VERSION_E;
}
ssh->peerId = (char*)WMALLOC(ssh->inputBuffer->length-1, ssh->ctx->heap, WOLFSSH_ID_TYPE);
if (ssh->peerId == NULL) {
return WS_MEMORY_E;
}
WMEMCPY(ssh->peerId, ssh->inputBuffer->buffer, ssh->inputBuffer->length-2);
ssh->peerId[ssh->inputBuffer->length - 1] = 0;
ssh->inputBuffer->idx += ssh->inputBuffer->length;
WLOG(WS_LOG_DEBUG, "%s", ssh->peerId);
return WS_SUCCESS;
}
int SendServerVersion(WOLFSSH* ssh)
{
(void)ssh;
WLOG(WS_LOG_DEBUG, "%s", sshIdStr);
SendText(ssh, sshIdStr, (uint32_t)WSTRLEN(sshIdStr));
return WS_FATAL_ERROR;
}

View File

@ -142,8 +142,8 @@ WOLFSSH_LOCAL int wsEmbedSend(WOLFSSH* ssh, void*, uint32_t sz, void* ctx);
WOLFSSH_LOCAL int ProcessReply(WOLFSSH*);
WOLFSSH_LOCAL int ProcessClientVersion(WOLFSSH*);
WOLFSSH_LOCAL int SendServerVersion(WOLFSSH*);
WOLFSSH_LOCAL int DoClientVersion(WOLFSSH*);
enum AcceptStates {