@@ -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+
925949static 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,83 @@ 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_FATAL_ERROR );
1237+ AssertIntEQ (harness .ssh -> error , WS_UNIMPLEMENTED_E );
1238+ AssertGlobalRequestReply (& harness , MSGID_REQUEST_FAILURE );
1239+
1240+ FreeChannelOpenHarness (& harness );
1241+ }
1242+
1243+ static void TestGlobalRequestFwdWithCbSendsSuccess (void )
1244+ {
1245+ ChannelOpenHarness harness ;
1246+ byte in [256 ];
1247+ word32 inSz ;
1248+ int ret ;
1249+
1250+ inSz = BuildGlobalRequestFwdPacket ("0.0.0.0" , 2222 , 0 , 1 , in , sizeof (in ));
1251+ InitChannelOpenHarness (& harness , in , inSz );
1252+ AssertIntEQ (wolfSSH_CTX_SetFwdCb (harness .ctx , AcceptFwdCb , NULL ), WS_SUCCESS );
1253+
1254+ ret = DoReceive (harness .ssh );
1255+
1256+ AssertIntEQ (ret , WS_SUCCESS );
1257+ AssertGlobalRequestReply (& harness , MSGID_REQUEST_SUCCESS );
1258+
1259+ FreeChannelOpenHarness (& harness );
1260+ }
1261+
1262+ static void TestGlobalRequestFwdCancelNoCbSendsFailure (void )
1263+ {
1264+ ChannelOpenHarness harness ;
1265+ byte in [256 ];
1266+ word32 inSz ;
1267+ int ret ;
1268+
1269+ inSz = BuildGlobalRequestFwdPacket ("0.0.0.0" , 2222 , 1 , 1 , in , sizeof (in ));
1270+ InitChannelOpenHarness (& harness , in , inSz );
1271+
1272+ ret = DoReceive (harness .ssh );
1273+
1274+ AssertIntEQ (ret , WS_FATAL_ERROR );
1275+ AssertIntEQ (harness .ssh -> error , WS_UNIMPLEMENTED_E );
1276+ AssertGlobalRequestReply (& harness , MSGID_REQUEST_FAILURE );
1277+
1278+ FreeChannelOpenHarness (& harness );
1279+ }
1280+
1281+ static void TestGlobalRequestFwdCancelWithCbSendsSuccess (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+ AssertIntEQ (wolfSSH_CTX_SetFwdCb (harness .ctx , AcceptFwdCb , NULL ), WS_SUCCESS );
1291+
1292+ ret = DoReceive (harness .ssh );
1293+
1294+ AssertIntEQ (ret , WS_SUCCESS );
1295+ AssertGlobalRequestReply (& harness , MSGID_REQUEST_SUCCESS );
1296+
1297+ FreeChannelOpenHarness (& harness );
1298+ }
11871299#endif
11881300
11891301#ifdef WOLFSSH_AGENT
@@ -1648,6 +1760,10 @@ int main(int argc, char** argv)
16481760 TestChannelOpenCallbackRejectSendsOpenFail ();
16491761#ifdef WOLFSSH_FWD
16501762 TestDirectTcpipRejectSendsOpenFail ();
1763+ TestGlobalRequestFwdNoCbSendsFailure ();
1764+ TestGlobalRequestFwdWithCbSendsSuccess ();
1765+ TestGlobalRequestFwdCancelNoCbSendsFailure ();
1766+ TestGlobalRequestFwdCancelWithCbSendsSuccess ();
16511767#endif
16521768#ifdef WOLFSSH_AGENT
16531769 TestAgentChannelNullAgentSendsOpenFail ();
0 commit comments