Skip to content

Commit 6239a28

Browse files
committed
session refactoring part 2
1 parent e626a74 commit 6239a28

File tree

2 files changed

+78
-187
lines changed

2 files changed

+78
-187
lines changed

contrib/win32/win32compat/pwd.c

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -184,33 +184,6 @@ w32_getpwuid(uid_t uid) {
184184
return ret;
185185
}
186186

187-
/* given a access token, find the domain name of user account of the access token */
188-
int GetDomainFromToken ( HANDLE *hAccessToken, UCHAR *domain, DWORD dwSize)
189-
{
190-
UCHAR InfoBuffer[1000],username[200];
191-
PTOKEN_USER pTokenUser = (PTOKEN_USER)InfoBuffer;
192-
DWORD dwInfoBufferSize,dwAccountSize = 200, dwDomainSize = dwSize;
193-
SID_NAME_USE snu;
194-
195-
domain[0] = '\0' ;
196-
GetTokenInformation(*hAccessToken,TokenUser,InfoBuffer,
197-
1000, &dwInfoBufferSize);
198-
199-
LookupAccountSid(NULL, pTokenUser->User.Sid, (LPSTR)username,
200-
&dwAccountSize,(LPSTR)domain, &dwDomainSize, &snu);
201-
return 0;
202-
}
203-
204-
/*
205-
* Retrieve user homedir from token, save it in static string
206-
* and return pointer to this string.
207-
*
208-
* userName - user's name (IN)
209-
* token - logon user's token (IN)
210-
*
211-
* RETURNS: pointer to static string with homedir or NULL if fails.
212-
*/
213-
214187
#define SET_USER_ENV(folder_id, evn_variable) do { \
215188
if (SHGetKnownFolderPath(&folder_id,0,token,&path) == S_OK) \
216189
{ \
@@ -219,13 +192,6 @@ int GetDomainFromToken ( HANDLE *hAccessToken, UCHAR *domain, DWORD dwSize)
219192
} \
220193
} while (0)
221194

222-
/*
223-
* Temporary getpwuid implementaion of Windows. This should be replaced with getpw_currentuser
224-
*/
225-
226-
227-
228-
229195

230196
/* TODO - this is moved from realpath.c in openbsdcompat. Review and finalize its position*/
231197

session.c

Lines changed: 78 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ do_authenticated1(Authctxt *authctxt)
493493
int do_exec_windows(Session *s, const char *command, int pty) {
494494
int pipein[2], pipeout[2], pipeerr[2], r;
495495
char *exec_command = NULL, *progdir = w32_programdir();
496-
wchar_t* exec_command_w = NULL;
496+
wchar_t *exec_command_w = NULL, *pw_dir_w;
497497

498498
if (s->is_subsystem >= SUBSYSTEM_INT_SFTP_ERROR)
499499
{
@@ -503,10 +503,12 @@ int do_exec_windows(Session *s, const char *command, int pty) {
503503
}
504504

505505
/* 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+
510512

511513
set_nonblock(pipein[0]);
512514
set_nonblock(pipein[1]);
@@ -536,45 +538,85 @@ int do_exec_windows(Session *s, const char *command, int pty) {
536538
memcpy(exec_command + strlen(progdir) + 1, command, strlen(command) + 1);
537539
}
538540
} 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);
541543
if (exec_command == NULL)
542544
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';
544556
}
545-
546-
wchar_t* pw_dir_utf16 = utf8_to_utf16(s->pw->pw_dir);
547-
extern int debug_flag;
548557

549-
PROCESS_INFORMATION pi;
550-
STARTUPINFOW si;
558+
/* setup Environment varibles */
559+
{
560+
wchar_t* tmp;
561+
char buf[128];
562+
char* laddr;
551563

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);
553568

554-
HANDLE hToken = INVALID_HANDLE_VALUE;
569+
if (s->display)
570+
SetEnvironmentVariableW(L"DISPLAY", s->display);
571+
555572

573+
//_wchdir(pw_dir_w);
556574

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);
561577

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+
}
562583

584+
snprintf(buf, sizeof buf, "%.50s %d %d",
585+
get_remote_ipaddr(), get_remote_port(), get_local_port());
563586

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);
572588

589+
laddr = get_local_ipaddr(packet_get_connection_in());
573590

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+
}
577609
}
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+
578620

579621
/*
580622
* Assign sockets to StartupInfo
@@ -602,122 +644,21 @@ int do_exec_windows(Session *s, const char *command, int pty) {
602644
si.hStdError = (HANDLE)sfd_to_handle(pipeerr[1]);
603645
si.lpDesktop = NULL;
604646

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-
616647
hToken = s->authctxt->methoddata;
617648

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-
700649
debug("Executing command: %s", exec_command);
701650

702-
/*
703-
* Create the child process
704-
*/
651+
/* Create the child process */
705652

706-
wchar_t exec_command_w[MAX_PATH];
653+
exec_command_w = utf8_to_utf16(exec_command);
707654

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);
714655
if (debug_flag)
715656
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,
717658
&si, &pi);
718659
else
719660
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,
721662
&si, &pi);
722663

723664
if (!b)
@@ -728,7 +669,7 @@ int do_exec_windows(Session *s, const char *command, int pty) {
728669

729670
exit(1);
730671
}
731-
else if (s->ttyfd != -1) { /*attach to shell console */
672+
else if (pty) { /*attach to shell console */
732673
FreeConsole();
733674
if (!debug_flag)
734675
ImpersonateLoggedOnUser(hToken);
@@ -748,23 +689,9 @@ int do_exec_windows(Session *s, const char *command, int pty) {
748689
}
749690
}
750691

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-
760692
s->pid = pi.dwProcessId;
761693
sw_add_child(pi.hProcess, pi.dwProcessId);
762694

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-
768695
/*
769696
* Set interactive/non-interactive mode.
770697
*/
@@ -780,9 +707,7 @@ int do_exec_windows(Session *s, const char *command, int pty) {
780707
close(pipeout[1]);
781708
close(pipeerr[1]);
782709

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+
786711
/*
787712
* 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
788713
*/

0 commit comments

Comments
 (0)