mirror of https://github.com/wolfSSL/wolfssh.git
Gate forwarded-tcpip opens like direct-tcpip
- forwarded-tcpip was never gated; fell through to default-accept channelOpenCb. - Require fwdCb for both forwarding channel types, failing closed without it. - Reject server-side forwarded-tcpip opens before any policy hook runs. - Add regress coverage for both rejections. Issue: F-6275pull/1042/head
parent
673b2d25e7
commit
616eb681e7
|
|
@ -9266,23 +9266,45 @@ static int DoChannelOpen(WOLFSSH* ssh,
|
|||
else {
|
||||
ChannelUpdatePeer(newChannel, peerChannelId,
|
||||
peerInitialWindowSz, peerMaxPacketSz);
|
||||
if (ssh->ctx->channelOpenCb) {
|
||||
ret = ssh->ctx->channelOpenCb(newChannel, ssh->channelOpenCtx);
|
||||
}
|
||||
else {
|
||||
WLOG(WS_LOG_WARN, "No channel open callback set "
|
||||
"(call wolfSSH_CTX_SetChannelOpenCb()), accepting "
|
||||
"channel open by default; typeId=%u, peerChannelId=%u",
|
||||
(word32)typeId, peerChannelId);
|
||||
}
|
||||
if (ssh->channelListSz == 0)
|
||||
ssh->defaultPeerChannelId = peerChannelId;
|
||||
#ifdef WOLFSSH_FWD
|
||||
if (typeId == ID_CHANTYPE_TCPIP_DIRECT) {
|
||||
ChannelUpdateForward(newChannel,
|
||||
host, hostPort, origin, originPort, isDirect);
|
||||
|
||||
/* A forwarded-tcpip open is a server-to-client message sent in
|
||||
* response to a tcpip-forward request, so only a client should
|
||||
* ever receive one. Reject opens arriving in the wrong direction
|
||||
* up front, before any policy callback runs or channel state is
|
||||
* updated. direct-tcpip is intentionally not direction-checked:
|
||||
* either forwarding side may legitimately request a direct
|
||||
* forward. */
|
||||
if (typeId == ID_CHANTYPE_TCPIP_FORWARD &&
|
||||
ssh->ctx->side == WOLFSSH_ENDPOINT_SERVER) {
|
||||
WLOG(WS_LOG_WARN, "Rejecting forwarded-tcpip channel open "
|
||||
"received by a server (wrong direction)");
|
||||
fail_reason = OPEN_ADMINISTRATIVELY_PROHIBITED;
|
||||
ret = WS_ERROR;
|
||||
}
|
||||
#endif /* WOLFSSH_FWD */
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (ssh->ctx->channelOpenCb) {
|
||||
ret = ssh->ctx->channelOpenCb(newChannel,
|
||||
ssh->channelOpenCtx);
|
||||
}
|
||||
else {
|
||||
WLOG(WS_LOG_WARN, "No channel open callback set "
|
||||
"(call wolfSSH_CTX_SetChannelOpenCb()), accepting "
|
||||
"channel open by default; typeId=%u, "
|
||||
"peerChannelId=%u",
|
||||
(word32)typeId, peerChannelId);
|
||||
}
|
||||
if (ssh->channelListSz == 0)
|
||||
ssh->defaultPeerChannelId = peerChannelId;
|
||||
}
|
||||
#ifdef WOLFSSH_FWD
|
||||
if (ret == WS_SUCCESS &&
|
||||
(typeId == ID_CHANTYPE_TCPIP_DIRECT ||
|
||||
typeId == ID_CHANTYPE_TCPIP_FORWARD)) {
|
||||
if (ssh->ctx->fwdCb) {
|
||||
ChannelUpdateForward(newChannel,
|
||||
host, hostPort, origin, originPort, isDirect);
|
||||
|
||||
ret = ssh->ctx->fwdCb(WOLFSSH_FWD_LOCAL_SETUP,
|
||||
ssh->fwdCbCtx, host, hostPort);
|
||||
if (ret == WS_SUCCESS) {
|
||||
|
|
@ -9291,8 +9313,11 @@ static int DoChannelOpen(WOLFSSH* ssh,
|
|||
}
|
||||
}
|
||||
else {
|
||||
WLOG(WS_LOG_WARN, "No forward callback set for direct-tcpip channel,"
|
||||
" failing channel open");
|
||||
/* Both forwarding channel types require an explicit policy
|
||||
* callback; without one, fail closed rather than letting
|
||||
* the default-accept channelOpenCb path admit them. */
|
||||
WLOG(WS_LOG_WARN, "No forward callback set for forwarding "
|
||||
"channel, failing channel open");
|
||||
fail_reason = OPEN_ADMINISTRATIVELY_PROHIBITED;
|
||||
ret = WS_ERROR;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1525,6 +1525,33 @@ static void TestDirectTcpipNoFwdCbSendsOpenFail(void)
|
|||
FreeChannelOpenHarness(&harness);
|
||||
}
|
||||
|
||||
static void TestForwardedTcpipOnServerSendsOpenFail(void)
|
||||
{
|
||||
ChannelOpenHarness harness;
|
||||
byte extra[128];
|
||||
byte in[192];
|
||||
word32 extraSz;
|
||||
word32 inSz;
|
||||
int ret;
|
||||
|
||||
/* forwarded-tcpip is only ever sent server-to-client. A server receiving
|
||||
* one is the wrong direction and must be rejected even with a fwdCb set,
|
||||
* before the forwarding policy hook runs. */
|
||||
extraSz = BuildDirectTcpipExtra("127.0.0.1", 8080, "127.0.0.1", 2222,
|
||||
extra, sizeof(extra));
|
||||
inSz = BuildChannelOpenPacket("forwarded-tcpip", 9, 0x4000, 0x8000,
|
||||
extra, extraSz, in, sizeof(in));
|
||||
|
||||
InitChannelOpenHarness(&harness, in, inSz);
|
||||
AssertIntEQ(wolfSSH_CTX_SetFwdCb(harness.ctx, AcceptFwdCb, NULL),
|
||||
WS_SUCCESS);
|
||||
|
||||
ret = DoReceive(harness.ssh);
|
||||
AssertChannelOpenFailResponse(&harness, ret);
|
||||
|
||||
FreeChannelOpenHarness(&harness);
|
||||
}
|
||||
|
||||
static void TestGlobalRequestFwdNoCbSendsFailure(void)
|
||||
{
|
||||
ChannelOpenHarness harness;
|
||||
|
|
@ -4133,6 +4160,7 @@ int main(int argc, char** argv)
|
|||
#ifdef WOLFSSH_FWD
|
||||
TestDirectTcpipRejectSendsOpenFail();
|
||||
TestDirectTcpipNoFwdCbSendsOpenFail();
|
||||
TestForwardedTcpipOnServerSendsOpenFail();
|
||||
TestGlobalRequestFwdNoCbSendsFailure();
|
||||
TestGlobalRequestFwdNoCbNoReplyKeepsConnection();
|
||||
TestGlobalRequestFwdWithCbSendsSuccess();
|
||||
|
|
|
|||
Loading…
Reference in New Issue