From e626a748cac26b2ae69bf5e8c15c6dc04cf5cfb6 Mon Sep 17 00:00:00 2001 From: Manoj Ampalam Date: Wed, 19 Oct 2016 14:38:33 -0700 Subject: [PATCH] session refactoring part 1 --- contrib/win32/win32compat/inc/w32posix.h | 1 + contrib/win32/win32compat/misc.c | 24 +++++++ contrib/win32/win32compat/w32fd.c | 6 +- session.c | 83 +++++++++++++++--------- sshd.c | 33 +++------- 5 files changed, 90 insertions(+), 57 deletions(-) diff --git a/contrib/win32/win32compat/inc/w32posix.h b/contrib/win32/win32compat/inc/w32posix.h index 5531209..2c09793 100644 --- a/contrib/win32/win32compat/inc/w32posix.h +++ b/contrib/win32/win32compat/inc/w32posix.h @@ -75,6 +75,7 @@ void w32_freeaddrinfo(struct addrinfo *); int w32_getaddrinfo(const char *, const char *, const struct addrinfo *, struct addrinfo **); FILE* w32_fopen_utf8(const char *, const char *); +char* w32_programdir(); /* Shutdown constants */ diff --git a/contrib/win32/win32compat/misc.c b/contrib/win32/win32compat/misc.c index 855259e..53f1fc6 100644 --- a/contrib/win32/win32compat/misc.c +++ b/contrib/win32/win32compat/misc.c @@ -140,4 +140,28 @@ utf16_to_utf8(const wchar_t* utf16) { WideCharToMultiByte(CP_UTF8, 0, utf16, -1, utf8, needed, NULL, NULL) == 0) return NULL; return utf8; +} + +static char* s_programdir = NULL; +char* w32_programdir() { + if (s_programdir != NULL) + return s_programdir; + + if ((s_programdir = utf16_to_utf8(_wpgmptr)) == NULL) + return NULL; + + /* null terminate after directory path */ + { + char* tail = s_programdir + strlen(s_programdir); + while (tail > s_programdir && *tail != '\\' && *tail != '/') + tail--; + + if (tail > s_programdir) + *tail = '\0'; + else + *tail = '.'; /* current directory */ + } + + return s_programdir; + } \ No newline at end of file diff --git a/contrib/win32/win32compat/w32fd.c b/contrib/win32/win32compat/w32fd.c index becc894..292f31a 100644 --- a/contrib/win32/win32compat/w32fd.c +++ b/contrib/win32/win32compat/w32fd.c @@ -125,8 +125,10 @@ w32posix_initialize() { || (socketio_initialize() != 0)) DebugBreak(); main_thread = OpenThread(THREAD_SET_CONTEXT, FALSE, GetCurrentThreadId()); - if ((main_thread == NULL) || (sw_initialize() != 0)) - DebugBreak(); + if ((main_thread == NULL) || (sw_initialize() != 0) || w32_programdir() == NULL) { + DebugBreak(); + fatal("failed to initialize w32posix wrapper"); + } } void diff --git a/session.c b/session.c index 0285526..e2cc734 100644 --- a/session.c +++ b/session.c @@ -491,17 +491,64 @@ do_authenticated1(Authctxt *authctxt) #ifdef WINDOWS int do_exec_windows(Session *s, const char *command, int pty) { + int pipein[2], pipeout[2], pipeerr[2], r; + char *exec_command = NULL, *progdir = w32_programdir(); + wchar_t* exec_command_w = NULL; + if (s->is_subsystem >= SUBSYSTEM_INT_SFTP_ERROR) + { + error("sub system not supported, exiting\n"); + fflush(NULL); + exit(1); + } + + /* Create three pipes for stdin, stdout and stderr */ + if (pipe(pipein) == -1 || pipe(pipeout) == -1 || pipe(pipeerr) == -1) { + error("%s: cannot create pipe: %.100s", __func__, strerror(errno)); + return -1; + } + + set_nonblock(pipein[0]); + set_nonblock(pipein[1]); + set_nonblock(pipeout[0]); + set_nonblock(pipeout[1]); + set_nonblock(pipeerr[0]); + set_nonblock(pipeerr[1]); + + fcntl(pipein[1], F_SETFD, FD_CLOEXEC); + fcntl(pipeout[0], F_SETFD, FD_CLOEXEC); + fcntl(pipeerr[0], F_SETFD, FD_CLOEXEC); + + /* prepare exec - path used with CreateProcess() */ + if (s->is_subsystem) { + /* relative or absolute */ + if (command == NULL || command[0] == '\0') + fatal("expecting command for a subsystem"); + + if (command[1] != ':') /* absolute */ + exec_command = xstrdup(command); + else {/*relative*/ + exec_command = malloc(strlen(progdir) + 1 + strlen(command)); + if (exec_command == NULL) + fatal("%s, out of memory"); + memcpy(exec_command, progdir, strlen(progdir)); + exec_command[strlen(progdir)] = '\\'; + memcpy(exec_command + strlen(progdir) + 1, command, strlen(command) + 1); + } + } else { + char* shell_host = pty ? "ssh-shellhost.exe -t " : "ssh-shellhost.exe "; + exec_command = malloc(strlen(progdir) + strlen(shell_host) + (command ? strlen(command) : 0)); + if (exec_command == NULL) + fatal("%s, out of memory"); + + } + wchar_t* pw_dir_utf16 = utf8_to_utf16(s->pw->pw_dir); extern int debug_flag; PROCESS_INFORMATION pi; STARTUPINFOW si; - int pipein[2]; - int pipeout[2]; - int pipeerr[2]; - BOOL b; HANDLE hToken = INVALID_HANDLE_VALUE; @@ -512,12 +559,6 @@ int do_exec_windows(Session *s, const char *command, int pty) { char *laddr; char buf[256]; - if (s->is_subsystem >= SUBSYSTEM_INT_SFTP_ERROR) - { - error("sub system not supported, exiting\n"); - fflush(NULL); - exit(1); - } if (!command) @@ -529,27 +570,12 @@ int do_exec_windows(Session *s, const char *command, int pty) { exec_command = command; } - /* - * Create three socket pairs for stdin, stdout and stderr - */ - pipe(pipein); - pipe(pipeout); - pipe(pipeerr); int retcode = -1; if ((!s->is_subsystem) && (s->ttyfd != -1)) { } - debug3("sockin[0]: %d sockin[1]: %d", pipein[0], pipein[1]); - debug3("sockout[0]: %d sockout[1]: %d", pipeout[0], pipeout[1]); - debug3("sockerr[0]: %d sockerr[1]: %d", pipeerr[0], pipeerr[1]); - - - SetHandleInformation(sfd_to_handle(pipein[1]), HANDLE_FLAG_INHERIT, 0); - SetHandleInformation(sfd_to_handle(pipeout[0]), HANDLE_FLAG_INHERIT, 0); - SetHandleInformation(sfd_to_handle(pipeerr[0]), HANDLE_FLAG_INHERIT, 0); - /* * Assign sockets to StartupInfo */ @@ -580,13 +606,6 @@ int do_exec_windows(Session *s, const char *command, int pty) { SetEnvironmentVariable("USERNAME", s->pw->pw_name); SetEnvironmentVariable("LOGNAME", s->pw->pw_name); - set_nonblock(pipein[0]); - set_nonblock(pipein[1]); - set_nonblock(pipeout[0]); - set_nonblock(pipeout[1]); - set_nonblock(pipeerr[0]); - set_nonblock(pipeerr[1]); - /* * If we get this far, the user has already been authenticated * We should either have a user token in authctxt -> methoddata diff --git a/sshd.c b/sshd.c index 2c988cd..871b2bf 100644 --- a/sshd.c +++ b/sshd.c @@ -281,25 +281,16 @@ static void do_ssh2_kex(void); { int exitCode = -1; - // - // Windows. - // - - #ifdef WIN32_FIXME - - if (GetModuleFileName(NULL, path, pathSize)){ - int i; - int lastSlashPos = 0; - - for (i = 0; path[i]; i++) { - if (path[i] == '/' || path[i] == '\\') { - lastSlashPos = i; - } - } - - path[lastSlashPos] = 0; + /* Windows */ + #ifdef WINDOWS + + char* dir = w32_programdir(); + if (strnlen(dir, pathSize) == pathSize) + error("program directory path size exceeded provided pathSize %d", pathSize); + else { + memcpy(path, dir, strnlen(dir, pathSize) + 1); exitCode = 0; - } + } #endif @@ -1972,11 +1963,7 @@ main(int ac, char **av) struct stat s; - #ifdef WIN32_FIXME - #define PATH_SIZE MAX_PATH - #else - #define PATH_SIZE PATH_MAX - #endif + #define PATH_SIZE PATH_MAX char basePath[PATH_SIZE] = {0}; char path[PATH_SIZE] = {0};