Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -12599,8 +12599,8 @@ static int DoGlobalRequestFwd(WOLFSSH* ssh,
WLOG(WS_LOG_WARN, "Forward cleanup after rejection failed, "
"ret = %d", cleanupRet);
}
ret = WS_RESOURCE_E;
}
ret = WS_RESOURCE_E;
}
}

Expand Down Expand Up @@ -12895,6 +12895,14 @@ static int DoChannelOpen(WOLFSSH* ssh,
if (ret == WS_SUCCESS)
ret = GetUint32(&peerMaxPacketSz, buf, len, &begin);

if (ret == WS_SUCCESS && ssh->channelListSz >= WOLFSSH_MAX_CHANNELS) {
Comment thread
ejohnstown marked this conversation as resolved.
Resolved
/* Per peer open, so DEBUG. */
WLOG(WS_LOG_DEBUG, "Rejecting channel open, %u channels open",
ssh->channelListSz);
ret = WS_RESOURCE_E;
fail_reason = OPEN_RESOURCE_SHORTAGE;
Comment thread
ejohnstown marked this conversation as resolved.
Resolved
}

if (ret == WS_SUCCESS) {
WLOG(WS_LOG_INFO, " type = %s", type);
WLOG(WS_LOG_INFO, " peerChannelId = %u", peerChannelId);
Expand Down
68 changes: 67 additions & 1 deletion tests/regress.c
Original file line number Diff line number Diff line change
Expand Up @@ -4817,6 +4817,7 @@ static void TestAgentRelayChannelDrainsOversizeBacklog(void)
FreeChannelOpenHarness(&harness.base);
}

#if WOLFSSH_MAX_CHANNELS >= 2 /* opens a second channel */
/* A partial request on one channel is dropped rather than prepended to the
* next channel's data. */
static void TestAgentRelayChannelResetsOnChannelChange(void)
Expand Down Expand Up @@ -4851,6 +4852,7 @@ static void TestAgentRelayChannelResetsOnChannelChange(void)

FreeChannelOpenHarness(&harness.base);
}
#endif

/* A declared length past the build's ceiling is refused and nothing is sent
* to the agent. */
Expand Down Expand Up @@ -5357,6 +5359,7 @@ static void TestAgentRelayChannelFlushesUnderRekey(void)
}


#if WOLFSSH_MAX_CHANNELS >= 2 /* opens a second channel */
/* Shifting a held request down leaves a copy of it above the buffer's
* length, and a channel change scrubs that copy too. */
static void TestAgentRelayChannelScrubsShiftedRequest(void)
Expand Down Expand Up @@ -5406,6 +5409,7 @@ static void TestAgentRelayChannelScrubsShiftedRequest(void)

FreeChannelOpenHarness(&harness.base);
}
#endif


#endif /* WOLFSSH_AGENT */
Expand Down Expand Up @@ -5868,6 +5872,11 @@ static void TestSecondSessionChannelRejected(void)
word32 in1Sz;
word32 in2Sz;
int ret;
#if WOLFSSH_MAX_CHANNELS < 2
const word32 reason = OPEN_RESOURCE_SHORTAGE;
#else
const word32 reason = OPEN_ADMINISTRATIVELY_PROHIBITED;
#endif

in1Sz = BuildChannelOpenPacket("session", 7, 0x4000, 0x8000,
NULL, 0, in1, sizeof(in1));
Expand Down Expand Up @@ -5902,7 +5911,7 @@ static void TestSecondSessionChannelRejected(void)
AssertIntEQ(ParseChannelOpenFailRecipient(harness.io.out, harness.io.outSz),
8); /* RFC 4254 5.1: server must echo the peer's channel ID */
AssertIntEQ(ParseChannelOpenFailReason(harness.io.out, harness.io.outSz),
OPEN_ADMINISTRATIVELY_PROHIBITED);
reason);
AssertIntEQ(harness.ssh->channelListSz, 1); /* original channel intact */

FreeChannelOpenHarness(&harness);
Expand Down Expand Up @@ -8842,6 +8851,54 @@ static void TestDirectTcpipNoFwdCbSendsOpenFail(void)
FreeChannelOpenHarness(&harness);
}

