@@ -626,6 +626,97 @@ static int test_DhGexGroupValidate(void)
626626#endif /* WOLFSSH_TEST_INTERNAL && !WOLFSSH_NO_DH_GEX_SHA256 */
627627
628628
629+ #ifdef WOLFSSH_TEST_INTERNAL
630+
631+ /* Verify DoUserAuthBanner fully consumes the payload, including a non-empty
632+ * language tag. Before the fix, the tag's data bytes were left unconsumed,
633+ * which would misalign packet decoding for subsequent messages. */
634+ static int test_DoUserAuthBanner (void )
635+ {
636+ WOLFSSH_CTX * ctx = NULL ;
637+ WOLFSSH * ssh = NULL ;
638+ int result = 0 ;
639+
640+ /* Payload layout: [4-byte banner len][banner][4-byte lang len][lang] */
641+ struct {
642+ const char * banner ;
643+ word32 bannerSz ;
644+ const char * lang ;
645+ word32 langSz ;
646+ int expectRet ;
647+ const char * label ;
648+ } cases [] = {
649+ { "Welcome" , 7 , "" , 0 , WS_SUCCESS , "empty lang tag" },
650+ { "Welcome" , 7 , "en-US" , 5 , WS_SUCCESS , "non-empty lang tag" },
651+ { NULL , 0 , NULL , 0 , WS_BAD_ARGUMENT , "null ssh" },
652+ };
653+ int i ;
654+
655+ ctx = wolfSSH_CTX_new (WOLFSSH_ENDPOINT_CLIENT , NULL );
656+ if (ctx == NULL )
657+ return -300 ;
658+ ssh = wolfSSH_new (ctx );
659+ if (ssh == NULL ) {
660+ wolfSSH_CTX_free (ctx );
661+ return -301 ;
662+ }
663+ ctx -> showBanner = 0 ;
664+
665+ for (i = 0 ; i < (int )(sizeof (cases )/sizeof (cases [0 ])); i ++ ) {
666+ byte buf [128 ];
667+ word32 idx = 0 ;
668+ word32 len = 0 ;
669+ int ret ;
670+
671+ if (cases [i ].banner == NULL ) {
672+ /* null-ssh case: pass NULL ssh, dummy non-null buf */
673+ buf [0 ] = 0 ;
674+ len = 1 ;
675+ ret = wolfSSH_TestDoUserAuthBanner (NULL , buf , len , & idx );
676+ }
677+ else {
678+ /* encode banner string */
679+ buf [len ++ ] = (byte )(cases [i ].bannerSz >> 24 );
680+ buf [len ++ ] = (byte )(cases [i ].bannerSz >> 16 );
681+ buf [len ++ ] = (byte )(cases [i ].bannerSz >> 8 );
682+ buf [len ++ ] = (byte )(cases [i ].bannerSz );
683+ WMEMCPY (buf + len , cases [i ].banner , cases [i ].bannerSz );
684+ len += cases [i ].bannerSz ;
685+ /* encode language tag string */
686+ buf [len ++ ] = (byte )(cases [i ].langSz >> 24 );
687+ buf [len ++ ] = (byte )(cases [i ].langSz >> 16 );
688+ buf [len ++ ] = (byte )(cases [i ].langSz >> 8 );
689+ buf [len ++ ] = (byte )(cases [i ].langSz );
690+ WMEMCPY (buf + len , cases [i ].lang , cases [i ].langSz );
691+ len += cases [i ].langSz ;
692+
693+ ret = wolfSSH_TestDoUserAuthBanner (ssh , buf , len , & idx );
694+ }
695+
696+ if (ret != cases [i ].expectRet ) {
697+ printf ("DoUserAuthBanner[%s]: ret=%d, expected=%d\n" ,
698+ cases [i ].label , ret , cases [i ].expectRet );
699+ result = -302 - i ;
700+ break ;
701+ }
702+
703+ /* On success the entire payload must be consumed. */
704+ if (ret == WS_SUCCESS && idx != len ) {
705+ printf ("DoUserAuthBanner[%s]: idx=%u, len=%u (unconsumed bytes)\n" ,
706+ cases [i ].label , idx , len );
707+ result = -310 - i ;
708+ break ;
709+ }
710+ }
711+
712+ wolfSSH_free (ssh );
713+ wolfSSH_CTX_free (ctx );
714+ return result ;
715+ }
716+
717+ #endif /* WOLFSSH_TEST_INTERNAL */
718+
719+
629720/* Error Code And Message Test */
630721
631722static int test_Errors (void )
@@ -714,6 +805,12 @@ int wolfSSH_UnitTest(int argc, char** argv)
714805 testResult = testResult || unitResult ;
715806#endif
716807
808+ #ifdef WOLFSSH_TEST_INTERNAL
809+ unitResult = test_DoUserAuthBanner ();
810+ printf ("DoUserAuthBanner: %s\n" , (unitResult == 0 ? "SUCCESS" : "FAILED" ));
811+ testResult = testResult || unitResult ;
812+ #endif
813+
717814#ifdef WOLFSSH_KEYGEN
718815#ifndef WOLFSSH_NO_RSA
719816 unitResult = test_RsaKeyGen ();
0 commit comments