diff --git a/contrib/win32/openssh/Win32-OpenSSH.sln b/contrib/win32/openssh/Win32-OpenSSH.sln index 3abc2cb..db9117a 100644 --- a/contrib/win32/openssh/Win32-OpenSSH.sln +++ b/contrib/win32/openssh/Win32-OpenSSH.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.23107.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssh", "ssh.vcxproj", "{74E69D5E-A1EF-46EA-9173-19A412774104}" ProjectSection(ProjectDependencies) = postProject diff --git a/contrib/win32/openssh/version.rc b/contrib/win32/openssh/version.rc index b0477e8..3f63c32 100644 Binary files a/contrib/win32/openssh/version.rc and b/contrib/win32/openssh/version.rc differ diff --git a/contrib/win32/win32compat/console.c b/contrib/win32/win32compat/console.c index 6c3cdcb..03d9e4a 100644 --- a/contrib/win32/win32compat/console.c +++ b/contrib/win32/win32compat/console.c @@ -46,7 +46,6 @@ #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4 #endif -HANDLE hInputConsole = NULL; HANDLE hOutputConsole = NULL; DWORD dwSavedAttributes = 0; WORD wStartingAttributes = 0; diff --git a/contrib/win32/win32compat/inc/w32posix.h b/contrib/win32/win32compat/inc/w32posix.h index b4f3ee0..eb67eaa 100644 --- a/contrib/win32/win32compat/inc/w32posix.h +++ b/contrib/win32/win32compat/inc/w32posix.h @@ -88,6 +88,8 @@ int w32_getaddrinfo(const char *, const char *, const struct addrinfo *, struct addrinfo **); FILE* w32_fopen_utf8(const char *, const char *); int w32_ftruncate(int fd, off_t length); +char* w32_programdir(); + /* Shutdown constants */ #define SHUT_WR SD_SEND diff --git a/contrib/win32/win32compat/misc.c b/contrib/win32/win32compat/misc.c index 130b85b..53f1fc6 100644 --- a/contrib/win32/win32compat/misc.c +++ b/contrib/win32/win32compat/misc.c @@ -141,3 +141,27 @@ utf16_to_utf8(const wchar_t* utf16) { 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/pwd.c b/contrib/win32/win32compat/pwd.c index 4e8242a..fd92b88 100644 --- a/contrib/win32/win32compat/pwd.c +++ b/contrib/win32/win32compat/pwd.c @@ -202,48 +202,6 @@ done: return ret; } -/* given a access token, find the domain name of user account of the access token */ -int GetDomainFromToken ( HANDLE *hAccessToken, UCHAR *domain, DWORD dwSize) -{ - UCHAR InfoBuffer[1000],username[200]; - PTOKEN_USER pTokenUser = (PTOKEN_USER)InfoBuffer; - DWORD dwInfoBufferSize,dwAccountSize = 200, dwDomainSize = dwSize; - SID_NAME_USE snu; - - domain[0] = '\0' ; - GetTokenInformation(*hAccessToken,TokenUser,InfoBuffer, - 1000, &dwInfoBufferSize); - - LookupAccountSid(NULL, pTokenUser->User.Sid, (LPSTR)username, - &dwAccountSize,(LPSTR)domain, &dwDomainSize, &snu); - return 0; -} - -/* - * Retrieve user homedir from token, save it in static string - * and return pointer to this string. - * - * userName - user's name (IN) - * token - logon user's token (IN) - * - * RETURNS: pointer to static string with homedir or NULL if fails. - */ - -#define SET_USER_ENV(folder_id, evn_variable) do { \ - if (SHGetKnownFolderPath(&folder_id,0,token,&path) == S_OK) \ - { \ - SetEnvironmentVariableW(evn_variable, path); \ - CoTaskMemFree(path); \ - } \ -} while (0) - -/* - * Temporary getpwuid implementaion of Windows. This should be replaced with getpw_currentuser - */ - - - - /* TODO - this is moved from realpath.c in openbsdcompat. Review and finalize its position*/ diff --git a/contrib/win32/win32compat/shell-host.c b/contrib/win32/win32compat/shell-host.c index 760bf42..ae7cd4f 100644 --- a/contrib/win32/win32compat/shell-host.c +++ b/contrib/win32/win32compat/shell-host.c @@ -50,32 +50,29 @@ #define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200 #endif -HINSTANCE hUserLibrary; -HINSTANCE hKernelLibrary; +typedef BOOL (WINAPI *__t_SetCurrentConsoleFontEx)( + _In_ HANDLE hConsoleOutput, + _In_ BOOL bMaximumWindow, + _In_ PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx + ); +__t_SetCurrentConsoleFontEx __SetCurrentConsoleFontEx; -// kernel32.dll -typedef BOOL(WINAPI * fSetCurrentConsoleFontEx)( - _In_ HANDLE hConsoleOutput, - _In_ BOOL bMaximumWindow, - _In_ PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx); -fSetCurrentConsoleFontEx fnSetCurrentConsoleFontEx = NULL; +typedef BOOL (WINAPI *__t_UnhookWinEvent)( + _In_ HWINEVENTHOOK hWinEventHook + ); +__t_UnhookWinEvent __UnhookWinEvent; -// user32.dll -typedef HWINEVENTHOOK (WINAPI * fSetWinEventHook)( - _In_ UINT eventMin, - _In_ UINT eventMax, - _In_ HMODULE hmodWinEventProc, - _In_ WINEVENTPROC lpfnWinEventProc, - _In_ DWORD idProcess, - _In_ DWORD idThread, - _In_ UINT dwflags -); -fSetWinEventHook fnSetWinEventHook = NULL; +typedef HWINEVENTHOOK (WINAPI *__t_SetWinEventHook)( + _In_ UINT eventMin, + _In_ UINT eventMax, + _In_ HMODULE hmodWinEventProc, + _In_ WINEVENTPROC lpfnWinEventProc, + _In_ DWORD idProcess, + _In_ DWORD idThread, + _In_ UINT dwflags + ); +__t_SetWinEventHook __SetWinEventHook; -typedef BOOL (WINAPI * fUnhookWinEvent)( - _In_ HWINEVENTHOOK hWinEventHook -); -fUnhookWinEvent fnUnhookWinEvent = NULL; typedef struct consoleEvent { DWORD event; @@ -417,8 +414,7 @@ void SizeWindow(HANDLE hInput) { matchingFont.FontWeight = FW_NORMAL; wcscpy(matchingFont.FaceName, L"Consolas"); - if(fnSetCurrentConsoleFontEx != NULL) - bSuccess = fnSetCurrentConsoleFontEx(child_out, FALSE, &matchingFont); + bSuccess = SetCurrentConsoleFontEx(child_out, FALSE, &matchingFont); // This information is the live screen ZeroMemory(&consoleInfo, sizeof(consoleInfo)); @@ -855,7 +851,7 @@ DWORD WINAPI ProcessPipes(LPVOID p) { INPUT_RECORD ir; if (buf[i] == 3) {/*Ctrl+C - Raise Ctrl+C*/ - GenerateConsoleCtrlEvent(CTRL_C_EVENT, childProcessId); + GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); continue; } @@ -1076,7 +1072,7 @@ cleanup: return 0; } -int wmain(int ac, wchar_t **av) { +int start_with_pty(int ac, wchar_t **av) { STARTUPINFO si; PROCESS_INFORMATION pi; wchar_t cmd[MAX_PATH]; @@ -1086,22 +1082,7 @@ int wmain(int ac, wchar_t **av) { DWORD dwMode; DWORD dwStatus; HANDLE hEventHook = NULL; - - HINSTANCE hUserLibrary; - HINSTANCE hKernelLibrary; - - hKernelLibrary = LoadLibrary(L"kernel32.dll"); - if (hKernelLibrary != NULL) - { - fnSetCurrentConsoleFontEx = (fSetCurrentConsoleFontEx)GetProcAddress(hKernelLibrary, "SetCurrentConsoleFontEx"); - } - - hUserLibrary = LoadLibrary(L"user32.dll"); - if (hUserLibrary != NULL) - { - fnSetWinEventHook = (fSetWinEventHook)GetProcAddress(hUserLibrary, "SetWinEventHook"); - fnUnhookWinEvent = (fUnhookWinEvent)GetProcAddress(hUserLibrary, "UnhookWinEvent"); - } + HMODULE hm_kernel32 = NULL, hm_user32 = NULL; pipe_in = GetStdHandle(STD_INPUT_HANDLE); pipe_out = GetStdHandle(STD_OUTPUT_HANDLE); @@ -1121,27 +1102,14 @@ int wmain(int ac, wchar_t **av) { memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); sa.bInheritHandle = TRUE; - /* create job to hold all child processes */ - { - /* TODO - this does not work as expected*/ - HANDLE job = CreateJobObject(NULL, NULL); - JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info; - memset(&job_info, 0, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); - job_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; - if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &job_info, sizeof(job_info))) - return -1; - CloseHandle(job); - } - /* WM_APPEXIT */ hostThreadId = GetCurrentThreadId(); hostProcessId = GetCurrentProcessId(); InitializeCriticalSection(&criticalSection); - if(fnSetWinEventHook != NULL) - hEventHook = SetWinEventHook(EVENT_CONSOLE_CARET, EVENT_CONSOLE_LAYOUT, NULL, - ConsoleEventProc, 0, 0, WINEVENT_OUTOFCONTEXT); + hEventHook = SetWinEventHook(EVENT_CONSOLE_CARET, EVENT_CONSOLE_LAYOUT, NULL, + ConsoleEventProc, 0, 0, WINEVENT_OUTOFCONTEXT); memset(&si, 0, sizeof(STARTUPINFO)); memset(&pi, 0, sizeof(PROCESS_INFORMATION)); @@ -1149,12 +1117,6 @@ int wmain(int ac, wchar_t **av) { // Copy our parent buffer sizes si.cb = sizeof(STARTUPINFO); si.dwFlags = 0; - if (fnSetWinEventHook == NULL) { - si.hStdInput = INVALID_HANDLE_VALUE; - si.hStdOutput = pipe_out; - si.hStdError = pipe_err; - si.dwFlags = STARTF_USESTDHANDLES; - } /* disable inheritance on pipe_in*/ GOTO_CLEANUP_ON_FALSE(SetHandleInformation(pipe_in, HANDLE_FLAG_INHERIT, 0)); @@ -1175,14 +1137,19 @@ int wmain(int ac, wchar_t **av) { av++; } + SetConsoleCtrlHandler(NULL, FALSE); GOTO_CLEANUP_ON_FALSE(CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)); childProcessId = pi.dwProcessId; FreeConsole(); + Sleep(20); while (!AttachConsole(pi.dwProcessId)) { - Sleep(1000); + DWORD exit_code; + if (GetExitCodeProcess(pi.hProcess, &exit_code) && exit_code != STILL_ACTIVE) + break; + Sleep(100); } /* monitor child exist */ @@ -1215,15 +1182,184 @@ cleanup: WaitForSingleObject(monitor_thread, INFINITE); if (ux_thread != INVALID_HANDLE_VALUE) TerminateThread(ux_thread, S_OK); - if (hEventHook && fnUnhookWinEvent != NULL) - fnUnhookWinEvent(hEventHook); - - if (hKernelLibrary != NULL) - FreeLibrary(hKernelLibrary); - if (hUserLibrary != NULL) - FreeLibrary(hUserLibrary); + if (hEventHook) + UnhookWinEvent(hEventHook); FreeConsole(); return 0; } + +HANDLE child_pipe_read; +HANDLE child_pipe_write; +DWORD WINAPI MonitorChild_nopty( + _In_ LPVOID lpParameter + ) { + WaitForSingleObject(child, INFINITE); + CloseHandle(pipe_in); + //printf("XXXX CHILD PROCESS DEAD XXXXX"); + return 0; +} + +int start_withno_pty(int ac, wchar_t **av) { + STARTUPINFO si; + PROCESS_INFORMATION pi; + wchar_t cmd[MAX_PATH]; + SECURITY_ATTRIBUTES sa; + BOOL ret; + + pipe_in = GetStdHandle(STD_INPUT_HANDLE); + pipe_out = GetStdHandle(STD_OUTPUT_HANDLE); + pipe_err = GetStdHandle(STD_ERROR_HANDLE); + + /* copy pipe handles passed through std io*/ + if ((pipe_in == INVALID_HANDLE_VALUE) + || (pipe_out == INVALID_HANDLE_VALUE) + || (pipe_err == INVALID_HANDLE_VALUE)) + return -1; + + memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); + sa.bInheritHandle = TRUE; + if (!CreatePipe(&child_pipe_read, &child_pipe_write, &sa, 128)) + return -1; + + memset(&si, 0, sizeof(STARTUPINFO)); + memset(&pi, 0, sizeof(PROCESS_INFORMATION)); + + si.cb = sizeof(STARTUPINFO); + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdInput = child_pipe_read; + si.hStdOutput = pipe_out; + si.hStdError = pipe_err; + + /* disable inheritance on child_pipe_write and pipe_in*/ + GOTO_CLEANUP_ON_FALSE(SetHandleInformation(pipe_in, HANDLE_FLAG_INHERIT, 0)); + GOTO_CLEANUP_ON_FALSE(SetHandleInformation(child_pipe_write, HANDLE_FLAG_INHERIT, 0)); + + /*TODO - pick this up from system32*/ + cmd[0] = L'\0'; + GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L"cmd.exe")); + ac -= 2; + av += 2; + if (ac) + GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L" /c")); + while (ac) { + GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L" ")); + GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, *av)); + ac--; + av++; + } + + GOTO_CLEANUP_ON_FALSE(CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)); + + /* close unwanted handles*/ + CloseHandle(child_pipe_read); + child_pipe_read = INVALID_HANDLE_VALUE; + + child = pi.hProcess; + /* monitor child exist */ + monitor_thread = CreateThread(NULL, 0, MonitorChild_nopty, NULL, 0, NULL); + if (monitor_thread == INVALID_HANDLE_VALUE) + goto cleanup; + + /* disable Ctrl+C hander in this process*/ + SetConsoleCtrlHandler(NULL, TRUE); + + /* process data from pipe_in and route appropriately */ + while (1) { + char buf[128]; + DWORD rd = 0, wr = 0, i = 0; + GOTO_CLEANUP_ON_FALSE(ReadFile(pipe_in, buf, 128, &rd, NULL)); + + while (i < rd) { + + /* skip arrow keys */ + if ((rd - i >= 3) && (buf[i] == '\033') && (buf[i + 1] == '[') + && (buf[i + 2] >= 'A') && (buf[i + 2] <= 'D')) { + i += 3; + continue; + } + + /* skip tab */ + if (buf[i] == '\t') { + i++; + continue; + } + + // Ctrl +C + if (buf[i] == '\003') { + GOTO_CLEANUP_ON_FALSE(GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0)); + in_cmd_len = 0; + i++; + continue; + } + + // for backspace, we need to send space and another backspace for visual erase + if (buf[i] == '\b') { + if (in_cmd_len > 0) { + GOTO_CLEANUP_ON_FALSE(WriteFile(pipe_out, "\b \b", 3, &wr, NULL)); + in_cmd_len--; + } + i++; + continue; + } + + //for CR and LF + if ((buf[i] == '\r') || (buf[i] == '\n')) { + + /* TODO - do a much accurate mapping */ + GOTO_CLEANUP_ON_FALSE(WriteFile(pipe_out, buf + i, 1, &wr, NULL)); + if ((buf[i] == '\r') && ((i == rd - 1) || (buf[i + 1] != '\n'))) { + buf[i] = '\n'; + GOTO_CLEANUP_ON_FALSE(WriteFile(pipe_out, buf + i, 1, &wr, NULL)); + } + in_cmd[in_cmd_len] = buf[i]; + in_cmd_len++; + GOTO_CLEANUP_ON_FALSE(WriteFile(child_pipe_write, in_cmd, in_cmd_len, &wr, NULL)); + in_cmd_len = 0; + i++; + continue; + } + + + GOTO_CLEANUP_ON_FALSE(WriteFile(pipe_out, buf + i, 1, &wr, NULL)); + in_cmd[in_cmd_len] = buf[i]; + in_cmd_len++; + if (in_cmd_len == MAX_CMD_LEN - 1) { + GOTO_CLEANUP_ON_FALSE(WriteFile(child_pipe_write, in_cmd, in_cmd_len, &wr, NULL)); + in_cmd_len = 0; + } + + i++; + } + } + +cleanup: + + if (child != INVALID_HANDLE_VALUE) + TerminateProcess(child, 0); + if (monitor_thread != INVALID_HANDLE_VALUE) + WaitForSingleObject(monitor_thread, INFINITE); + return 0; +} + +int wmain(int ac, wchar_t **av) { + + + /* create job to hold all child processes */ + { + /* TODO - this does not work as expected*/ + HANDLE job = CreateJobObject(NULL, NULL); + JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info; + memset(&job_info, 0, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); + job_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &job_info, sizeof(job_info))) + return -1; + CloseHandle(job); + } + + if ((ac == 1) || wcscmp(av[1], L"-nopty")) + return start_with_pty(ac, av); + else + return start_withno_pty(ac, av); +} \ No newline at end of file diff --git a/contrib/win32/win32compat/ssh-agent/agent-main.c b/contrib/win32/win32compat/ssh-agent/agent-main.c index dac972c..9090026 100644 --- a/contrib/win32/win32compat/ssh-agent/agent-main.c +++ b/contrib/win32/win32compat/ssh-agent/agent-main.c @@ -90,8 +90,8 @@ BOOL WINAPI ctrl_c_handler( return TRUE; } -int main(int argc, char **argv) { - +int wmain(int argc, wchar_t **argv) { + w32posix_initialize(); load_config(); if (!StartServiceCtrlDispatcherW(dispatch_table)) { @@ -108,7 +108,7 @@ int main(int argc, char **argv) { if (argc == 2) { /*agent process is likely a spawned child*/ char* h = 0; - h += atoi(*(argv + 1)); + h += _wtoi(*(argv + 1)); if (h != 0) { log_init("ssh-agent", config_log_level(), 1, 0); agent_start(FALSE, TRUE, h); @@ -146,7 +146,7 @@ int scm_start_service(DWORD num, LPWSTR* args) { ZeroMemory(&service_status, sizeof(service_status)); service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 300); - ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0); + ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0); log_init("ssh-agent", config_log_level(), 1, 0); agent_start(FALSE, FALSE, 0); return 0; diff --git a/contrib/win32/win32compat/w32fd.c b/contrib/win32/win32compat/w32fd.c index 4140a39..8f0022f 100644 --- a/contrib/win32/win32compat/w32fd.c +++ b/contrib/win32/win32compat/w32fd.c @@ -126,8 +126,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/scp.c b/scp.c index 03f48f4..2e0dee3 100644 --- a/scp.c +++ b/scp.c @@ -2230,6 +2230,10 @@ int start_process_io(char *exename, char **argv, char **envv, ctr = 0; cmdbuf[0] = '\0'; + if (argv[0][0] != '\0' && argv[0][1] != ':') { + strcat(cmdbuf, w32_programdir()); + strcat(cmdbuf, "\\"); + } while (argv[ctr]) { strcat_s(cmdbuf, sizeof(cmdbuf), argv[ctr]); strcat_s(cmdbuf, sizeof(cmdbuf), " "); diff --git a/session.c b/session.c index 49b3c78..c40efb1 100644 --- a/session.c +++ b/session.c @@ -99,6 +99,7 @@ #include "sftp.h" #ifdef WIN32_FIXME #include "console.h" +#include #endif #ifdef WIN32_FIXME @@ -112,9 +113,6 @@ FIXME: GFPZR: Function stat() may be undeclared. #include #include -#ifdef WIN32_PRAGMA_REMCON -#include -#endif extern char HomeDirLsaW[MAX_PATH]; #endif @@ -491,14 +489,383 @@ do_authenticated1(Authctxt *authctxt) } } -// PRAGMA:TODO -#ifndef WIN32_FIXME -#define USE_PIPES 1 -#endif +#ifdef WINDOWS -#ifdef WIN32_FIXME -extern int debug_flag; -#endif +#define SET_USER_ENV(folder_id, evn_variable) do { \ + if (SHGetKnownFolderPath(&folder_id,0,token,&path) == S_OK) \ + { \ + SetEnvironmentVariableW(evn_variable, path); \ + CoTaskMemFree(path); \ + } \ +} while (0) + +void setup_session_vars(Session* s) +{ + wchar_t* pw_dir_w; + wchar_t* tmp; + char buf[128]; + char* laddr; + + if ((pw_dir_w = utf8_to_utf16(s->pw->pw_dir)) == NULL) + fatal("%s: out of memory"); + + + + if ((tmp = utf8_to_utf16(s->pw->pw_name)) == NULL) + fatal("%s, out of memory"); + SetEnvironmentVariableW(L"USERNAME", tmp); + free(tmp); + + if (s->display) + SetEnvironmentVariableA("DISPLAY", s->display); + + + SetEnvironmentVariableW(L"HOMEPATH", pw_dir_w); + SetEnvironmentVariableW(L"USERPROFILE", pw_dir_w); + + if (pw_dir_w[1] == L':') { + wchar_t wc = pw_dir_w[2]; + pw_dir_w[2] = L'\0'; + SetEnvironmentVariableW(L"HOMEDRIVE", pw_dir_w); + pw_dir_w[2] = wc; + } + + snprintf(buf, sizeof buf, "%.50s %d %d", + get_remote_ipaddr(), get_remote_port(), get_local_port()); + + SetEnvironmentVariableA("SSH_CLIENT", buf); + + laddr = get_local_ipaddr(packet_get_connection_in()); + + snprintf(buf, sizeof buf, "%.50s %d %.50s %d", + get_remote_ipaddr(), get_remote_port(), laddr, get_local_port()); + + free(laddr); + + SetEnvironmentVariableA("SSH_CONNECTION", buf); + + if (original_command) + SetEnvironmentVariableA("SSH_ORIGINAL_COMMAND", original_command); + + + if ((s->term) && (s->term[0])) + SetEnvironmentVariable("TERM", s->term); + + if (!s->is_subsystem) { + snprintf(buf, sizeof buf, "%s@%s $P$G", s->pw->pw_name, getenv("COMPUTERNAME")); + SetEnvironmentVariableA("PROMPT", buf); + } + + /*set user environment variables*/ + { + UCHAR InfoBuffer[1000]; + PTOKEN_USER pTokenUser = (PTOKEN_USER)InfoBuffer; + DWORD dwInfoBufferSize, tmp_len; + LPWSTR sid_str = NULL; + wchar_t reg_path[MAX_PATH]; + HKEY reg_key = 0; + HANDLE token = s->authctxt->methoddata; + + tmp_len = MAX_PATH; + if (GetTokenInformation(token, TokenUser, InfoBuffer, + 1000, &dwInfoBufferSize) == FALSE || + ConvertSidToStringSidW(pTokenUser->User.Sid, &sid_str) == FALSE || + swprintf(reg_path, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", sid_str) == MAX_PATH || + RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY, ®_key) != 0 || + RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, pw_dir_w, &tmp_len) != 0) { + /* one of the above failed */ + debug("cannot retirve profile path - perhaps user profile is not created yet"); + } + + if (sid_str) + LocalFree(sid_str); + + if (reg_key) + RegCloseKey(reg_key); + + { /* retrieve and set env variables. */ + /* TODO - Get away with fixed limits and dynamically allocate required memory, cleanup this logic*/ +#define MAX_VALUE_LEN 1000 +#define MAX_DATA_LEN 2000 +#define MAX_EXPANDED_DATA_LEN 5000 + wchar_t *path; + wchar_t value_name[MAX_VALUE_LEN]; + wchar_t value_data[MAX_DATA_LEN], value_data_expanded[MAX_EXPANDED_DATA_LEN], *to_apply; + DWORD value_type, name_len, data_len; + int i; + LONG ret; + + if (ImpersonateLoggedOnUser(token) == FALSE) + debug("Failed to impersonate user token, %d", GetLastError()); + SET_USER_ENV(FOLDERID_LocalAppData, L"LOCALAPPDATA"); + SET_USER_ENV(FOLDERID_Profile, L"USERPROFILE"); + SET_USER_ENV(FOLDERID_RoamingAppData, L"APPDATA"); + reg_key = 0; + if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Environment", 0, KEY_QUERY_VALUE, ®_key) == ERROR_SUCCESS) { + i = 0; + while (1) { + name_len = MAX_VALUE_LEN * 2; + data_len = MAX_DATA_LEN * 2; + to_apply = NULL; + if (RegEnumValueW(reg_key, i++, &value_name, &name_len, 0, &value_type, &value_data, &data_len) != ERROR_SUCCESS) + break; + if (value_type == REG_SZ) + to_apply = value_data; + else if (value_type == REG_EXPAND_SZ) { + ExpandEnvironmentStringsW(value_data, value_data_expanded, MAX_EXPANDED_DATA_LEN); + to_apply = value_data_expanded; + } + + if (wcsicmp(value_name, L"PATH") == 0) { + DWORD size; + if ((size = GetEnvironmentVariableW(L"PATH", NULL, 0)) != ERROR_ENVVAR_NOT_FOUND) { + memcpy(value_data_expanded + size, to_apply, (wcslen(to_apply) + 1) * 2); + GetEnvironmentVariableW(L"PATH", value_data_expanded, MAX_EXPANDED_DATA_LEN); + value_data_expanded[size - 1] = L';'; + to_apply = value_data_expanded; + } + + } + if (to_apply) + SetEnvironmentVariableW(value_name, to_apply); + + + } + RegCloseKey(reg_key); + } + + + RevertToSelf(); + } + } + + free(pw_dir_w); +} + +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, *pw_dir_w; + + 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) + fatal("%s: cannot create pipe: %.100s", __func__, strerror(errno)); + + if ((pw_dir_w = utf8_to_utf16(s->pw->pw_dir)) == NULL) + fatal("%s: out of memory"); + + + 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 || (command && memcmp(command, "scp", 3) == 0)) { + /* 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 " : "ssh-shellhost.exe -nopty ", *c; + exec_command = malloc(strlen(progdir) + 1 + strlen(shell_host) + (command ? strlen(command) : 0) + 1); + if (exec_command == NULL) + fatal("%s, out of memory"); + c = exec_command; + memcpy(c, progdir, strlen(progdir)); + c += strlen(progdir); + *c++ = '\\'; + memcpy(c, shell_host, strlen(shell_host)); + c += strlen(shell_host); + if (command) { + memcpy(c, command, strlen(command)); + c += strlen(command); + } + *c = '\0'; + } + + /* setup Environment varibles */ + setup_session_vars(s); + + extern int debug_flag; + + PROCESS_INFORMATION pi; + STARTUPINFOW si; + + BOOL b; + + HANDLE hToken = INVALID_HANDLE_VALUE; + + + /* + * Assign sockets to StartupInfo + */ + + memset(&si, 0, sizeof(STARTUPINFO)); + + si.cb = sizeof(STARTUPINFO); + si.lpReserved = 0; + si.lpTitle = NULL; /* NULL means use exe name as title */ + si.dwX = 0; + si.dwY = 0; + si.dwXSize = 5; + si.dwYSize = 5; + si.dwXCountChars = s->col; + si.dwYCountChars = s->row; + si.dwFillAttribute = 0; + si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESIZE | STARTF_USECOUNTCHARS; + si.wShowWindow = 0; // FALSE ; + si.cbReserved2 = 0; + si.lpReserved2 = 0; + + si.hStdInput = (HANDLE)sfd_to_handle(pipein[0]); + si.hStdOutput = (HANDLE)sfd_to_handle(pipeout[1]); + si.hStdError = (HANDLE)sfd_to_handle(pipeerr[1]); + si.lpDesktop = NULL; + + hToken = s->authctxt->methoddata; + + debug("Executing command: %s", exec_command); + + /* Create the child process */ + + exec_command_w = utf8_to_utf16(exec_command); + + if (debug_flag) + b = CreateProcessW(NULL, exec_command_w, NULL, NULL, TRUE, + DETACHED_PROCESS, NULL, pw_dir_w, + &si, &pi); + else + b = CreateProcessAsUserW(hToken, NULL, exec_command_w, NULL, NULL, TRUE, + DETACHED_PROCESS , NULL, pw_dir_w, + &si, &pi); + + if (!b) + { + debug("ERROR. Cannot create process (%u).\n", GetLastError()); + + CloseHandle(hToken); + + exit(1); + } + else if (pty) { /*attach to shell console */ + FreeConsole(); + if (!debug_flag) + ImpersonateLoggedOnUser(hToken); + Sleep(20); + while (AttachConsole(pi.dwProcessId) == FALSE) { + DWORD exit_code; + if (GetExitCodeProcess(pi.hProcess, &exit_code) && exit_code != STILL_ACTIVE) + break; + Sleep(100); + } + if (!debug_flag) + RevertToSelf(); + { + /* TODO - check this - Create Process above is not respecting x# and y# chars, so we are doing this explicity on the + * attached console agein */ + + COORD coord; + coord.X = s->col; + coord.Y = 9999;; + SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coord); + } + } + + s->pid = pi.dwProcessId; + sw_add_child(pi.hProcess, pi.dwProcessId); + + /* + * Set interactive/non-interactive mode. + */ + + packet_set_interactive(s->display != NULL, options.ip_qos_interactive, + options.ip_qos_bulk); + + /* + * We are the parent. Close the child sides of the socket pairs. + */ + + close(pipein[0]); + close(pipeout[1]); + close(pipeerr[1]); + + + /* + * 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 + */ + + CloseHandle(pi.hThread); + + // CloseHandle(pi.hProcess); + + /* + * Clear loginmsg, since it's the child's responsibility to display + * it to the user, otherwise multiple sessions may accumulate + * multiple copies of the login messages. + */ + + buffer_clear(&loginmsg); + + /* + * Enter the interactive session. Note: server_loop must be able to + * handle the case that fdin and fdout are the same. + */ + + if (compat20) + { + if (s->ttyfd == -1) + session_set_fds(s, pipein[1], pipeout[0], pipeerr[0], s->is_subsystem, 0); + else + session_set_fds(s, pipein[1], pipeout[0], pipeerr[0], s->is_subsystem, 1); // tty interactive session + } + else + { + server_loop(pi.hProcess, pipein[1], pipeout[0], pipeerr[0]); + + /* + * server_loop has closed inout[0] and err[0]. + */ + } + + return 0; + +} + +int +do_exec_no_pty(Session *s, const char *command) { + return do_exec_windows(s, command, 0); +} + +int +do_exec_pty(Session *s, const char *command) { + return do_exec_windows(s, command, 1); +} + +#else /* * This is called to fork and execute a command when we have no tty. This @@ -508,408 +875,6 @@ extern int debug_flag; int do_exec_no_pty(Session *s, const char *command) { -#ifdef WIN32_FIXME - wchar_t* pw_dir_utf16 = utf8_to_utf16(s->pw->pw_dir); - - /* - * Win32 code. - */ - - if (s -> is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) - { - printf("This service allows sftp connections only.\n"); - fflush(NULL); - exit(1); - } - else if (s -> is_subsystem == SUBSYSTEM_INT_SFTP) - { - u_int i; - for (i = 0; i < options.num_subsystems; i++) - { - if (strcmp("sftp", options.subsystem_name[i]) == 0) - { - command = options.subsystem_args[i]; - } - } - } - - PROCESS_INFORMATION pi; - STARTUPINFOW si; - - int pipein[2]; - int pipeout[2]; - int pipeerr[2]; - - BOOL b; - - HANDLE hToken = INVALID_HANDLE_VALUE; - - int do_xauth; - - FILE *f = NULL; - - char cmd[1024]; - char *exec_command; - char *laddr; - char buf[256]; - #ifdef WIN32_PRAGMA_REMCON - char exec_command_str[512]; - #endif - - if (!command) - { - #ifndef WIN32_PRAGMA_REMCON - exec_command = s->pw->pw_shell; - #else - if ( PathFileExists("\\program files\\pragma\\shared files\\cmdserver.exe") ) - snprintf(exec_command_str, sizeof(exec_command_str), - "\\program files\\pragma\\shared files\\cmdserver.exe SSHD %d %d", s->row, s->col ); - else { - // find base path of our executable - char basepath[MAX_PATH]; - strcpy_s(basepath, MAX_PATH, __progname); - PathRemoveFileSpec(basepath); // get the full dir part of the name - snprintf(exec_command_str, sizeof(exec_command_str), - "%s\\cmdserver.exe SSHD %d %d", basepath,s->row, s->col); - } - exec_command = exec_command_str; - #endif - } - else - { - exec_command = command; - } - - do_xauth = s -> display != NULL && s -> auth_proto != NULL && s -> auth_data != NULL; - - /* - * 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)) - { - extern HANDLE hInputConsole; - extern HANDLE hOutputConsole ; - hInputConsole = GetConsoleInputHandle(); - hOutputConsole = GetConsoleOutputHandle(); - ConSetScreenSize( s->col, s->row ); - s->ptyfd = pipein[1]; // hConsole; // the pty is the Windows console output handle in our Win32 port - } - - 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 - */ - - memset(&si, 0 , sizeof(STARTUPINFO)); - - si.cb = sizeof(STARTUPINFO); - si.lpReserved = 0; - si.lpTitle = NULL; /* NULL means use exe name as title */ - si.dwX = 0; - si.dwY = 0; - si.dwXSize = 5; - si.dwYSize = 5; - si.dwXCountChars = s->col; - si.dwYCountChars = s->row; - si.dwFillAttribute = 0; - si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESIZE | STARTF_USECOUNTCHARS; - si.wShowWindow = 0; // FALSE ; - si.cbReserved2 = 0; - si.lpReserved2 = 0; - - si.hStdInput = (HANDLE) sfd_to_handle(pipein[0]); - si.hStdOutput = (HANDLE) sfd_to_handle(pipeout[1]); - si.hStdError = (HANDLE) sfd_to_handle(pipeerr[1]); - si.lpDesktop = NULL; - - SetEnvironmentVariable("USER", s->pw->pw_name); - SetEnvironmentVariable("USERNAME", s->pw->pw_name); - SetEnvironmentVariable("LOGNAME", s->pw->pw_name); - - /* - * Setup xauth if needed - */ - - if (do_xauth && options.xauth_location != NULL) - { - /* - * Add authority data to .Xauthority if appropriate. - */ - - if (debug_flag) - { - fprintf(stderr, "Running %.500s remove %.100s\n", - options.xauth_location, s->auth_display); - - fprintf(stderr, "%.500s add %.100s %.100s %.100s\n", options.xauth_location, - s -> auth_display, s -> auth_proto, s -> auth_data); - } - - snprintf(cmd, sizeof cmd, "%s -q -", options.xauth_location); - - f = _popen(cmd, "w"); - - if (f) - { - fprintf(f, "remove %s\n", s -> auth_display); - - fprintf(f, "add %s %s %s\n", s -> auth_display, s -> auth_proto, s -> auth_data); - - _pclose(f); - } - else - { - fprintf(stderr, "Could not run %s\n", cmd); - } - } - - #if 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]); - - #endif - - /* - * If we get this far, the user has already been authenticated - * We should either have a user token in authctxt -> methoddata - * (e.g. for password auth) or we need to create a more restrictive - * token using CreateUserToken for non-password auth mechanisms. - */ - - hToken = s -> authctxt -> methoddata; - - - if (s -> display) - { - SetEnvironmentVariable("DISPLAY", s -> display); - } - - /* - * Change to users home directory - * TODO - pw_dir is utf-8, convert it to utf-16 and call _wchdir - * also change subsequent calls to SetEnvironmentVariable - */ - - _wchdir(pw_dir_utf16); - - SetEnvironmentVariableW(L"HOME", pw_dir_utf16); - SetEnvironmentVariableW(L"USERPROFILE", pw_dir_utf16); - - wchar_t *wstr, wchr; - wstr = wcschr(pw_dir_utf16, L':'); - if (wstr) { - wchr = *(wstr + 1); - *(wstr + 1) = '\0'; - SetEnvironmentVariableW(L"HOMEDRIVE", pw_dir_utf16); - *(wstr + 1) = wchr; - SetEnvironmentVariableW(L"HOMEPATH", (wstr+1)); - } - - - - // find the server name of the domain controller which created this token - GetDomainFromToken ( &hToken, buf, sizeof(buf)); - if (buf[0]) - SetEnvironmentVariable("USERDOMAIN", buf ); - - /* - * Set SSH_CLIENT variable. - */ - - snprintf(buf, sizeof buf, "%.50s %d %d", - get_remote_ipaddr(), get_remote_port(), get_local_port()); - - SetEnvironmentVariableA("SSH_CLIENT", buf); - - /* - * Set SSH_CONNECTION variable. - */ - - laddr = get_local_ipaddr(packet_get_connection_in()); - - snprintf(buf, sizeof buf, "%.50s %d %.50s %d", - get_remote_ipaddr(), get_remote_port(), laddr, get_local_port()); - - free(laddr); - - SetEnvironmentVariableA("SSH_CONNECTION", buf); - - if (original_command) - SetEnvironmentVariableA("SSH_ORIGINAL_COMMAND", original_command); - - - // set better prompt for Windows cmd shell - if (!s -> is_subsystem) { - snprintf(buf,sizeof buf, "%s@%s $P$G", s->pw->pw_name, getenv("COMPUTERNAME")); - SetEnvironmentVariableA("PROMPT", buf); - } - - /* - * Get the current user's name (associated with sshd thread). - */ - - debug3("Home path before CreateProcessAsUser [%ls]", s -> pw -> pw_dir); - - DWORD size = 256; - - char name[256]; - - GetUserName(name, &size); - - if ( (s->term) && (s->term[0]) ) - SetEnvironmentVariable("TERM", s->term); - /* - * Create new process as other user using access token object. - */ - - debug("Executing command: %s", exec_command); - - /* - * Create the child process - */ - - wchar_t exec_command_w[MAX_PATH]; - - MultiByteToWideChar(CP_UTF8, 0, exec_command, -1, exec_command_w, MAX_PATH); - DWORD dwStartupFlags = DETACHED_PROCESS;// CREATE_SUSPENDED; // 0 - - SetConsoleCtrlHandler(NULL, FALSE); - - wchar_t* p_dir = utf8_to_utf16(s->pw->pw_dir); - if (debug_flag) - b = CreateProcessW(NULL, exec_command_w, NULL, NULL, TRUE, - /*CREATE_NEW_PROCESS_GROUP*/ dwStartupFlags, NULL, pw_dir_utf16, - &si, &pi); - else - b = CreateProcessAsUserW(hToken, NULL, exec_command_w, NULL, NULL, TRUE, - /*CREATE_NEW_PROCESS_GROUP*/ dwStartupFlags, NULL, pw_dir_utf16, - &si, &pi); - - if (!b) - { - debug("ERROR. Cannot create process (%u).\n", GetLastError()); - - CloseHandle(hToken); - - exit(1); - } - else if (s->ttyfd != -1) { /*attach to shell console */ - FreeConsole(); - if (!debug_flag) - ImpersonateLoggedOnUser(hToken); - while (AttachConsole(pi.dwProcessId) == FALSE) { - Sleep(200); - } - if (!debug_flag) - RevertToSelf(); - { - /* TODO - check this - Create Process above is not respecting x# and y# chars, so we are doing this explicity on the - * attached console agein */ - - COORD coord; - coord.X = s->col; - coord.Y = 9999;; - SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coord); - } - } - - /* - * Save token used for create child process. We'll need it on cleanup - * to clean up DACL of Winsta0. - */ - - /* - * Log the process handle (fake it as the pid) for termination lookups - */ - - s -> pid = pi.dwProcessId; - sw_add_child(pi.hProcess, pi.dwProcessId); - - // Add the child process created to select mux so that during our select data call we know if the process has exited - /* TODO - fix thi s*/ - //int WSHELPAddChildToWatch ( HANDLE processtowatch); - //WSHELPAddChildToWatch ( pi.hProcess); - - /* - * Set interactive/non-interactive mode. - */ - - packet_set_interactive(s -> display != NULL, options.ip_qos_interactive, - options.ip_qos_bulk); - - /* - * We are the parent. Close the child sides of the socket pairs. - */ - - close(pipein[0]); - close(pipeout[1]); - close(pipeerr[1]); - - ResumeThread ( pi.hThread ); /* now let cmd shell main thread be active s we have closed all i/o file handle that cmd will use */ - SetConsoleCtrlHandler(NULL, TRUE); - - /* - * 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 - */ - - CloseHandle(pi.hThread); - - // CloseHandle(pi.hProcess); - - /* - * Clear loginmsg, since it's the child's responsibility to display - * it to the user, otherwise multiple sessions may accumulate - * multiple copies of the login messages. - */ - - buffer_clear(&loginmsg); - - /* - * Enter the interactive session. Note: server_loop must be able to - * handle the case that fdin and fdout are the same. - */ - - if (compat20) - { - if ( s->ttyfd == -1) - session_set_fds(s, pipein[1], pipeout[0], pipeerr[0], s -> is_subsystem, 0); - else - session_set_fds(s, pipein[1], pipeout[0], pipeerr[0], s -> is_subsystem, 1); // tty interactive session - } - else - { - server_loop(pi.hProcess, pipein[1], pipeout[0], pipeerr[0]); - - /* - * server_loop has closed inout[0] and err[0]. - */ - } - - return 0; - - #else - - /* - * Original OpenSSH code. - */ pid_t pid; #ifdef USE_PIPES @@ -1094,7 +1059,7 @@ do_exec_no_pty(Session *s, const char *command) } #endif return 0; -#endif /* else WIN32_FIXME */ + } /* @@ -1106,11 +1071,6 @@ do_exec_no_pty(Session *s, const char *command) int do_exec_pty(Session *s, const char *command) { -#ifndef WIN32_FIXME - - /* - * Original OpenSSH code. - */ int fdout, ptyfd, ttyfd, ptymaster; pid_t pid; @@ -1222,17 +1182,8 @@ do_exec_pty(Session *s, const char *command) /* server_loop _has_ closed ptyfd and fdout. */ } return 0; -#else - - /* - * Win32 code. - */ - - //return 0; - return do_exec_no_pty(s, command); - -#endif } +#endif #ifdef LOGIN_NEEDS_UTMPX static void @@ -2616,9 +2567,7 @@ session_pty_req(Session *s) /* for SSH1 the tty modes length is not given */ if (!compat20) n_bytes = packet_remaining(); - #ifndef WIN32_PRAGMA_REMCON tty_parse_modes(s->ttyfd, &n_bytes); - #endif if (!use_privsep) pty_setowner(s->pw, s->tty); @@ -2626,9 +2575,7 @@ session_pty_req(Session *s) /* Set window size from the packet. */ pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); - #ifndef WIN32_PRAGMA_REMCON packet_check_eom(); - #endif session_proctitle(s); return 1; } diff --git a/sftp-server.c b/sftp-server.c index dacbbe3..09633af 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -35,6 +35,7 @@ #ifdef WIN32_VS #include "win32_dirent.h" +#include #else #include #endif diff --git a/sftp.c b/sftp.c index cab175c..3332fb4 100644 --- a/sftp.c +++ b/sftp.c @@ -2396,6 +2396,11 @@ connect_to_server(char *path, char **args, int *in, int *out) STARTUPINFO si = { 0 }; debug3("Generating ssh-client command..."); + fullCmd[0] = '\0'; + if (path[0] != '\0' && path[1] != ':') { + strncat(fullCmd, w32_programdir(), MAX_PATH); + strncat(fullCmd, "\\", MAX_PATH); + } strncat(fullCmd, path, MAX_PATH); for (i = 1; args[i]; i++) { strncat(fullCmd, " ", MAX_PATH); diff --git a/ssh.c b/ssh.c index 83dd270..d785bd0 100644 --- a/ssh.c +++ b/ssh.c @@ -118,7 +118,6 @@ #include char dotsshdir[MAX_PATH]; - extern HANDLE hInputConsole; #endif /* WIN32_FIXME */ @@ -1393,7 +1392,6 @@ main(int ac, char **av) if (tty_flag) { //AllocConsole(); ConInputInitParams(); // init the Console input side with global parameters - hInputConsole = GetStdHandle(STD_INPUT_HANDLE); ConInit(STD_OUTPUT_HANDLE, TRUE); //init the output console surface for us to write ConClearScreen(); } 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}; diff --git a/sshpty.c b/sshpty.c index fb6115d..7ea87ac 100644 --- a/sshpty.c +++ b/sshpty.c @@ -21,7 +21,6 @@ #ifdef WIN32_FIXME #undef GSSAPI #undef KRB5 -//#define WIN32_PRAGMA_REMCON #endif #include