From cd6ac9dc31bb5b9f754769818c93ab78d5958d26 Mon Sep 17 00:00:00 2001 From: bagajjal Date: Thu, 29 Jun 2017 12:48:13 -0700 Subject: [PATCH] Multiple fixes (#172) PowerShell/Win32-OpenSSH#596 - shellhost should pickup cmd.exe from %windir%\system32 PowerShell/Win32-OpenSSH#789 - SFTP - remove comspec PowerShell/Win32-OpenSSH#779 - AuthorizedKeysFile in sshd_config is not working PowerShell/Win32-OpenSSH#776 - SFTP ls command to show rwx permissions for user --- auth.c | 9 +++++++++ contrib/win32/win32compat/fileio.c | 2 +- contrib/win32/win32compat/misc.c | 25 +++++++++++++++++++------ contrib/win32/win32compat/shell-host.c | 23 ++++++++++++++++++----- sftp.c | 11 ++++++++--- 5 files changed, 55 insertions(+), 15 deletions(-) diff --git a/auth.c b/auth.c index 9084958f9..2f18cf888 100644 --- a/auth.c +++ b/auth.c @@ -405,6 +405,13 @@ expand_authorized_keys(const char *filename, struct passwd *pw) file = percent_expand(filename, "h", pw->pw_dir, "u", pw->pw_name, (char *)NULL); +#ifdef WINDOWS + /* Return if the path is absolute. If not, prepend the '%h\\' */ + if ((strlen(file) > 1) && (file[1] == ':')) + return (file); + + i = snprintf(ret, sizeof(ret), "%s\\%s", pw->pw_dir, file); +#else /* * Ensure that filename starts anchored. If not, be backward * compatible and prepend the '%h/' @@ -413,6 +420,8 @@ expand_authorized_keys(const char *filename, struct passwd *pw) return (file); i = snprintf(ret, sizeof(ret), "%s/%s", pw->pw_dir, file); +#endif // WINDOWS + if (i < 0 || (size_t)i >= sizeof(ret)) fatal("expand_authorized_keys: path too long"); free(file); diff --git a/contrib/win32/win32compat/fileio.c b/contrib/win32/win32compat/fileio.c index d67745366..c876adb3e 100644 --- a/contrib/win32/win32compat/fileio.c +++ b/contrib/win32/win32compat/fileio.c @@ -115,7 +115,7 @@ fileio_connect(struct w32_io* pio, char* name) { wchar_t* name_w = NULL; HANDLE h = INVALID_HANDLE_VALUE; - int ret = 0, r; + int ret = 0; if (pio->handle != 0 && pio->handle != INVALID_HANDLE_VALUE) { debug3("fileio_connect called in unexpected state, pio = %p", pio); diff --git a/contrib/win32/win32compat/misc.c b/contrib/win32/win32compat/misc.c index f016eaaa8..144589d17 100644 --- a/contrib/win32/win32compat/misc.c +++ b/contrib/win32/win32compat/misc.c @@ -478,11 +478,23 @@ strmode(mode_t mode, char *p) break; } - /* The below code is commented as the group, other is not applicable on the windows. - * As of now we are keeping "*" for everything. - * TODO - figure out if there is a better option - */ - const char *permissions = "********* "; + /* group, other are not applicable on the windows */ + + /* usr */ + if (mode & S_IREAD) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWRITE) + *p++ = 'w'; + else + *p++ = '-'; + if (mode & S_IEXEC) + *p++ = 'x'; + else + *p++ = '-'; + + const char *permissions = "****** "; for(int i = 0; i < strlen(permissions); i++) *p++ = permissions[i]; @@ -950,7 +962,8 @@ w32_strerror(int errnum) } char * -readpassphrase(const char *prompt, char *outBuf, size_t outBufLen, int flags) { +readpassphrase(const char *prompt, char *outBuf, size_t outBufLen, int flags) +{ int current_index = 0; char ch; wchar_t* wtmp = NULL; diff --git a/contrib/win32/win32compat/shell-host.c b/contrib/win32/win32compat/shell-host.c index f50443fff..e0830a5f7 100644 --- a/contrib/win32/win32compat/shell-host.c +++ b/contrib/win32/win32compat/shell-host.c @@ -125,6 +125,8 @@ struct key_translation keys[] = { static SHORT lastX = 0; static SHORT lastY = 0; +static wchar_t cmd_exe_path[PATH_MAX]; + SHORT currentLine = 0; consoleEvent* head = NULL; consoleEvent* tail = NULL; @@ -939,6 +941,19 @@ cleanup: return 0; } +wchar_t * +w32_cmd_path() +{ + ZeroMemory(cmd_exe_path, PATH_MAX); + if (!GetSystemDirectory(cmd_exe_path, sizeof(cmd_exe_path))) { + printf("GetSystemDirectory failed"); + exit(255); + } + + wcscat_s(cmd_exe_path, sizeof(cmd_exe_path), L"\\cmd.exe"); + return cmd_exe_path; +} + int start_with_pty(wchar_t *command) { @@ -1004,9 +1019,8 @@ start_with_pty(wchar_t *command) /* disable inheritance on pipe_in*/ GOTO_CLEANUP_ON_FALSE(SetHandleInformation(pipe_in, HANDLE_FLAG_INHERIT, 0)); - /*TODO - pick this up from system32*/ cmd[0] = L'\0'; - GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, L"cmd.exe")); + GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, w32_cmd_path())); if (command) { GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, L" /c")); @@ -1178,10 +1192,9 @@ start_withno_pty(wchar_t *command) run_under_cmd = TRUE; /* if above failed with FILE_NOT_FOUND, try running the provided command under cmd*/ - if (run_under_cmd) { - /*TODO - pick this up from system32*/ + if (run_under_cmd) { cmd[0] = L'\0'; - GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, L"cmd.exe")); + GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, w32_cmd_path())); if (command) { GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, L" /c")); GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, L" ")); diff --git a/sftp.c b/sftp.c index f30fb94ca..856de710b 100644 --- a/sftp.c +++ b/sftp.c @@ -296,9 +296,14 @@ static void local_do_shell(const char *args) { #ifdef WINDOWS - /* execute via system call in Windows*/ - if (!*args) { - args = (char *) getenv("ComSpec"); // get name of Windows cmd shell + /* execute via system call in Windows*/ + char cmd_path[PATH_MAX] = { 0, }; + if (!*args){ + if (!GetSystemDirectory(cmd_path, sizeof(cmd_path))) + fatal("GetSystemDirectory failed"); + + strcat_s(cmd_path, PATH_MAX, "\\cmd.exe"); + args = cmd_path; } else { convertToBackslash((char *) args); }