From 1ff1b074103f7b20d17b5cc3687d4866b0fd345d Mon Sep 17 00:00:00 2001 From: Manoj Ampalam Date: Mon, 24 Apr 2017 22:02:03 -0700 Subject: [PATCH] Run SSHD as NetworkService (#121) PowerShell/Win32-OpenSSH#681 --- .../win32/openssh/Win32-OpenSSh-design.pptx | Bin 0 -> 31637 bytes contrib/win32/openssh/install-sshd.ps1 | 70 +----- .../win32/win32compat/ssh-agent/agent-main.c | 35 ++- contrib/win32/win32compat/ssh-agent/agent.c | 204 +++++++-------- contrib/win32/win32compat/ssh-agent/agent.h | 13 +- .../win32/win32compat/ssh-agent/agentconfig.c | 1 - .../win32compat/ssh-agent/authagent-request.c | 4 +- .../win32/win32compat/ssh-agent/connection.c | 233 +++++++++--------- .../win32compat/ssh-agent/keyagent-request.c | 83 ++++--- 9 files changed, 282 insertions(+), 361 deletions(-) create mode 100644 contrib/win32/openssh/Win32-OpenSSh-design.pptx diff --git a/contrib/win32/openssh/Win32-OpenSSh-design.pptx b/contrib/win32/openssh/Win32-OpenSSh-design.pptx new file mode 100644 index 0000000000000000000000000000000000000000..4c95fb82361e4229d2e376d8da83669a0e4bd76e GIT binary patch literal 31637 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 literal 0 HcmV?d00001 diff --git a/contrib/win32/openssh/install-sshd.ps1 b/contrib/win32/openssh/install-sshd.ps1 index fbdc56574..39078d1ab 100644 --- a/contrib/win32/openssh/install-sshd.ps1 +++ b/contrib/win32/openssh/install-sshd.ps1 @@ -11,70 +11,6 @@ $logsdir = Join-Path $scriptdir "logs" $sshdAccount = "NT SERVICE\SSHD" -#Idea borrowed from http://sqldbamusings.blogspot.com/2012/03/powershell-adding-accounts-to-local.html -function Add-Privilege -{ - param( - [string] $Account, - - [ValidateSet("SeAssignPrimaryTokenPrivilege", "SeServiceLogonRight")] - [string] $Privilege - ) - - #Get $Account SID - $account_sid = $null - try - { - $ntprincipal = new-object System.Security.Principal.NTAccount "$Account" - $sid = $ntprincipal.Translate([System.Security.Principal.SecurityIdentifier]) - $account_sid = $sid.Value.ToString() - } - catch - { - Throw 'Unable to resolve '+ $Account - } - - #Prepare policy settings file to be applied - $settings_to_export = [System.IO.Path]::GetTempFileName() - "[Unicode]" | Set-Content $settings_to_export -Encoding Unicode - "Unicode=yes" | Add-Content $settings_to_export -Force -WhatIf:$false - "[Version]" | Add-Content $settings_to_export -Force -WhatIf:$false - "signature=`"`$CHICAGO`$`"" | Add-Content $settings_to_export -Force -WhatIf:$false - "Revision=1" | Add-Content $settings_to_export -Force -WhatIf:$false - "[Privilege Rights]" | Add-Content $settings_to_export -Force -WhatIf:$false - - #Get Current policy settings - $imported_settings = [System.IO.Path]::GetTempFileName() - secedit.exe /export /areas USER_RIGHTS /cfg "$($imported_settings)" > $null - - if (-not(Test-Path $imported_settings)) { - Throw "Unable to import current security policy settings" - } - - #find current assigned accounts to $Privilege and add it to $settings_to_export - $current_settings = Get-Content $imported_settings -Encoding Unicode - $existing_setting = $null - foreach ($setting in $current_settings) { - if ($setting -like "$Privilege`*") { - $existing_setting = $setting - } - } - - #Add $account_sid to list - if ($existing_setting -eq $null) { - $Privilege + " = *" + $account_sid | Add-Content $settings_to_export -Force -WhatIf:$false - } - else - { - $existing_setting + ",*" + $account_sid | Add-Content $settings_to_export -Force -WhatIf:$false - } - - #export - secedit.exe /configure /db "secedit.sdb" /cfg "$($settings_to_export)" /areas USER_RIGHTS > $null - -} - - if (-not (Test-Path $sshdpath)) { throw "sshd.exe is not present in script path" } @@ -95,10 +31,8 @@ New-Service -Name ssh-agent -BinaryPathName $sshagentpath -Description "SSH Agen cmd.exe /c 'sc.exe sdset ssh-agent D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RP;;;AU)' New-Service -Name sshd -BinaryPathName $sshdpath -Description "SSH Daemon" -StartupType Manual -DependsOn ssh-agent | Out-Null -sc.exe config sshd obj= $sshdAccount - -Add-Privilege -Account $sshdAccount -Privilege SeAssignPrimaryTokenPrivilege -Add-Privilege -Account $sshdAccount -Privilege SeServiceLogonRight +sc.exe config sshd obj= "NT AUTHORITY\NetworkService" +sc.exe sidtype sshd unrestricted if(-not (test-path $logsdir -PathType Container)) { diff --git a/contrib/win32/win32compat/ssh-agent/agent-main.c b/contrib/win32/win32compat/ssh-agent/agent-main.c index e7634bfa8..e962aebd6 100644 --- a/contrib/win32/win32compat/ssh-agent/agent-main.c +++ b/contrib/win32/win32compat/ssh-agent/agent-main.c @@ -1,6 +1,7 @@ /* * Author: Manoj Ampalam * ssh-agent implementation on Windows + * NT Service routines * * Copyright (c) 2015 Microsoft Corp. * All rights reserved @@ -43,7 +44,8 @@ static SERVICE_STATUS_HANDLE service_status_handle; static SERVICE_STATUS service_status; -static VOID ReportSvcStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) +static VOID +ReportSvcStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) { service_status.dwCurrentState = dwCurrentState; service_status.dwWin32ExitCode = dwWin32ExitCode; @@ -62,7 +64,8 @@ static VOID ReportSvcStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD d SetServiceStatus(service_status_handle, &service_status); } -static VOID WINAPI service_handler(DWORD dwControl) +static VOID WINAPI +service_handler(DWORD dwControl) { switch (dwControl) { @@ -81,22 +84,27 @@ static VOID WINAPI service_handler(DWORD dwControl) ReportSvcStatus(service_status.dwCurrentState, NO_ERROR, 0); } -BOOL WINAPI ctrl_c_handler( - _In_ DWORD dwCtrlType -) { +BOOL WINAPI +ctrl_c_handler(_In_ DWORD dwCtrlType) +{ /* for any Ctrl type, shutdown agent*/ debug("Ctrl+C received"); agent_shutdown(); return TRUE; } -int wmain(int argc, wchar_t **argv) { - +int +wmain(int argc, wchar_t **argv) +{ w32posix_initialize(); + /* this exits() on failure*/ load_config(); if (!StartServiceCtrlDispatcherW(dispatch_table)) { if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { - + /* + * agent is not spawned by SCM + * Its either started in debug mode or a worker child + */ if (argc == 2) { if (wcsncmp(argv[1], L"-ddd", 4) == 0) log_init("ssh-agent", 7, 1, 1); @@ -105,9 +113,10 @@ int wmain(int argc, wchar_t **argv) { else if (wcsncmp(argv[1], L"-d", 2) == 0) log_init("ssh-agent", 5, 1, 1); + /* Set Ctrl+C handler if starting in debug mode */ if (wcsncmp(argv[1], L"-d", 2) == 0) { SetConsoleCtrlHandler(ctrl_c_handler, TRUE); - agent_start(TRUE, FALSE, 0); + agent_start(TRUE); return 0; } @@ -116,7 +125,7 @@ int wmain(int argc, wchar_t **argv) { h += _wtoi(*(argv + 1)); if (h != 0) { log_init("ssh-agent", config_log_level(), 1, 0); - agent_start(FALSE, TRUE, h); + agent_process_connection(h); return 0; } } @@ -146,14 +155,16 @@ int wmain(int argc, wchar_t **argv) { return 0; } -int scm_start_service(DWORD num, LPWSTR* args) { +int +scm_start_service(DWORD num, LPWSTR* args) +{ service_status_handle = RegisterServiceCtrlHandlerW(L"ssh-agent", service_handler); 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); log_init("ssh-agent", config_log_level(), 1, 0); - agent_start(FALSE, FALSE, 0); + agent_start(FALSE); return 0; } diff --git a/contrib/win32/win32compat/ssh-agent/agent.c b/contrib/win32/win32compat/ssh-agent/agent.c index b97227a76..beeb3c0d3 100644 --- a/contrib/win32/win32compat/ssh-agent/agent.c +++ b/contrib/win32/win32compat/ssh-agent/agent.c @@ -44,40 +44,21 @@ static OVERLAPPED ol; static HANDLE pipe; static SECURITY_ATTRIBUTES sa; -static int -init_listener() { - { - if ((ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) { - debug("cannot create event ERROR:%d", GetLastError()); - return GetLastError(); - } - pipe = INVALID_HANDLE_VALUE; - sa.bInheritHandle = FALSE; - if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(L"D:P(A;; GA;;; AU)", SDDL_REVISION_1, - &sa.lpSecurityDescriptor, &sa.nLength)) { - debug("cannot convert sddl ERROR:%d", GetLastError()); - return GetLastError(); - } - } - - return 0; -} - static void -agent_cleanup() { - { - if (ol.hEvent != NULL) - CloseHandle(ol.hEvent); - if (pipe != INVALID_HANDLE_VALUE) - CloseHandle(pipe); - } +agent_cleanup() +{ + if (ol.hEvent != NULL) + CloseHandle(ol.hEvent); + if (pipe != INVALID_HANDLE_VALUE) + CloseHandle(pipe); if (ioc_port) CloseHandle(ioc_port); return; } static DWORD WINAPI -iocp_work(LPVOID lpParam) { +iocp_work(LPVOID lpParam) +{ DWORD bytes; struct agent_connection* con = NULL; OVERLAPPED *p_ol; @@ -85,7 +66,7 @@ iocp_work(LPVOID lpParam) { con = NULL; p_ol = NULL; if (GetQueuedCompletionStatus(ioc_port, &bytes, &(ULONG_PTR)con, &p_ol, INFINITE) == FALSE) { - debug("iocp error: %d on %p \n", GetLastError(), con); + debug("iocp error: %d on %p", GetLastError(), con); if (con) agent_connection_on_error(con, GetLastError()); else @@ -93,80 +74,56 @@ iocp_work(LPVOID lpParam) { } else agent_connection_on_io(con, bytes, p_ol); - } } -static void -process_connection(HANDLE pipe) { - struct agent_connection* con; - - if ((con = malloc(sizeof(struct agent_connection))) == NULL) - fatal("failed to alloc"); - - memset(con, 0, sizeof(struct agent_connection)); - con->connection = pipe; - if (CreateIoCompletionPort(pipe, ioc_port, (ULONG_PTR)con, 0) != ioc_port) - fatal("failed to assign pipe to ioc_port"); - - agent_connection_on_io(con, 0, &con->ol); - iocp_work(NULL); -} - static void -agent_listen_loop() { +agent_listen_loop() +{ DWORD r; HANDLE wait_events[2]; wait_events[0] = event_stop_agent; - wait_events[1] = ol.hEvent; while (1) { - { - { - pipe = CreateNamedPipeW( - AGENT_PIPE_ID, // pipe name - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // read/write access - PIPE_TYPE_BYTE | // message type pipe - PIPE_READMODE_BYTE | // message-read mode - PIPE_WAIT, // blocking mode - PIPE_UNLIMITED_INSTANCES, // max. instances - BUFSIZE, // output buffer size - BUFSIZE, // input buffer size - 0, // client time-out - &sa); + pipe = CreateNamedPipeW( + AGENT_PIPE_ID, // pipe name + PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // read/write access + PIPE_TYPE_BYTE | // message type pipe + PIPE_READMODE_BYTE | // message-read mode + PIPE_WAIT, // blocking mode + PIPE_UNLIMITED_INSTANCES, // max. instances + BUFSIZE, // output buffer size + BUFSIZE, // input buffer size + 0, // client time-out + &sa); - if (pipe == INVALID_HANDLE_VALUE) { - verbose("cannot create listener pipe ERROR:%d", GetLastError()); - SetEvent(event_stop_agent); - } - else if (ConnectNamedPipe(pipe, &ol) != FALSE) { - verbose("ConnectNamedPipe returned TRUE unexpectedly "); - SetEvent(event_stop_agent); - } + if (pipe == INVALID_HANDLE_VALUE) { + verbose("cannot create listener pipe ERROR:%d", GetLastError()); + SetEvent(event_stop_agent); + } else if (ConnectNamedPipe(pipe, &ol) != FALSE) { + verbose("ConnectNamedPipe returned TRUE unexpectedly "); + SetEvent(event_stop_agent); + } - if (GetLastError() == ERROR_PIPE_CONNECTED) { - debug("Client has already connected"); - SetEvent(ol.hEvent); - } + if (GetLastError() == ERROR_PIPE_CONNECTED) { + debug("Client has already connected"); + SetEvent(ol.hEvent); + } - if (GetLastError() != ERROR_IO_PENDING) { - debug("ConnectNamedPipe failed ERROR: %d", GetLastError()); - SetEvent(event_stop_agent); - } - - } + if (GetLastError() != ERROR_IO_PENDING) { + debug("ConnectNamedPipe failed ERROR: %d", GetLastError()); + SetEvent(event_stop_agent); } r = WaitForMultipleObjects(2, wait_events, FALSE, INFINITE); if (r == WAIT_OBJECT_0) { - //received signal to shutdown + /*received signal to shutdown*/ debug("shutting down"); agent_cleanup(); return; - } - else if ((r > WAIT_OBJECT_0) && (r <= (WAIT_OBJECT_0 + 1))) { + } else if ((r > WAIT_OBJECT_0) && (r <= (WAIT_OBJECT_0 + 1))) { /* process incoming connection */ HANDLE con = pipe; DWORD client_pid = 0; @@ -174,11 +131,10 @@ agent_listen_loop() { GetNamedPipeClientProcessId(con, &client_pid); verbose("client pid %d connected", client_pid); if (debug_mode) { - process_connection(con); + agent_process_connection(con); agent_cleanup(); return; - } - else { + } else { /* spawn a child to take care of this*/ wchar_t path[PATH_MAX], module_path[PATH_MAX]; PROCESS_INFORMATION pi; @@ -193,8 +149,7 @@ agent_listen_loop() { DETACHED_PROCESS, NULL, NULL, &si, &pi) == FALSE)) { verbose("Failed to create child process %ls ERROR:%d", module_path, GetLastError()); - } - else { + } else { debug("spawned worker %d for agent client pid %d ", pi.dwProcessId, client_pid); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); @@ -203,17 +158,18 @@ agent_listen_loop() { CloseHandle(con); } - } - else { + } else { fatal("wait on events ended with %d ERROR:%d", r, GetLastError()); } } } -void agent_cleanup_connection(struct agent_connection* con) { +void +agent_cleanup_connection(struct agent_connection* con) +{ debug("connection %p clean up", con); - CloseHandle(con->connection); + CloseHandle(con->pipe_handle); if (con->hProfile) UnloadUserProfile(con->auth_token, con->hProfile); if (con->auth_token) @@ -223,45 +179,59 @@ void agent_cleanup_connection(struct agent_connection* con) { ioc_port = NULL; } -void agent_shutdown() { - verbose("shutdown"); +void +agent_shutdown() +{ SetEvent(event_stop_agent); } -#define REG_AGENT_SDDL L"D:P(A;; GR;;; AU)(A;; GA;;; SY)(A;; GA;;; BA)" - void -agent_start(BOOL dbg_mode, BOOL child, HANDLE pipe) { +agent_start(BOOL dbg_mode) +{ int r; HKEY agent_root = NULL; DWORD process_id = GetCurrentProcessId(); - - verbose("agent_start pid:%d, dbg:%d, child:%d, pipe:%d", process_id, dbg_mode, child, pipe); + + verbose("%s pid:%d, dbg:%d", __FUNCTION__, process_id, dbg_mode); debug_mode = dbg_mode; + memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); + sa.nLength = sizeof(sa); + /* allow access to Authenticated users and Network Service */ + if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(L"D:P(A;;GA;;;AU)(A;;GA;;;NS)", SDDL_REVISION_1, + &sa.lpSecurityDescriptor, &sa.nLength)) + fatal("cannot convert sddl ERROR:%d", GetLastError()); + if ((r = RegCreateKeyExW(HKEY_LOCAL_MACHINE, SSH_AGENT_ROOT, 0, 0, 0, KEY_WRITE, &sa, &agent_root, 0)) != ERROR_SUCCESS) + fatal("cannot create agent root reg key, ERROR:%d", r); + if ((r = RegSetValueExW(agent_root, L"ProcessID", 0, REG_DWORD, (BYTE*)&process_id, 4)) != ERROR_SUCCESS) + fatal("cannot publish agent master process id ERROR:%d", r); + if ((event_stop_agent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) + fatal("cannot create global stop event ERROR:%d", GetLastError()); + if ((ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) + fatal("cannot create event ERROR:%d", GetLastError()); + pipe = INVALID_HANDLE_VALUE; + sa.bInheritHandle = FALSE; + agent_listen_loop(); +} + +void +agent_process_connection(HANDLE pipe) +{ + struct agent_connection* con; + verbose("%s pipe:%p", __FUNCTION__, pipe); + if ((ioc_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, (ULONG_PTR)NULL, 0)) == NULL) fatal("cannot create ioc port ERROR:%d", GetLastError()); + if ((con = malloc(sizeof(struct agent_connection))) == NULL) + fatal("failed to alloc"); - if (child == FALSE) { - SECURITY_ATTRIBUTES sa; - memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); - sa.nLength = sizeof(sa); - if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(REG_AGENT_SDDL, SDDL_REVISION_1, &sa.lpSecurityDescriptor, &sa.nLength)) - fatal("ConvertStringSecurityDescriptorToSecurityDescriptorW failed"); - if ((r = RegCreateKeyExW(HKEY_LOCAL_MACHINE, SSH_AGENT_ROOT, 0, 0, 0, KEY_WRITE, &sa, &agent_root, 0)) != ERROR_SUCCESS) - fatal("cannot create agent root reg key, ERROR:%d", r); - if ((r = RegSetValueExW(agent_root, L"ProcessID", 0, REG_DWORD, (BYTE*)&process_id, 4)) != ERROR_SUCCESS) - fatal("cannot publish agent master process id ERROR:%d", r); - if ((event_stop_agent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) - fatal("cannot create global stop event ERROR:%d", GetLastError()); - if ((r = init_listener()) != 0) - fatal("failed to create server pipes ERROR:%d", r); - agent_listen_loop(); - } - else { /* this is a child process that processes one connection */ - process_connection(pipe); - } - + memset(con, 0, sizeof(struct agent_connection)); + con->pipe_handle = pipe; + if (CreateIoCompletionPort(pipe, ioc_port, (ULONG_PTR)con, 0) != ioc_port) + fatal("failed to assign pipe to ioc_port"); + + agent_connection_on_io(con, 0, &con->ol); + iocp_work(NULL); } diff --git a/contrib/win32/win32compat/ssh-agent/agent.h b/contrib/win32/win32compat/ssh-agent/agent.h index e919cfc4a..d6aaaa825 100644 --- a/contrib/win32/win32compat/ssh-agent/agent.h +++ b/contrib/win32/win32compat/ssh-agent/agent.h @@ -11,7 +11,7 @@ struct agent_connection { OVERLAPPED ol; - HANDLE connection; + HANDLE pipe_handle; struct { DWORD num_bytes; DWORD transferred; @@ -27,11 +27,9 @@ struct agent_connection { } state; enum { UNKNOWN = 0, - OTHER, - LOCAL_SYSTEM, - SSHD, - NETWORK_SERVICE - } client_process; + USER, /* client is running as some user */ + MACHINE /* clinet is running as machine - System, NS or LS */ + } client_type; HANDLE auth_token; HANDLE hProfile; }; @@ -40,7 +38,8 @@ void agent_connection_on_io(struct agent_connection*, DWORD, OVERLAPPED*); void agent_connection_on_error(struct agent_connection* , DWORD); void agent_connection_disconnect(struct agent_connection*); -void agent_start(BOOL, BOOL, HANDLE); +void agent_start(BOOL); +void agent_process_connection(HANDLE); void agent_shutdown(); void agent_cleanup_connection(struct agent_connection*); diff --git a/contrib/win32/win32compat/ssh-agent/agentconfig.c b/contrib/win32/win32compat/ssh-agent/agentconfig.c index 155fd2c01..c3db1f8cd 100644 --- a/contrib/win32/win32compat/ssh-agent/agentconfig.c +++ b/contrib/win32/win32compat/ssh-agent/agentconfig.c @@ -96,7 +96,6 @@ int load_config() { wchar_t basePath[PATH_MAX] = { 0 }; wchar_t path[PATH_MAX] = { 0 }; - /* TODO - account for UNICODE paths*/ if (GetCurrentModulePath(basePath, PATH_MAX) == -1) return -1; diff --git a/contrib/win32/win32compat/ssh-agent/authagent-request.c b/contrib/win32/win32compat/ssh-agent/authagent-request.c index 291f332fa..af7ba68d1 100644 --- a/contrib/win32/win32compat/ssh-agent/authagent-request.c +++ b/contrib/win32/win32compat/ssh-agent/authagent-request.c @@ -243,7 +243,7 @@ int process_passwordauth_request(struct sshbuf* request, struct sshbuf* response goto done; } - if ((FALSE == GetNamedPipeClientProcessId(con->connection, &client_pid)) || + if ((FALSE == GetNamedPipeClientProcessId(con->pipe_handle, &client_pid)) || ((client_proc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, client_pid)) == NULL) || (FALSE == DuplicateHandle(GetCurrentProcess(), token, client_proc, &dup_token, TOKEN_QUERY | TOKEN_IMPERSONATE, FALSE, DUPLICATE_SAME_ACCESS)) || (sshbuf_put_u32(response, (int)(intptr_t)dup_token) != 0)) { @@ -317,7 +317,7 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response, goto done; } - if ((FALSE == GetNamedPipeClientProcessId(con->connection, &client_pid)) || + if ((FALSE == GetNamedPipeClientProcessId(con->pipe_handle, &client_pid)) || ( (client_proc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, client_pid)) == NULL) || (FALSE == DuplicateHandle(GetCurrentProcess(), token, client_proc, &dup_token, TOKEN_QUERY | TOKEN_IMPERSONATE, FALSE, DUPLICATE_SAME_ACCESS)) || (sshbuf_put_u32(response, (int)(intptr_t)dup_token) != 0)) { diff --git a/contrib/win32/win32compat/ssh-agent/connection.c b/contrib/win32/win32compat/ssh-agent/connection.c index d95973236..77233eed4 100644 --- a/contrib/win32/win32compat/ssh-agent/connection.c +++ b/contrib/win32/win32compat/ssh-agent/connection.c @@ -39,104 +39,101 @@ int process_request(struct agent_connection*); return; \ } while (0) -void agent_connection_on_error(struct agent_connection* con, DWORD error) { +void +agent_connection_on_error(struct agent_connection* con, DWORD error) +{ ABORT_CONNECTION_RETURN(con); } -void agent_connection_on_io(struct agent_connection* con, DWORD bytes, OVERLAPPED* ol) { - +void +agent_connection_on_io(struct agent_connection* con, DWORD bytes, OVERLAPPED* ol) +{ /* process error */ debug3("connection io %p #bytes:%d state:%d", con, bytes, con->state); - if ((bytes == 0) && (GetOverlappedResult(con->connection, ol, &bytes, FALSE) == FALSE)) + if ((bytes == 0) && (GetOverlappedResult(con->pipe_handle, ol, &bytes, FALSE) == FALSE)) ABORT_CONNECTION_RETURN(con); - if (con->state == DONE) DebugBreak(); - { - switch (con->state) { - case LISTENING: - case WRITING: - /* Writing is done, read next request */ - /* assert on assumption that write always completes on sending all bytes*/ - if (bytes != con->io_buf.num_bytes) - DebugBreak(); - con->state = READING_HEADER; - ZeroMemory(&con->io_buf, sizeof(con->io_buf)); - if (!ReadFile(con->connection, con->io_buf.buf, - HEADER_SIZE, NULL, &con->ol) && (GetLastError() != ERROR_IO_PENDING)) - ABORT_CONNECTION_RETURN(con); - break; - case READING_HEADER: - con->io_buf.transferred += bytes; - if (con->io_buf.transferred == HEADER_SIZE) { - con->io_buf.num_bytes = PEEK_U32(con->io_buf.buf); - con->io_buf.transferred = 0; - if (con->io_buf.num_bytes > MAX_MESSAGE_SIZE) - ABORT_CONNECTION_RETURN(con); - - con->state = READING; - if (!ReadFile(con->connection, con->io_buf.buf, - con->io_buf.num_bytes, NULL, &con->ol)&&(GetLastError() != ERROR_IO_PENDING)) - ABORT_CONNECTION_RETURN(con); - } - else { - if (!ReadFile(con->connection, con->io_buf.buf + con->io_buf.num_bytes, - HEADER_SIZE - con->io_buf.num_bytes, NULL, &con->ol)&& (GetLastError() != ERROR_IO_PENDING)) - ABORT_CONNECTION_RETURN(con); - } - break; - case READING: - con->io_buf.transferred += bytes; - if (con->io_buf.transferred == con->io_buf.num_bytes) { - if (process_request(con) != 0) { - ABORT_CONNECTION_RETURN(con); - } - con->state = WRITING; - if (!WriteFile(con->connection, con->io_buf.buf, - con->io_buf.num_bytes, NULL, &con->ol)&& (GetLastError() != ERROR_IO_PENDING) ) - ABORT_CONNECTION_RETURN(con); - } - else { - if (!ReadFile(con->connection, con->io_buf.buf + con->io_buf.transferred, - con->io_buf.num_bytes - con->io_buf.transferred, NULL, &con->ol)&& (GetLastError() != ERROR_IO_PENDING)) - ABORT_CONNECTION_RETURN(con); - } - break; - default: + switch (con->state) { + case LISTENING: + case WRITING: + /* Writing is done, read next request */ + /* assert on assumption that write always completes on sending all bytes*/ + if (bytes != con->io_buf.num_bytes) DebugBreak(); - } - } + con->state = READING_HEADER; + ZeroMemory(&con->io_buf, sizeof(con->io_buf)); + if (!ReadFile(con->pipe_handle, con->io_buf.buf, + HEADER_SIZE, NULL, &con->ol) && (GetLastError() != ERROR_IO_PENDING)) + ABORT_CONNECTION_RETURN(con); + break; + case READING_HEADER: + con->io_buf.transferred += bytes; + if (con->io_buf.transferred == HEADER_SIZE) { + con->io_buf.num_bytes = PEEK_U32(con->io_buf.buf); + con->io_buf.transferred = 0; + if (con->io_buf.num_bytes > MAX_MESSAGE_SIZE) + ABORT_CONNECTION_RETURN(con); + + con->state = READING; + if (!ReadFile(con->pipe_handle, con->io_buf.buf, + con->io_buf.num_bytes, NULL, &con->ol)&&(GetLastError() != ERROR_IO_PENDING)) + ABORT_CONNECTION_RETURN(con); + } else { + if (!ReadFile(con->pipe_handle, con->io_buf.buf + con->io_buf.num_bytes, + HEADER_SIZE - con->io_buf.num_bytes, NULL, &con->ol)&& (GetLastError() != ERROR_IO_PENDING)) + ABORT_CONNECTION_RETURN(con); + } + break; + case READING: + con->io_buf.transferred += bytes; + if (con->io_buf.transferred == con->io_buf.num_bytes) { + if (process_request(con) != 0) { + ABORT_CONNECTION_RETURN(con); + } + con->state = WRITING; + if (!WriteFile(con->pipe_handle, con->io_buf.buf, + con->io_buf.num_bytes, NULL, &con->ol)&& (GetLastError() != ERROR_IO_PENDING) ) + ABORT_CONNECTION_RETURN(con); + } else { + if (!ReadFile(con->pipe_handle, con->io_buf.buf + con->io_buf.transferred, + con->io_buf.num_bytes - con->io_buf.transferred, NULL, &con->ol)&& (GetLastError() != ERROR_IO_PENDING)) + ABORT_CONNECTION_RETURN(con); + } + break; + default: + DebugBreak(); + } } -void agent_connection_disconnect(struct agent_connection* con) { - CancelIoEx(con->connection, NULL); - DisconnectNamedPipe(con->connection); +void +agent_connection_disconnect(struct agent_connection* con) +{ + CancelIoEx(con->pipe_handle, NULL); + DisconnectNamedPipe(con->pipe_handle); } static int -get_con_client_type(HANDLE pipe) { +get_con_client_type(struct agent_connection* con) +{ int r = -1; - wchar_t *sshd_act = L"NT SERVICE\\SSHD", *ref_dom = NULL; - PSID sshd_sid = NULL; char system_sid[SECURITY_MAX_SID_SIZE]; char ns_sid[SECURITY_MAX_SID_SIZE]; - DWORD sshd_sid_len = 0, reg_dom_len = 0, info_len = 0, sid_size; + char ls_sid[SECURITY_MAX_SID_SIZE]; + DWORD reg_dom_len = 0, info_len = 0, sid_size; SID_NAME_USE nuse; HANDLE token; TOKEN_USER* info = NULL; + HANDLE pipe = con->pipe_handle; if (ImpersonateNamedPipeClient(pipe) == FALSE) return -1; - if (LookupAccountNameW(NULL, sshd_act, NULL, &sshd_sid_len, NULL, ®_dom_len, &nuse) == TRUE || - (sshd_sid = malloc(sshd_sid_len)) == NULL || - (ref_dom = (wchar_t*)malloc(reg_dom_len * 2)) == NULL || - LookupAccountNameW(NULL, sshd_act, sshd_sid, &sshd_sid_len, ref_dom, ®_dom_len, &nuse) == FALSE || - OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &token) == FALSE || - GetTokenInformation(token, TokenUser, NULL, 0, &info_len) == TRUE || - (info = (TOKEN_USER*)malloc(info_len)) == NULL || - GetTokenInformation(token, TokenUser, info, info_len, &info_len) == FALSE) + if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &token) == FALSE || + GetTokenInformation(token, TokenUser, NULL, 0, &info_len) == TRUE || + (info = (TOKEN_USER*)malloc(info_len)) == NULL || + GetTokenInformation(token, TokenUser, info, info_len, &info_len) == FALSE) goto done; sid_size = SECURITY_MAX_SID_SIZE; @@ -145,22 +142,20 @@ get_con_client_type(HANDLE pipe) { sid_size = SECURITY_MAX_SID_SIZE; if (CreateWellKnownSid(WinNetworkServiceSid, NULL, ns_sid, &sid_size) == FALSE) goto done; + sid_size = SECURITY_MAX_SID_SIZE; + if (CreateWellKnownSid(WinLocalServiceSid, NULL, ls_sid, &sid_size) == FALSE) + goto done; - if (EqualSid(info->User.Sid, system_sid)) - r = LOCAL_SYSTEM; - else if (EqualSid(info->User.Sid, sshd_sid)) - r = SSHD; - else if (EqualSid(info->User.Sid, ns_sid)) - r = NETWORK_SERVICE; + if (EqualSid(info->User.Sid, system_sid) || + EqualSid(info->User.Sid, ls_sid) || + EqualSid(info->User.Sid, ns_sid)) + con->client_type = MACHINE; else - r = OTHER; + con->client_type = USER; - debug2("client type: %d", r); + debug2("client type: %s", con->client_type == MACHINE? "machine" : "user"); + r = 0; done: - if (sshd_sid) - free(sshd_sid); - if (ref_dom) - free(ref_dom); if (info) free(info); RevertToSelf(); @@ -168,51 +163,49 @@ done: } static int -process_request(struct agent_connection* con) { +process_request(struct agent_connection* con) +{ int r = -1; struct sshbuf *request = NULL, *response = NULL; + u_char type; - if (con->client_process == UNKNOWN) - if ((con->client_process = get_con_client_type(con->connection)) == -1) - goto done; + if (con->client_type == UNKNOWN && get_con_client_type(con) == -1) { + debug("unable to get client process type"); + goto done; + } - //Sleep(30 * 1000); request = sshbuf_from(con->io_buf.buf, con->io_buf.num_bytes); response = sshbuf_new(); if ((request == NULL) || (response == NULL)) goto done; - { - u_char type; + if (sshbuf_get_u8(request, &type) != 0) + return -1; + debug("process agent request type %d", type); - if (sshbuf_get_u8(request, &type) != 0) - return -1; - debug("process agent request type %d", type); - - switch (type) { - case SSH2_AGENTC_ADD_IDENTITY: - r = process_add_identity(request, response, con); - break; - case SSH2_AGENTC_REQUEST_IDENTITIES: - r = process_request_identities(request, response, con); - break; - case SSH2_AGENTC_SIGN_REQUEST: - r = process_sign_request(request, response, con); - break; - case SSH2_AGENTC_REMOVE_IDENTITY: - r = process_remove_key(request, response, con); - break; - case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: - r = process_remove_all(request, response, con); - break; - case SSH_AGENT_AUTHENTICATE: - r = process_authagent_request(request, response, con); - break; - default: - debug("unknown agent request %d", type); - r = -1; - break; - } + switch (type) { + case SSH2_AGENTC_ADD_IDENTITY: + r = process_add_identity(request, response, con); + break; + case SSH2_AGENTC_REQUEST_IDENTITIES: + r = process_request_identities(request, response, con); + break; + case SSH2_AGENTC_SIGN_REQUEST: + r = process_sign_request(request, response, con); + break; + case SSH2_AGENTC_REMOVE_IDENTITY: + r = process_remove_key(request, response, con); + break; + case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: + r = process_remove_all(request, response, con); + break; + case SSH_AGENT_AUTHENTICATE: + r = process_authagent_request(request, response, con); + break; + default: + debug("unknown agent request %d", type); + r = -1; + break; } done: diff --git a/contrib/win32/win32compat/ssh-agent/keyagent-request.c b/contrib/win32/win32compat/ssh-agent/keyagent-request.c index 08225ac27..4c253e7c4 100644 --- a/contrib/win32/win32compat/ssh-agent/keyagent-request.c +++ b/contrib/win32/win32compat/ssh-agent/keyagent-request.c @@ -36,21 +36,33 @@ #define MAX_KEY_LENGTH 255 #define MAX_VALUE_NAME 16383 +/* + * get registry root where keys are stored + * user keys are stored in user's hive + * while system keys (host keys) in HKLM + */ static int -get_user_root(struct agent_connection* con, HKEY *root){ +get_user_root(struct agent_connection* con, HKEY *root) +{ int r = 0; - *root = NULL; - if (ImpersonateNamedPipeClient(con->connection) == FALSE) - return -1; + LONG ret; + *root = HKEY_LOCAL_MACHINE; - if (con->client_process > OTHER) - *root = HKEY_LOCAL_MACHINE; - else if (RegOpenCurrentUser(KEY_ALL_ACCESS, root) != ERROR_SUCCESS) - r = -1; - - if (*root == NULL) - debug("cannot connect to user's registry root"); - RevertToSelf(); + if (con->client_type == USER) { + if (ImpersonateNamedPipeClient(con->pipe_handle) == FALSE) + return -1; + *root = NULL; + /* + * TODO - check that user profile is loaded, + * otherwise, this will return default profile + */ + if ((ret = RegOpenCurrentUser(KEY_ALL_ACCESS, root)) != ERROR_SUCCESS) { + debug("unable to open user's registry hive, ERROR - %d", ret); + r = -1; + } + + RevertToSelf(); + } return r; } @@ -59,8 +71,8 @@ convert_blob(struct agent_connection* con, const char *blob, DWORD blen, char ** int success = 0; DATA_BLOB in, out; - if (con->client_process == OTHER) - if (ImpersonateNamedPipeClient(con->connection) == FALSE) + if (con->client_type == USER) + if (ImpersonateNamedPipeClient(con->pipe_handle) == FALSE) return -1; in.cbData = blen; @@ -73,8 +85,7 @@ convert_blob(struct agent_connection* con, const char *blob, DWORD blen, char ** debug("cannot encrypt data"); goto done; } - } - else { + } else { if (!CryptUnprotectData(&in, NULL, NULL, 0, NULL, 0, &out)) { debug("cannot decrypt data"); goto done; @@ -91,7 +102,7 @@ convert_blob(struct agent_connection* con, const char *blob, DWORD blen, char ** done: if (out.pbData) LocalFree(out.pbData); - if (con->client_process == OTHER) + if (con->client_type == USER) RevertToSelf(); return success? 0: -1; } @@ -99,7 +110,8 @@ done: #define REG_KEY_SDDL L"D:P(A;; GA;;; SY)(A;; GA;;; BA)" int -process_add_identity(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) { +process_add_identity(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) +{ struct sshkey* key = NULL; int r = 0, blob_len, eblob_len, request_invalid = 0, success = 0; size_t comment_len, pubkey_blob_len; @@ -170,7 +182,8 @@ done: } static int sign_blob(const struct sshkey *pubkey, u_char ** sig, size_t *siglen, - const u_char *blob, size_t blen, u_int flags, struct agent_connection* con) { + const u_char *blob, size_t blen, u_int flags, struct agent_connection* con) +{ HKEY reg = 0, sub = 0, user_root = 0; int r = 0, success = 0; struct sshkey* prikey = NULL; @@ -225,7 +238,8 @@ done: } int -process_sign_request(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) { +process_sign_request(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) +{ u_char *blob, *data, *signature = NULL; size_t blen, dlen, slen = 0; u_int flags = 0; @@ -257,8 +271,7 @@ done: sshbuf_put_string(response, signature, slen) != 0) { r = -1; } - } - else + } else if (sshbuf_put_u8(response, SSH_AGENT_FAILURE) != 0) r = -1; } @@ -271,7 +284,8 @@ done: } int -process_remove_key(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) { +process_remove_key(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) +{ HKEY user_root = 0, root = 0; char *blob, *thumbprint = NULL; size_t blen; @@ -285,10 +299,10 @@ process_remove_key(struct sshbuf* request, struct sshbuf* response, struct agent } if ((thumbprint = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT, SSH_FP_DEFAULT)) == NULL || - get_user_root(con, &user_root) != 0 || - RegOpenKeyExW(user_root, SSH_KEYS_ROOT, 0, - DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE | KEY_WOW64_64KEY, &root) != 0 || - RegDeleteTreeA(root, thumbprint) != 0) + get_user_root(con, &user_root) != 0 || + RegOpenKeyExW(user_root, SSH_KEYS_ROOT, 0, + DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE | KEY_WOW64_64KEY, &root) != 0 || + RegDeleteTreeA(root, thumbprint) != 0) goto done; success = 1; done: @@ -309,7 +323,8 @@ done: return r; } int -process_remove_all(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) { +process_remove_all(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) +{ HKEY user_root = 0, root = 0; int r = 0; @@ -333,7 +348,8 @@ done: } int -process_request_identities(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) { +process_request_identities(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) +{ int count = 0, index = 0, success = 0, r = 0; HKEY root = NULL, sub = NULL, user_root = 0; char* count_ptr = NULL; @@ -379,8 +395,7 @@ process_request_identities(struct sshbuf* request, struct sshbuf* response, stru key_count++; } - } - else + } else break; } @@ -393,8 +408,7 @@ done: sshbuf_put_u32(response, key_count) != 0 || sshbuf_putb(response, identities) != 0) goto done; - } - else + } else r = -1; if (pkblob) @@ -413,7 +427,8 @@ done: } -int process_keyagent_request(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) { +int process_keyagent_request(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) +{ u_char type; if (sshbuf_get_u8(request, &type) != 0)