Skip to content

Commit ad38cc3

Browse files
Fix DoGlobalRequestFwd and Add the regress tests
1 parent cdd6df0 commit ad38cc3

File tree

2 files changed

+153
-4
lines changed

2 files changed

+153
-4
lines changed

src/internal.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8496,16 +8496,30 @@ static int DoGlobalRequestFwd(WOLFSSH* ssh,
84968496
isCancel ? " cancel" : "", bindAddr, bindPort);
84978497
}
84988498

8499-
if (ret == WS_SUCCESS && wantReply) {
8500-
ret = SendGlobalRequestFwdSuccess(ssh, 1, bindPort);
8501-
}
8502-
85038499
if (ret == WS_SUCCESS) {
85048500
if (ssh->ctx->fwdCb) {
85058501
ret = ssh->ctx->fwdCb(isCancel ? WOLFSSH_FWD_REMOTE_CLEANUP :
85068502
WOLFSSH_FWD_REMOTE_SETUP,
85078503
ssh->fwdCbCtx, bindAddr, bindPort);
85088504
}
8505+
else {
8506+
WLOG(WS_LOG_WARN, "No forwarding callback set, rejecting request. "
8507+
"Set one with wolfSSH_CTX_SetFwdCb().");
8508+
ret = WS_UNIMPLEMENTED_E;
8509+
}
8510+
}
8511+
8512+
if (wantReply) {
8513+
if (ret == WS_SUCCESS) {
8514+
ret = SendGlobalRequestFwdSuccess(ssh, 1, bindPort);
8515+
}
8516+
else {
8517+
ret = SendGlobalRequestFwdSuccess(ssh, 0, 0);
8518+
}
8519+
}
8520+
else if (ret == WS_UNIMPLEMENTED_E) {
8521+
/* No reply expected; silently reject without terminating connection. */
8522+
ret = WS_SUCCESS;
85098523
}
85108524

85118525
if (bindAddr != NULL)

tests/regress.c

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,21 @@ static word32 BuildDirectTcpipExtra(const char* host, word32 hostPort,
231231

232232
return idx;
233233
}
234+
235+
static word32 BuildGlobalRequestFwdPacket(const char* bindAddr, word32 bindPort,
236+
int isCancel, byte wantReply, byte* out, word32 outSz)
237+
{
238+
byte payload[256];
239+
word32 idx = 0;
240+
const char* reqName = isCancel ? "cancel-tcpip-forward" : "tcpip-forward";
241+
242+
idx = AppendString(payload, sizeof(payload), idx, reqName);
243+
idx = AppendByte (payload, sizeof(payload), idx, wantReply);
244+
idx = AppendString(payload, sizeof(payload), idx, bindAddr);
245+
idx = AppendUint32(payload, sizeof(payload), idx, bindPort);
246+
247+
return WrapPacket(MSGID_GLOBAL_REQUEST, payload, idx, out, outSz);
248+
}
234249
#endif
235250

236251
/* Simple in-memory transport harness */
@@ -957,6 +972,15 @@ static void AssertChannelOpenFailResponse(const ChannelOpenHarness* harness,
957972
AssertTrue(harness->ssh->channelList == NULL);
958973
}
959974

