diff --git a/contrib/win32/openssh/Win32-OpenSSh-design.pptx b/contrib/win32/openssh/Win32-OpenSSh-design.pptx
new file mode 100644
index 000000000..4c95fb823
Binary files /dev/null and b/contrib/win32/openssh/Win32-OpenSSh-design.pptx differ
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 <manoj.ampalam@microsoft.com>
  * 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, &reg_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, &reg_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)