Skip to content

Commit 0a795af

Browse files
Fix DoGlobalRequestFwd and Add the regress tests
1 parent 9c8b4e8 commit 0a795af

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 */
@@ -922,6 +937,15 @@ static void AssertChannelOpenFailResponse(const ChannelOpenHarness* harness,
922937
AssertTrue(harness->ssh->channelList == NULL);
923938
}
924939

940+
#ifdef WOLFSSH_FWD
941+
static void AssertGlobalRequestReply(const ChannelOpenHarness* harness,
942+
byte expectedMsgId)
943+
{
944+
AssertTrue(harness->io.outSz > 0);
945+
AssertIntEQ(ParseMsgId(harness->io.out, harness->io.outSz), expectedMsgId);
946+
}
947+
#endif
948+
925949
static int RejectChannelOpenCb(WOLFSSH_CHANNEL* channel, void* ctx)
926950
{
927951
(void)channel;
@@ -943,6 +967,17 @@ static int RejectDirectTcpipSetup(WS_FwdCbAction action, void* ctx,
943967

944968
return WS_SUCCESS;
945969
}
970+
971+
static int AcceptFwdCb(WS_FwdCbAction action, void* ctx,
972+
const char* host, word32 port)
973+
{
974+
(void)action;
975+
(void)ctx;
976+
(void)host;
977+
(void)port;
978+
979+
return WS_SUCCESS;
980+
}
946981
#endif
947982

948983

@@ -1184,6 +1219,101 @@ static void TestDirectTcpipRejectSendsOpenFail(void)
11841219

11851220
FreeChannelOpenHarness(&harness);
11861221
}
1222+
1223+
static void TestGlobalRequestFwdNoCbSendsFailure(void)
1224+
{
1225+
ChannelOpenHarness harness;
1226+
byte in[256];
1227+
word32 inSz;
1228+
int ret;
1229+
1230+
inSz = BuildGlobalRequestFwdPacket("0.0.0.0", 2222, 0, 1, in, sizeof(in));
1231+
InitChannelOpenHarness(&harness, in, inSz);
1232+
/* no fwdCb registered */
1233+
1234+
ret = DoReceive(harness.ssh);
1235+
1236+
AssertIntEQ(ret, WS_SUCCESS);
1237+
AssertGlobalRequestReply(&harness, MSGID_REQUEST_FAILURE);
1238+
1239+
FreeChannelOpenHarness(&harness);
1240+
}
1241+
1242+
static void TestGlobalRequestFwdNoCbNoReplyKeepsConnection(void)
1243+
{
1244+
ChannelOpenHarness harness;
1245+
byte in[256];
1246+
word32 inSz;
1247+
int ret;
1248+
1249+
/* wantReply=0: no reply sent, connection must stay alive */
1250+
inSz = BuildGlobalRequestFwdPacket("0.0.0.0", 2222, 0, 0, in, sizeof(in));
1251+
InitChannelOpenHarness(&harness, in, inSz);
1252+
/* no fwdCb registered */
1253+
1254+
ret = DoReceive(harness.ssh);
1255+
1256+
AssertIntEQ(ret, WS_SUCCESS);
1257+
AssertIntEQ(harness.io.outSz, 0); /* no reply sent */
1258+
1259+
FreeChannelOpenHarness(&harness);
1260+
}
1261+
1262+
static void TestGlobalRequestFwdWithCbSendsSuccess(void)
1263+
{
1264+
ChannelOpenHarness harness;
1265+
byte in[256];
1266+
word32 inSz;
1267+
int ret;
1268+
1269+
inSz = BuildGlobalRequestFwdPacket("0.0.0.0", 2222, 0, 1, in, sizeof(in));
1270+
InitChannelOpenHarness(&harness, in, inSz);
1271+
AssertIntEQ(wolfSSH_CTX_SetFwdCb(harness.ctx, AcceptFwdCb, NULL), WS_SUCCESS);
1272+
1273+
ret = DoReceive(harness.ssh);
1274+
1275+
AssertIntEQ(ret, WS_SUCCESS);
1276+
AssertGlobalRequestReply(&harness, MSGID_REQUEST_SUCCESS);
1277+
1278+
FreeChannelOpenHarness(&harness);
1279+
}
1280+
1281+
static void TestGlobalRequestFwdCancelNoCbSendsFailure(void)
1282+
{
1283+
ChannelOpenHarness harness;
1284+
byte in[256];
1285+
word32 inSz;
1286+
int ret;
1287+
1288+
inSz = BuildGlobalRequestFwdPacket("0.0.0.0", 2222, 1, 1, in, sizeof(in));
1289+
InitChannelOpenHarness(&harness, in, inSz);
1290+
1291+
ret = DoReceive(harness.ssh);
1292+
1293+
AssertIntEQ(ret, WS_SUCCESS);
1294+
AssertGlobalRequestReply(&harness, MSGID_REQUEST_FAILURE);
1295+
1296+
FreeChannelOpenHarness(&harness);
1297+
}
1298+
1299+
static void TestGlobalRequestFwdCancelWithCbSendsSuccess(void)
1300+
{
1301+
ChannelOpenHarness harness;
1302+
byte in[256];
1303+
word32 inSz;
1304+
int ret;
1305+
1306+
inSz = BuildGlobalRequestFwdPacket("0.0.0.0", 2222, 1, 1, in, sizeof(in));
1307+
InitChannelOpenHarness(&harness, in, inSz);
1308+
AssertIntEQ(wolfSSH_CTX_SetFwdCb(harness.ctx, AcceptFwdCb, NULL), WS_SUCCESS);
1309+
1310+
ret = DoReceive(harness.ssh);
1311+
1312+
AssertIntEQ(ret, WS_SUCCESS);
1313+
AssertGlobalRequestReply(&harness, MSGID_REQUEST_SUCCESS);
1314+
1315+
FreeChannelOpenHarness(&harness);
1316+
}
11871317
#endif
11881318

11891319
#ifdef WOLFSSH_AGENT
@@ -1648,6 +1778,11 @@ int main(int argc, char** argv)
16481778
TestChannelOpenCallbackRejectSendsOpenFail();
16491779
#ifdef WOLFSSH_FWD
16501780
TestDirectTcpipRejectSendsOpenFail();
1781+
TestGlobalRequestFwdNoCbSendsFailure();
1782+
TestGlobalRequestFwdNoCbNoReplyKeepsConnection();
1783+
TestGlobalRequestFwdWithCbSendsSuccess();
1784+
TestGlobalRequestFwdCancelNoCbSendsFailure();
1785+
TestGlobalRequestFwdCancelWithCbSendsSuccess();
16511786
#endif
16521787
#ifdef WOLFSSH_AGENT
16531788
TestAgentChannelNullAgentSendsOpenFail();

0 commit comments

Comments
 (0)