975+
#ifdef WOLFSSH_FWD
976+
static void AssertGlobalRequestReply(const ChannelOpenHarness* harness,
977+
byte expectedMsgId)
978+
{
979+
AssertTrue(harness->io.outSz > 0);
980+
AssertIntEQ(ParseMsgId(harness->io.out, harness->io.outSz), expectedMsgId);
981+
}
982+
#endif
983+
960984
static int RejectChannelOpenCb(WOLFSSH_CHANNEL* channel, void* ctx)
961985
{
962986
(void)channel;
@@ -978,6 +1002,17 @@ static int RejectDirectTcpipSetup(WS_FwdCbAction action, void* ctx,
9781002

9791003
return WS_SUCCESS;
9801004
}
1005+
1006+
static int AcceptFwdCb(WS_FwdCbAction action, void* ctx,
1007+
const char* host, word32 port)
1008+
{
1009+
(void)action;
1010+
(void)ctx;
1011+
(void)host;
1012+
(void)port;
1013+
1014+
return WS_SUCCESS;
1015+
}
9811016
#endif
9821017

9831018

@@ -1239,6 +1274,101 @@ static void TestDirectTcpipNoFwdCbSendsOpenFail(void)
12391274

12401275
ret = DoReceive(harness.ssh);
12411276
AssertChannelOpenFailResponse(&harness, ret);
1277+
1278+
FreeChannelOpenHarness(&harness);
1279+
}
1280+
1281+
static void TestGlobalRequestFwdNoCbSendsFailure(void)
1282+
{
1283+
ChannelOpenHarness harness;
1284+
byte in[256];
1285+
word32 inSz;
1286+
int ret;
1287+
1288+
inSz = BuildGlobalRequestFwdPacket("0.0.0.0", 2222, 0, 1, in, sizeof(in));
1289+
InitChannelOpenHarness(&harness, in, inSz);
1290+
/* no fwdCb registered */
1291+
1292+
ret = DoReceive(harness.ssh);
1293+
1294+
AssertIntEQ(ret, WS_SUCCESS);
1295+
AssertGlobalRequestReply(&harness, MSGID_REQUEST_FAILURE);
1296+
1297+
FreeChannelOpenHarness(&harness);
1298+
}
1299+
1300+
static void TestGlobalRequestFwdNoCbNoReplyKeepsConnection(void)
1301+
{
1302+
ChannelOpenHarness harness;
1303+
byte in[256];
1304+
word32 inSz;
1305+
int ret;
1306+
1307+
/* wantReply=0: no reply sent, connection must stay alive */
1308+
inSz = BuildGlobalRequestFwdPacket("0.0.0.0", 2222, 0, 0, in, sizeof(in));
1309+
InitChannelOpenHarness(&harness, in, inSz);
1310+
/* no fwdCb registered */
1311+
1312+
ret = DoReceive(harness.ssh);
1313+
1314+
AssertIntEQ(ret, WS_SUCCESS);
1315+
AssertIntEQ(harness.io.outSz, 0); /* no reply sent */
1316+
1317+
FreeChannelOpenHarness(&harness);
1318+
}
1319+
1320+
static void TestGlobalRequestFwdWithCbSendsSuccess(void)
1321+
{
1322+
ChannelOpenHarness harness;
1323+
byte in[256];
1324+
word32 inSz;
1325+
int ret;
1326+
1327+
inSz = BuildGlobalRequestFwdPacket("0.0.0.0", 2222, 0, 1, in, sizeof(in));
1328+
InitChannelOpenHarness(&harness, in, inSz);
1329+
AssertIntEQ(wolfSSH_CTX_SetFwdCb(harness.ctx, AcceptFwdCb, NULL), WS_SUCCESS);
1330+
1331+
ret = DoReceive(harness.ssh);
1332+
1333+
AssertIntEQ(ret, WS_SUCCESS);
1334+
AssertGlobalRequestReply(&harness, MSGID_REQUEST_SUCCESS);
1335+
1336+
FreeChannelOpenHarness(&harness);
1337+
}
1338+
1339+
static void TestGlobalRequestFwdCancelNoCbSendsFailure(void)
1340+
{
1341+
ChannelOpenHarness harness;
1342+
byte in[256];
1343+
word32 inSz;
1344+
int ret;
1345+
1346+
inSz = BuildGlobalRequestFwdPacket("0.0.0.0", 2222, 1, 1, in, sizeof(in));
1347+
InitChannelOpenHarness(&harness, in, inSz);
1348+
1349+
ret = DoReceive(harness.ssh);
1350+
1351+
AssertIntEQ(ret, WS_SUCCESS);
1352+
AssertGlobalRequestReply(&harness, MSGID_REQUEST_FAILURE);
1353+
1354+
FreeChannelOpenHarness(&harness);
1355+
}
1356+
1357+
static void TestGlobalRequestFwdCancelWithCbSendsSuccess(void)
1358+
{
1359+
ChannelOpenHarness harness;
1360+
byte in[256];
1361+
word32 inSz;
1362+
int ret;
1363+
1364+
inSz = BuildGlobalRequestFwdPacket("0.0.0.0", 2222, 1, 1, in, sizeof(in));
1365+
InitChannelOpenHarness(&harness, in, inSz);
1366+
AssertIntEQ(wolfSSH_CTX_SetFwdCb(harness.ctx, AcceptFwdCb, NULL), WS_SUCCESS);
1367+
1368+
ret = DoReceive(harness.ssh);
1369+
1370+
AssertIntEQ(ret, WS_SUCCESS);
1371+
AssertGlobalRequestReply(&harness, MSGID_REQUEST_SUCCESS);
12421372

12431373
FreeChannelOpenHarness(&harness);
12441374
}
@@ -1707,6 +1837,11 @@ int main(int argc, char** argv)
17071837
#ifdef WOLFSSH_FWD
17081838
TestDirectTcpipRejectSendsOpenFail();
17091839
TestDirectTcpipNoFwdCbSendsOpenFail();
1840+
TestGlobalRequestFwdNoCbSendsFailure();
1841+
TestGlobalRequestFwdNoCbNoReplyKeepsConnection();
1842+
TestGlobalRequestFwdWithCbSendsSuccess();
1843+
TestGlobalRequestFwdCancelNoCbSendsFailure();
1844+
TestGlobalRequestFwdCancelWithCbSendsSuccess();
17101845
#endif
17111846
#ifdef WOLFSSH_AGENT
17121847
TestAgentChannelNullAgentSendsOpenFail();

0 commit comments

Comments
 (0)