/* Peer opens up to WOLFSSH_MAX_CHANNELS are accepted; the next is refused
* with OPEN_RESOURCE_SHORTAGE, the session stays up, and closing a channel
* makes room again. */
static void TestChannelOpenPastCapSendsResourceShortage(void)
{
ChannelOpenHarness harness;
byte extra[128];
byte in[192];
word32 extraSz;
word32 inSz;
word32 i;

extraSz = BuildDirectTcpipExtra("127.0.0.1", 8080, "127.0.0.1", 2222,
extra, sizeof(extra));

InitChannelOpenHarness(&harness, NULL, 0);
AssertIntEQ(wolfSSH_CTX_SetFwdCb(harness.ctx, AcceptFwdCb, NULL),
WS_SUCCESS);
/* Keep the test's footprint small; the cap is on count, not size. */
AssertIntEQ(wolfSSH_CTX_SetWindowPacketSize(harness.ctx, 1024, 1024),
WS_SUCCESS);

for (i = 0; i < WOLFSSH_MAX_CHANNELS; i++) {
inSz = BuildChannelOpenPacket("direct-tcpip", 100 + i, 0x4000, 0x8000,
extra, extraSz, in, sizeof(in));
AssertIntEQ(ReplyToPacket(&harness, in, inSz),
MSGID_CHANNEL_OPEN_CONF);
}
AssertIntEQ(harness.ssh->channelListSz, WOLFSSH_MAX_CHANNELS);

inSz = BuildChannelOpenPacket("direct-tcpip", 9, 0x4000, 0x8000,
extra, extraSz, in, sizeof(in));
AssertIntEQ(ReplyToPacket(&harness, in, inSz), MSGID_CHANNEL_OPEN_FAIL);
AssertIntEQ(ParseChannelOpenFailRecipient(harness.io.out,
harness.io.outSz), 9);
AssertIntEQ(ParseChannelOpenFailReason(harness.io.out, harness.io.outSz),
OPEN_RESOURCE_SHORTAGE);
AssertIntEQ(harness.ssh->channelListSz, WOLFSSH_MAX_CHANNELS);
AssertFalse(harness.ssh->disconnected);

AssertIntEQ(ChannelRemove(harness.ssh, 100, WS_CHANNEL_ID_PEER),
WS_SUCCESS);
AssertIntEQ(ReplyToPacket(&harness, in, inSz), MSGID_CHANNEL_OPEN_CONF);
AssertIntEQ(harness.ssh->channelListSz, WOLFSSH_MAX_CHANNELS);

FreeChannelOpenHarness(&harness);
}

/* Both a channelOpenCb and a fwdCb registered, open callback rejects. The
* rejection has to stand: the forwarding hook must not run, and must not
* overwrite the rejection with its own return. That clobber shipped in
Expand Down Expand Up @@ -13226,6 +13283,7 @@ static void TestForwardedTcpipPortZeroFoldSettlesQueuedCancel(void)
FreeChannelOpenHarness(&harness);
}

#if WOLFSSH_MAX_CHANNELS >= 2 /* opens a second channel */
static void TestForwardedTcpipRepliesPairInSendOrder(void)
{
ChannelOpenHarness harness;
Expand Down Expand Up @@ -13253,6 +13311,7 @@ static void TestForwardedTcpipRepliesPairInSendOrder(void)

FreeChannelOpenHarness(&harness);
}
#endif

/* A port-0 request whose reply names no usable port leaves nothing to match
* on, so the registration goes. */
Expand Down Expand Up @@ -21942,7 +22001,9 @@ int main(int argc, char** argv)
TestAgentRelayChannelReassemblesFragmentedRequest();
TestAgentRelayChannelKeepsTrailingBytes();
TestAgentRelayChannelDrainsOversizeBacklog();
#if WOLFSSH_MAX_CHANNELS >= 2
TestAgentRelayChannelResetsOnChannelChange();
#endif
TestAgentRelayChannelRejectsOversizeLength();
TestAgentRelayChannelRejectsZeroLength();
TestAgentRelayChannelReplyReachesChannel();
Expand All @@ -21960,9 +22021,11 @@ int main(int argc, char** argv)
TestAgentRelayChannelReconnectsOnDeadSocket();
TestAgentRelayChannelHoldsOnRekey();
TestAgentRelayChannelFlushesUnderRekey();
#if WOLFSSH_MAX_CHANNELS >= 2
TestAgentRelayChannelScrubsShiftedRequest();
#endif
#endif
#endif
#if defined(WOLFSSH_AGENT) && !defined(NO_WOLFSSH_SERVER)
TestAgentOpenOnServerFails();
#endif
Expand Down Expand Up @@ -22052,6 +22115,7 @@ int main(int argc, char** argv)
#ifdef WOLFSSH_FWD
TestDirectTcpipRejectSendsOpenFail();
TestDirectTcpipNoFwdCbSendsOpenFail();
TestChannelOpenPastCapSendsResourceShortage();
TestDirectTcpipOpenCbRejectBeatsFwdCb();
TestDirectTcpipFwdCbRejectAfterOpenCbAccept();
TestDirectTcpipFwdCbRejectsChannelId();
Expand Down Expand Up @@ -22211,7 +22275,9 @@ int main(int argc, char** argv)
TestForwardedTcpipInterruptedSendStillRegisters();
TestInterruptedSendRetriesForAnySender();
TestGlobalRequestNoReplyQueuesNothing();
#if WOLFSSH_MAX_CHANNELS >= 2
TestForwardedTcpipRepliesPairInSendOrder();
#endif
TestForwardedTcpipUnusablePortReplySendsOpenFail();
TestForwardedTcpipPortZeroOtherPortSendsOpenFail();
#endif /* WOLFSSH_FWD && !NO_WOLFSSH_CLIENT */
Expand Down
8 changes: 8 additions & 0 deletions wolfssh/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,14 @@ enum NameIdType {
* MaxAuthTries default. */
#define DEFAULT_MAX_AUTH_ATTEMPTS 6
#endif
#ifndef WOLFSSH_MAX_CHANNELS
/* Cap on open channels; a peer CHANNEL_OPEN past it is refused with
* OPEN_RESOURCE_SHORTAGE. Each channel holds a window-sized buffer. */
#define WOLFSSH_MAX_CHANNELS 64
#endif
#if WOLFSSH_MAX_CHANNELS < 1
#error "WOLFSSH_MAX_CHANNELS must be at least 1"
#endif
#ifndef MAX_PACKET_SZ
/* This is from RFC 4253 section 6.1. */
#define MAX_PACKET_SZ 35000
Expand Down
Loading