@@ -493,7 +493,7 @@ do_authenticated1(Authctxt *authctxt)
493
493
int do_exec_windows (Session * s , const char * command , int pty ) {
494
494
int pipein [2 ], pipeout [2 ], pipeerr [2 ], r ;
495
495
char * exec_command = NULL , * progdir = w32_programdir ();
496
- wchar_t * exec_command_w = NULL ;
496
+ wchar_t * exec_command_w = NULL , * pw_dir_w ;
497
497
498
498
if (s -> is_subsystem >= SUBSYSTEM_INT_SFTP_ERROR )
499
499
{
@@ -503,10 +503,12 @@ int do_exec_windows(Session *s, const char *command, int pty) {
503
503
}
504
504
505
505
/* Create three pipes for stdin, stdout and stderr */
506
- if (pipe (pipein ) == -1 || pipe (pipeout ) == -1 || pipe (pipeerr ) == -1 ) {
507
- error ("%s: cannot create pipe: %.100s" , __func__ , strerror (errno ));
508
- return -1 ;
509
- }
506
+ if (pipe (pipein ) == -1 || pipe (pipeout ) == -1 || pipe (pipeerr ) == -1 )
507
+ fatal ("%s: cannot create pipe: %.100s" , __func__ , strerror (errno ));
508
+
509
+ if ((pw_dir_w = utf8_to_utf16 (s -> pw -> pw_dir )) == NULL )
510
+ fatal ("%s: out of memory" );
511
+
510
512
511
513
set_nonblock (pipein [0 ]);
512
514
set_nonblock (pipein [1 ]);
@@ -536,45 +538,85 @@ int do_exec_windows(Session *s, const char *command, int pty) {
536
538
memcpy (exec_command + strlen (progdir ) + 1 , command , strlen (command ) + 1 );
537
539
}
538
540
} else {
539
- char * shell_host = pty ? "ssh-shellhost.exe -t " : "ssh-shellhost.exe " ;
540
- exec_command = malloc (strlen (progdir ) + strlen (shell_host ) + (command ? strlen (command ) : 0 ));
541
+ char * shell_host = pty ? "ssh-shellhost.exe " : "ssh-shellhost.exe -nopty " , * c ;
542
+ exec_command = malloc (strlen (progdir ) + 1 + strlen (shell_host ) + (command ? strlen (command ) : 0 ) + 1 );
541
543
if (exec_command == NULL )
542
544
fatal ("%s, out of memory" );
543
-
545
+ c = exec_command ;
546
+ memcpy (c , progdir , strlen (progdir ));
547
+ c += strlen (progdir );
548
+ * c ++ = '\\' ;
549
+ memcpy (c , shell_host , strlen (shell_host ));
550
+ c += strlen (shell_host );
551
+ if (command ) {
552
+ memcpy (c , command , strlen (command ));
553
+ c += strlen (command );
554
+ }
555
+ * c == '\0' ;
544
556
}
545
-
546
- wchar_t * pw_dir_utf16 = utf8_to_utf16 (s -> pw -> pw_dir );
547
- extern int debug_flag ;
548
557
549
- PROCESS_INFORMATION pi ;
550
- STARTUPINFOW si ;
558
+ /* setup Environment varibles */
559
+ {
560
+ wchar_t * tmp ;
561
+ char buf [128 ];
562
+ char * laddr ;
551
563
552
- BOOL b ;
564
+ if ((tmp == utf8_to_utf16 (s -> pw -> pw_name )) != NULL )
565
+ fatal ("%s, out of memory" );
566
+ SetEnvironmentVariableW (L"USERNAME" , tmp );
567
+ free (tmp );
553
568
554
- HANDLE hToken = INVALID_HANDLE_VALUE ;
569
+ if (s -> display )
570
+ SetEnvironmentVariableW (L"DISPLAY" , s -> display );
571
+
555
572
573
+ //_wchdir(pw_dir_w);
556
574
557
- char cmd [1024 ];
558
- char * exec_command ;
559
- char * laddr ;
560
- char buf [256 ];
575
+ SetEnvironmentVariableW (L"HOMEPATH" , pw_dir_w );
576
+ SetEnvironmentVariableW (L"USERPROFILE" , pw_dir_w );
561
577
578
+ if (pw_dir_w [1 ] == L':' ) {
579
+ wchar_t wc = pw_dir_w [2 ];
580
+ pw_dir_w [2 ] = L'\0' ;
581
+ SetEnvironmentVariableW (L"HOMEDRIVE" , pw_dir_w );
582
+ }
562
583
584
+ snprintf (buf , sizeof buf , "%.50s %d %d" ,
585
+ get_remote_ipaddr (), get_remote_port (), get_local_port ());
563
586
564
- if (!command )
565
- {
566
- exec_command = s -> pw -> pw_shell ;
567
- }
568
- else
569
- {
570
- exec_command = command ;
571
- }
587
+ SetEnvironmentVariableA ("SSH_CLIENT" , buf );
572
588
589
+ laddr = get_local_ipaddr (packet_get_connection_in ());
573
590
574
- int retcode = -1 ;
575
- if ((!s -> is_subsystem ) && (s -> ttyfd != -1 ))
576
- {
591
+ snprintf (buf , sizeof buf , "%.50s %d %.50s %d" ,
592
+ get_remote_ipaddr (), get_remote_port (), laddr , get_local_port ());
593
+
594
+ free (laddr );
595
+
596
+ SetEnvironmentVariableA ("SSH_CONNECTION" , buf );
597
+
598
+ if (original_command )
599
+ SetEnvironmentVariableA ("SSH_ORIGINAL_COMMAND" , original_command );
600
+
601
+
602
+ if ((s -> term ) && (s -> term [0 ]))
603
+ SetEnvironmentVariable ("TERM" , s -> term );
604
+
605
+ if (!s -> is_subsystem ) {
606
+ snprintf (buf , sizeof buf , "%s@%s $P$G" , s -> pw -> pw_name , getenv ("COMPUTERNAME" ));
607
+ SetEnvironmentVariableA ("PROMPT" , buf );
608
+ }
577
609
}
610
+
611
+ extern int debug_flag ;
612
+
613
+ PROCESS_INFORMATION pi ;
614
+ STARTUPINFOW si ;
615
+
616
+ BOOL b ;
617
+
618
+ HANDLE hToken = INVALID_HANDLE_VALUE ;
619
+
578
620
579
621
/*
580
622
* Assign sockets to StartupInfo
@@ -602,122 +644,21 @@ int do_exec_windows(Session *s, const char *command, int pty) {
602
644
si .hStdError = (HANDLE )sfd_to_handle (pipeerr [1 ]);
603
645
si .lpDesktop = NULL ;
604
646
605
- SetEnvironmentVariable ("USER" , s -> pw -> pw_name );
606
- SetEnvironmentVariable ("USERNAME" , s -> pw -> pw_name );
607
- SetEnvironmentVariable ("LOGNAME" , s -> pw -> pw_name );
608
-
609
- /*
610
- * If we get this far, the user has already been authenticated
611
- * We should either have a user token in authctxt -> methoddata
612
- * (e.g. for password auth) or we need to create a more restrictive
613
- * token using CreateUserToken for non-password auth mechanisms.
614
- */
615
-
616
647
hToken = s -> authctxt -> methoddata ;
617
648
618
-
619
- if (s -> display )
620
- {
621
- SetEnvironmentVariable ("DISPLAY" , s -> display );
622
- }
623
-
624
- /*
625
- * Change to users home directory
626
- * TODO - pw_dir is utf-8, convert it to utf-16 and call _wchdir
627
- * also change subsequent calls to SetEnvironmentVariable
628
- */
629
-
630
- _wchdir (pw_dir_utf16 );
631
-
632
- SetEnvironmentVariableW (L"HOME" , pw_dir_utf16 );
633
- SetEnvironmentVariableW (L"USERPROFILE" , pw_dir_utf16 );
634
-
635
- wchar_t * wstr , wchr ;
636
- wstr = wcschr (pw_dir_utf16 , L':' );
637
- if (wstr ) {
638
- wchr = * (wstr + 1 );
639
- * (wstr + 1 ) = '\0' ;
640
- SetEnvironmentVariableW (L"HOMEDRIVE" , pw_dir_utf16 );
641
- * (wstr + 1 ) = wchr ;
642
- SetEnvironmentVariableW (L"HOMEPATH" , (wstr + 1 ));
643
- }
644
-
645
- // find the server name of the domain controller which created this token
646
- GetDomainFromToken (& hToken , buf , sizeof (buf ));
647
- if (buf [0 ])
648
- SetEnvironmentVariable ("USERDOMAIN" , buf );
649
-
650
- /*
651
- * Set SSH_CLIENT variable.
652
- */
653
-
654
- snprintf (buf , sizeof buf , "%.50s %d %d" ,
655
- get_remote_ipaddr (), get_remote_port (), get_local_port ());
656
-
657
- SetEnvironmentVariableA ("SSH_CLIENT" , buf );
658
-
659
- /*
660
- * Set SSH_CONNECTION variable.
661
- */
662
-
663
- laddr = get_local_ipaddr (packet_get_connection_in ());
664
-
665
- snprintf (buf , sizeof buf , "%.50s %d %.50s %d" ,
666
- get_remote_ipaddr (), get_remote_port (), laddr , get_local_port ());
667
-
668
- free (laddr );
669
-
670
- SetEnvironmentVariableA ("SSH_CONNECTION" , buf );
671
-
672
- if (original_command )
673
- SetEnvironmentVariableA ("SSH_ORIGINAL_COMMAND" , original_command );
674
-
675
-
676
- // set better prompt for Windows cmd shell
677
- if (!s -> is_subsystem ) {
678
- snprintf (buf , sizeof buf , "%s@%s $P$G" , s -> pw -> pw_name , getenv ("COMPUTERNAME" ));
679
- SetEnvironmentVariableA ("PROMPT" , buf );
680
- }
681
-
682
- /*
683
- * Get the current user's name (associated with sshd thread).
684
- */
685
-
686
- debug3 ("Home path before CreateProcessAsUser [%ls]" , s -> pw -> pw_dir );
687
-
688
- DWORD size = 256 ;
689
-
690
- char name [256 ];
691
-
692
- GetUserName (name , & size );
693
-
694
- if ((s -> term ) && (s -> term [0 ]))
695
- SetEnvironmentVariable ("TERM" , s -> term );
696
- /*
697
- * Create new process as other user using access token object.
698
- */
699
-
700
649
debug ("Executing command: %s" , exec_command );
701
650
702
- /*
703
- * Create the child process
704
- */
651
+ /* Create the child process */
705
652
706
- wchar_t exec_command_w [ MAX_PATH ] ;
653
+ exec_command_w = utf8_to_utf16 ( exec_command ) ;
707
654
708
- MultiByteToWideChar (CP_UTF8 , 0 , exec_command , -1 , exec_command_w , MAX_PATH );
709
- DWORD dwStartupFlags = DETACHED_PROCESS ;// CREATE_SUSPENDED; // 0
710
-
711
- SetConsoleCtrlHandler (NULL , FALSE);
712
-
713
- wchar_t * p_dir = utf8_to_utf16 (s -> pw -> pw_dir );
714
655
if (debug_flag )
715
656
b = CreateProcessW (NULL , exec_command_w , NULL , NULL , TRUE,
716
- /*CREATE_NEW_PROCESS_GROUP*/ dwStartupFlags , NULL , pw_dir_utf16 ,
657
+ DETACHED_PROCESS , NULL , pw_dir_w ,
717
658
& si , & pi );
718
659
else
719
660
b = CreateProcessAsUserW (hToken , NULL , exec_command_w , NULL , NULL , TRUE,
720
- /*CREATE_NEW_PROCESS_GROUP*/ dwStartupFlags , NULL , pw_dir_utf16 ,
661
+ DETACHED_PROCESS , NULL , pw_dir_w ,
721
662
& si , & pi );
722
663
723
664
if (!b )
@@ -728,7 +669,7 @@ int do_exec_windows(Session *s, const char *command, int pty) {
728
669
729
670
exit (1 );
730
671
}
731
- else if (s -> ttyfd != -1 ) { /*attach to shell console */
672
+ else if (pty ) { /*attach to shell console */
732
673
FreeConsole ();
733
674
if (!debug_flag )
734
675
ImpersonateLoggedOnUser (hToken );
@@ -748,23 +689,9 @@ int do_exec_windows(Session *s, const char *command, int pty) {
748
689
}
749
690
}
750
691
751
- /*
752
- * Save token used for create child process. We'll need it on cleanup
753
- * to clean up DACL of Winsta0.
754
- */
755
-
756
- /*
757
- * Log the process handle (fake it as the pid) for termination lookups
758
- */
759
-
760
692
s -> pid = pi .dwProcessId ;
761
693
sw_add_child (pi .hProcess , pi .dwProcessId );
762
694
763
- // Add the child process created to select mux so that during our select data call we know if the process has exited
764
- /* TODO - fix thi s*/
765
- //int WSHELPAddChildToWatch ( HANDLE processtowatch);
766
- //WSHELPAddChildToWatch ( pi.hProcess);
767
-
768
695
/*
769
696
* Set interactive/non-interactive mode.
770
697
*/
@@ -780,9 +707,7 @@ int do_exec_windows(Session *s, const char *command, int pty) {
780
707
close (pipeout [1 ]);
781
708
close (pipeerr [1 ]);
782
709
783
- ResumeThread (pi .hThread ); /* now let cmd shell main thread be active s we have closed all i/o file handle that cmd will use */
784
- SetConsoleCtrlHandler (NULL , TRUE);
785
-
710
+
786
711
/*
787
712
* Close child thread handles as we do not need it. Process handle we keep so that we can know if it has died o not
788
713
*/
0 commit comments