Skip to content

Commit

Permalink
Merge pull request wolfSSL#553 from falemagn/pull-reqs/bb7773a_Correc…
Browse files Browse the repository at this point in the history
…tly_send_out_the_CHANNEL_OPEN_FAIL_message_in_case_opening_a_channel_didnt_succeed

Correctly send out the CHANNEL_OPEN_FAIL message on failure.
  • Loading branch information
JacobBarthelmeh authored Aug 8, 2023
2 parents 837393a + ed82a1b commit 1015a8b
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 2 deletions.
80 changes: 78 additions & 2 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -6362,6 +6362,7 @@ static int DoChannelOpen(WOLFSSH* ssh,
#endif /* WOLFSSH_FWD */
WOLFSSH_CHANNEL* newChannel = NULL;
int ret = WS_SUCCESS;
word32 fail_reason = OPEN_OK;

WLOG(WS_LOG_DEBUG, "Entering DoChannelOpen()");

Expand Down Expand Up @@ -6392,6 +6393,10 @@ static int DoChannelOpen(WOLFSSH* ssh,
typeId = NameToId(type, typeSz);
switch (typeId) {
case ID_CHANTYPE_SESSION:
if (ssh->channelListSz >= 1) {
ret = WS_INVALID_CHANID;
fail_reason = OPEN_ADMINISTRATIVELY_PROHIBITED;
}
break;
#ifdef WOLFSSH_FWD
case ID_CHANTYPE_TCPIP_DIRECT:
Expand All @@ -6414,6 +6419,7 @@ static int DoChannelOpen(WOLFSSH* ssh,
#endif
default:
ret = WS_INVALID_CHANTYPE;
fail_reason = OPEN_UNKNOWN_CHANNEL_TYPE;
}
}

Expand All @@ -6422,8 +6428,10 @@ static int DoChannelOpen(WOLFSSH* ssh,

newChannel = ChannelNew(ssh, typeId,
ssh->ctx->windowSz, ssh->ctx->maxPacketSz);
if (newChannel == NULL)
if (newChannel == NULL) {
ret = WS_RESOURCE_E;
fail_reason = OPEN_RESOURCE_SHORTAGE;
}
else {
ChannelUpdatePeer(newChannel, peerChannelId,
peerInitialWindowSz, peerMaxPacketSz);
Expand All @@ -6450,8 +6458,24 @@ static int DoChannelOpen(WOLFSSH* ssh,
}
}

if (ret == WS_SUCCESS)
if (ret == WS_SUCCESS) {
ret = SendChannelOpenConf(ssh, newChannel);
}
else {
const char *description = NULL;

if (fail_reason == OPEN_ADMINISTRATIVELY_PROHIBITED)
description = "Each session cannot have more than one channel open.";
else if (fail_reason == OPEN_UNKNOWN_CHANNEL_TYPE)
description = "Channel type not supported.";
else if (fail_reason == OPEN_RESOURCE_SHORTAGE)
description = "Not enough resources.";

if (description != NULL)
ret = SendChannelOpenFail(ssh, peerChannelId, fail_reason, description, "en");
else
ret = SendRequestSuccess(ssh, 0);
}

#ifdef WOLFSSH_FWD
/* ChannelUpdateForward makes new host and origin buffer */
Expand Down Expand Up @@ -12190,6 +12214,58 @@ int SendChannelOpenConf(WOLFSSH* ssh, WOLFSSH_CHANNEL* channel)
return ret;
}

int SendChannelOpenFail(WOLFSSH* ssh, word32 channel, word32 reason, const char *description, const char *language)
{
byte* output;
word32 idx;
word32 descriptionSz = (word32)WSTRLEN(description);
word32 languageSz = (word32)WSTRLEN(language);
int ret = WS_SUCCESS;

WLOG(WS_LOG_DEBUG, "Entering SendChannelOpenFail()");

if (ssh == NULL)
ret = WS_BAD_ARGUMENT;

if (ret == WS_SUCCESS) {
WLOG(WS_LOG_INFO, " channelId = %u", channel);
WLOG(WS_LOG_INFO, " reason = %u", reason);
WLOG(WS_LOG_INFO, " description = %s", description);
WLOG(WS_LOG_INFO, " language = %s", language);
}

if (ret == WS_SUCCESS)
ret = PreparePacket(ssh, MSG_ID_SZ + UINT32_SZ + UINT32_SZ + LENGTH_SZ + descriptionSz + LENGTH_SZ + languageSz);

if (ret == WS_SUCCESS) {
output = ssh->outputBuffer.buffer;
idx = ssh->outputBuffer.length;

output[idx++] = MSGID_CHANNEL_OPEN_FAIL;
c32toa(channel, output + idx);
idx += UINT32_SZ;
c32toa(reason, output + idx);
idx += UINT32_SZ;
c32toa(descriptionSz, output + idx);
idx += UINT32_SZ;
WMEMCPY(output + idx, description, descriptionSz);
idx += descriptionSz;
c32toa(languageSz, output + idx);
idx += UINT32_SZ;
WMEMCPY(output + idx, language, languageSz);
idx += languageSz;

ssh->outputBuffer.length = idx;

ret = BundlePacket(ssh);
}

if (ret == WS_SUCCESS)
ret = wolfSSH_SendPacket(ssh);

WLOG(WS_LOG_DEBUG, "Leaving SendChannelOpenFail(), ret = %d", ret);
return ret;
}

int SendChannelEof(WOLFSSH* ssh, word32 peerChannelId)
{
Expand Down
8 changes: 8 additions & 0 deletions wolfssh/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,13 @@ WOLFSSH_LOCAL int wsEmbedSend(WOLFSSH*, void*, word32, void*);

#endif /* WOLFSSH_USER_IO */

enum ChannelOpenFailReasons {
OPEN_OK = 0,
OPEN_ADMINISTRATIVELY_PROHIBITED,
OPEN_CONNECT_FAILED,
OPEN_UNKNOWN_CHANNEL_TYPE,
OPEN_RESOURCE_SHORTAGE
};

WOLFSSH_LOCAL int DoReceive(WOLFSSH*);
WOLFSSH_LOCAL int DoProtoId(WOLFSSH*);
Expand Down Expand Up @@ -907,6 +914,7 @@ WOLFSSH_LOCAL int SendRequestSuccess(WOLFSSH*, int);
WOLFSSH_LOCAL int SendChannelOpenSession(WOLFSSH*, WOLFSSH_CHANNEL*);
WOLFSSH_LOCAL int SendChannelOpenForward(WOLFSSH*, WOLFSSH_CHANNEL*);
WOLFSSH_LOCAL int SendChannelOpenConf(WOLFSSH*, WOLFSSH_CHANNEL*);
WOLFSSH_LOCAL int SendChannelOpenFail(WOLFSSH*, word32, word32, const char*, const char*);
WOLFSSH_LOCAL int SendChannelEof(WOLFSSH*, word32);
WOLFSSH_LOCAL int SendChannelEow(WOLFSSH*, word32);
WOLFSSH_LOCAL int SendChannelClose(WOLFSSH*, word32);
Expand Down

0 comments on commit 1015a8b

Please sign in to comment.