From 70784d560648368b3092157c7c302560c8ae7a24 Mon Sep 17 00:00:00 2001
From: bagajjal <bagajjal@microsoft.com>
Date: Thu, 2 Feb 2017 23:54:02 -0800
Subject: [PATCH] Fixed Denyusers issue when logging in with ssh
 username@domain@serverip
 (https://github.com/PowerShell/Win32-OpenSSH/issues/511)

---
 auth-passwd.c                                 |  14 +-
 auth2-pubkey.c                                |  10 +-
 authfd.h                                      |   8 +
 contrib/win32/win32compat/inc/pwd.h           |   5 +-
 contrib/win32/win32compat/pwd.c               | 320 +++++-----
 .../win32compat/ssh-agent/authagent-request.c | 545 ++++++++----------
 .../win32/win32compat/ssh-agent/connection.c  |   5 +-
 misc.c                                        |   7 +
 8 files changed, 454 insertions(+), 460 deletions(-)

diff --git a/auth-passwd.c b/auth-passwd.c
index 3b81c2d68..d95f1184a 100644
--- a/auth-passwd.c
+++ b/auth-passwd.c
@@ -54,6 +54,7 @@
 #include "hostfile.h"
 #include "auth.h"
 #include "auth-options.h"
+#include "authfd.h"
 
 extern Buffer loginmsg;
 extern ServerOptions options;
@@ -225,7 +226,7 @@ sys_auth_passwd(Authctxt *authctxt, const char *password)
 
 #elif defined(WINDOWS)
 /*
-* Authenticate on Windows - Pass creds to ssh-agent and retrieve token
+* Authenticate on Windows - Pass credentials to ssh-agent and retrieve token
 * upon succesful authentication
 */
 extern int auth_sock;
@@ -239,17 +240,18 @@ int sys_auth_passwd(Authctxt *authctxt, const char *password)
 	msg = sshbuf_new();
 	if (!msg)
 		return 0;
-	if (sshbuf_put_u8(msg, 100) != 0 ||
-		sshbuf_put_cstring(msg, "password") != 0 ||
-		sshbuf_put_cstring(msg, authctxt->user) != 0 ||
+
+	if (sshbuf_put_u8(msg, SSH_AGENT_AUTHENTICATE) != 0 ||
+		sshbuf_put_cstring(msg, PASSWD_AUTH_REQUEST) != 0 ||
+		sshbuf_put_cstring(msg, authctxt->pw->pw_name) != 0 ||
+		sshbuf_put_cstring(msg, authctxt->pw->pw_domain) != 0 ||
 		sshbuf_put_cstring(msg, password) != 0 ||
 		ssh_request_reply(auth_sock, msg, msg) != 0 ||
 		sshbuf_get_u32(msg, &token) != 0) {
-		debug("auth agent did not authorize client %s", authctxt->pw->pw_name);
+		debug("auth agent did not authorize client %s", authctxt->user);
 		return 0;
 	}
 
-
 	if (blob)
 		free(blob);
 	if (msg)
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index a5a5c273e..d338896eb 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -68,6 +68,7 @@
 #include "ssherr.h"
 #include "channels.h" /* XXX for session.h */
 #include "session.h" /* XXX for child_set_env(); refactor? */
+#include "authfd.h"
 
 /* import */
 extern ServerOptions options;
@@ -190,20 +191,21 @@ userauth_pubkey(Authctxt *authctxt)
 				msg = sshbuf_new();
 				if (!msg)
 					break;
-				if ((r = sshbuf_put_u8(msg, 100)) != 0 ||
-					(r = sshbuf_put_cstring(msg, "pubkey")) != 0 ||
+				if ((r = sshbuf_put_u8(msg, SSH_AGENT_AUTHENTICATE)) != 0 ||
+					(r = sshbuf_put_cstring(msg, PUBKEY_AUTH_REQUEST)) != 0 ||
 					(r = sshkey_to_blob(key, &blob, &blen)) != 0 ||
 					(r = sshbuf_put_string(msg, blob, blen)) != 0 ||
 					(r = sshbuf_put_cstring(msg, authctxt->pw->pw_name)) != 0 ||
+					(r = sshbuf_put_cstring(msg, authctxt->pw->pw_domain)) != 0 ||
 					(r = sshbuf_put_string(msg, sig, slen)) != 0 ||
 					(r = sshbuf_put_string(msg, buffer_ptr(&b), buffer_len(&b))) != 0 ||
 					(r = ssh_request_reply(auth_sock, msg, msg)) != 0 ||
 					(r = sshbuf_get_u32(msg, &token)) != 0) {
-					debug("auth agent did not authorize client %s", authctxt->pw->pw_name);
+					debug("auth agent did not authorize client %s", authctxt->user);
 					break;
 				}
 
-				debug3("auth agent authenticated %s", authctxt->pw->pw_name);
+				debug3("auth agent authenticated %s", authctxt->user);
 				break;
 				
 			}
diff --git a/authfd.h b/authfd.h
index 4b417e3f4..38cffaf0e 100644
--- a/authfd.h
+++ b/authfd.h
@@ -89,4 +89,12 @@ int	ssh_agent_sign(int sock, struct sshkey *key,
 #define	SSH_AGENT_RSA_SHA2_256			0x02
 #define	SSH_AGENT_RSA_SHA2_512			0x04
 
+/* 
+* Following are used in Windows implementation
+* ssh-agent in Windows also serves user authentication
+*/
+#define SSH_AGENT_AUTHENTICATE			200
+#define PUBKEY_AUTH_REQUEST			"pubkey"
+#define PASSWD_AUTH_REQUEST			"password"
+
 #endif				/* AUTHFD_H */
diff --git a/contrib/win32/win32compat/inc/pwd.h b/contrib/win32/win32compat/inc/pwd.h
index ffb4619e0..45768deaa 100644
--- a/contrib/win32/win32compat/inc/pwd.h
+++ b/contrib/win32/win32compat/inc/pwd.h
@@ -13,8 +13,9 @@
 #include "sys\types.h"
 
 struct passwd {
-        char	*pw_name;	/* user's login name */
-        char	*pw_passwd;	/* password? */
+	char	*pw_name;	/* user's login name */
+	char	*pw_domain;	/* user's domain name */
+	char	*pw_passwd;	/* password? */
 	char	*pw_gecos;	/* ??? */
 	uid_t	pw_uid;		/* numerical user ID */
 	gid_t	pw_gid;		/* numerical group ID */
diff --git a/contrib/win32/win32compat/pwd.c b/contrib/win32/win32compat/pwd.c
index eaaacb71c..56c7bdafd 100644
--- a/contrib/win32/win32compat/pwd.c
+++ b/contrib/win32/win32compat/pwd.c
@@ -47,193 +47,207 @@ static char* pw_shellpath = NULL;
 
 int
 initialize_pw() {
-        if (pw_shellpath == NULL) {
-                if ((pw_shellpath = malloc(strlen(w32_programdir()) + strlen(SHELL_HOST) + 1)) == NULL)
-                        fatal("initialize_pw - out of memory");
-                else {
-                        char* head = pw_shellpath;
-                        memcpy(head, w32_programdir(), strlen(w32_programdir()));
-                        head += strlen(w32_programdir());
-                        memcpy(head, SHELL_HOST, strlen(SHELL_HOST));
-                        head += strlen(SHELL_HOST);
-                        *head = '\0';
-                }
-        }
-        if (pw.pw_shell != pw_shellpath) {
-                memset(&pw, 0, sizeof(pw));
-                pw.pw_shell = pw_shellpath;
-                pw.pw_passwd = "\0";
-                /* pw_uid = 0 for root on Unix and SSH code has specific restrictions for root 
-                 * that are not applicable in Windows */
-                pw.pw_uid = 1;
-        }
-        return 0;
+	if (pw_shellpath == NULL) {
+		if ((pw_shellpath = malloc(strlen(w32_programdir()) + strlen(SHELL_HOST) + 1)) == NULL)
+			fatal("initialize_pw - out of memory");
+		else {
+			char* head = pw_shellpath;
+			memcpy(head, w32_programdir(), strlen(w32_programdir()));
+			head += strlen(w32_programdir());
+			memcpy(head, SHELL_HOST, strlen(SHELL_HOST));
+			head += strlen(SHELL_HOST);
+			*head = '\0';
+		}
+	}
+	if (pw.pw_shell != pw_shellpath) {
+		memset(&pw, 0, sizeof(pw));
+		pw.pw_shell = pw_shellpath;
+		pw.pw_passwd = "\0";
+		/* pw_uid = 0 for root on Unix and SSH code has specific restrictions for root
+		 * that are not applicable in Windows */
+		pw.pw_uid = 1;
+	}
+	return 0;
 }
 
 void
 reset_pw() {
-        initialize_pw();
-        if (pw.pw_name)
-                free(pw.pw_name);
-        if (pw.pw_dir)
-                free(pw.pw_dir);
+	initialize_pw();
+	if (pw.pw_name)
+		free(pw.pw_name);
+	if (pw.pw_dir)
+		free(pw.pw_dir);
 }
 
 static struct passwd*
 get_passwd(const char *user_utf8, LPWSTR user_sid) {
-        struct passwd *ret = NULL;
-        wchar_t *user_utf16 = NULL, *uname_utf16, *udom_utf16, *tmp;
-        char *uname_utf8 = NULL, *pw_home_utf8 = NULL, *user_sid_utf8;
-        LPBYTE user_info = NULL;
-        LPWSTR user_sid_local = NULL;
-        wchar_t reg_path[PATH_MAX], profile_home[PATH_MAX];
-        HKEY reg_key = 0;
-        int tmp_len = PATH_MAX;
-        PDOMAIN_CONTROLLER_INFOW pdc = NULL;
+	struct passwd *ret = NULL;
+	wchar_t *user_utf16 = NULL, *uname_utf16, *udom_utf16, *tmp;
+	char *uname_utf8 = NULL, *udom_utf8 = NULL, *pw_home_utf8 = NULL, *user_sid_utf8 = NULL;
+	LPBYTE user_info = NULL;
+	LPWSTR user_sid_local = NULL;
+	wchar_t reg_path[PATH_MAX], profile_home[PATH_MAX];
+	HKEY reg_key = 0;
+	int tmp_len = PATH_MAX;
+	PDOMAIN_CONTROLLER_INFOW pdc = NULL;
 
-        errno = 0;
+	errno = 0;
 
-        reset_pw();
+	reset_pw();
 
-        if ((user_utf16 = utf8_to_utf16(user_utf8) ) == NULL) {
-                errno = ENOMEM;
-                goto done;
-        }
+	if ((user_utf16 = utf8_to_utf16(user_utf8) ) == NULL) {
+		errno = ENOMEM;
+		goto done;
+	}
 
-        /*find domain part if any*/
-        if ((tmp = wcschr(user_utf16, L'\\')) != NULL) {
-                udom_utf16 = user_utf16;
-                uname_utf16 = tmp + 1;
-                *tmp = L'\0';
+	/*find domain part if any*/
+	if ((tmp = wcschr(user_utf16, L'\\')) != NULL) {
+		udom_utf16 = user_utf16;
+		uname_utf16 = tmp + 1;
+		*tmp = L'\0';
 
-        }
-        else if ((tmp = wcschr(user_utf16, L'@')) != NULL) {
-                udom_utf16 = tmp + 1;
-                uname_utf16 = user_utf16;
-                *tmp = L'\0';
-        }
-        else {
-                uname_utf16 = user_utf16;
-                udom_utf16 = NULL;
-        }
+	} else if ((tmp = wcschr(user_utf16, L'@')) != NULL) {
+		udom_utf16 = tmp + 1;
+		uname_utf16 = user_utf16;
+		*tmp = L'\0';
+	} else {
+		uname_utf16 = user_utf16;
+		udom_utf16 = NULL;
+	}
 
-        if (user_sid == NULL) {
-            NET_API_STATUS status;
-            if ((status = NetUserGetInfo(udom_utf16, uname_utf16, 23, &user_info)) != NERR_Success) {
-                debug("NetUserGetInfo() failed with error: %d \n", status);
+	if (user_sid == NULL) {
+		NET_API_STATUS status;
+		if ((status = NetUserGetInfo(udom_utf16, uname_utf16, 23, &user_info)) != NERR_Success) {
+			debug("NetUserGetInfo() failed with error: %d \n", status);
 
-                DWORD dsStatus;
-                if ((dsStatus = DsGetDcNameW(NULL, udom_utf16, NULL, NULL, DS_DIRECTORY_SERVICE_PREFERRED, &pdc)) == ERROR_SUCCESS) {
-                    if ((status = NetUserGetInfo(pdc->DomainControllerName, uname_utf16, 23, &user_info)) != NERR_Success) {
-                        debug("NetUserGetInfo() with domainController failed with error: %d \n", status);
+			/* We reach here only for domain users.
+			 * If we didn't get the domain name from the end-user then we treat it as error and return.
+			 */
+			if (udom_utf16 == NULL) {
+				errno = ENOENT;
+				goto done;
+			}
 
-                        if (ConvertSidToStringSidW(((LPUSER_INFO_23)user_info)->usri23_user_sid, &user_sid_local) == FALSE) {
-							error("ConvertSidToStringSidW() failed with error: %d\n", GetLastError());
+			DWORD dsStatus;
+			if ((dsStatus = DsGetDcNameW(NULL, udom_utf16, NULL, NULL, DS_DIRECTORY_SERVICE_PREFERRED, &pdc)) == ERROR_SUCCESS) {
+				if ((status = NetUserGetInfo(pdc->DomainControllerName, uname_utf16, 23, &user_info)) != NERR_Success) {
+					debug("NetUserGetInfo() with domainController failed with error: %d \n", status);
 
-                            errno = ENOMEM; //??
-                            goto done;
-                        }
-                    }
-                } else {
-					error("DsGetDcNameW() failed with error: %d \n", dsStatus);
-                    errno = ENOMEM; //??
-                    goto done;
-                }
-            } else {
-                if (ConvertSidToStringSidW(((LPUSER_INFO_23)user_info)->usri23_user_sid, &user_sid_local) == FALSE) {
-					error("NetUserGetInfo() Succeded but ConvertSidToStringSidW() failed with error: %d\n", GetLastError());
-                    errno = ENOMEM; //??
-                    goto done;
-                }
-            }
+					if (ConvertSidToStringSidW(((LPUSER_INFO_23)user_info)->usri23_user_sid, &user_sid_local) == FALSE) {
+						error("ConvertSidToStringSidW() failed with error: %d\n", GetLastError());
 
-            user_sid = user_sid_local;
-        }
+						errno = ENOENT;
+						goto done;
+					}
+				}
+			}
+			else {
+				error("DsGetDcNameW() failed with error: %d \n", dsStatus);
+				errno = ENOENT;
+				goto done;
+			}
+		}
+		else {
+			if (ConvertSidToStringSidW(((LPUSER_INFO_23)user_info)->usri23_user_sid, &user_sid_local) == FALSE) {
+				debug("NetUserGetInfo() Succeded but ConvertSidToStringSidW() failed with error: %d\n", GetLastError());
+				errno = ENOENT;
+				goto done;
+			}
+		}
 
-        if (swprintf(reg_path, PATH_MAX, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", user_sid) == PATH_MAX ||
-                RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY, &reg_key) != 0 ||
-                RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, (LPBYTE)profile_home, &tmp_len) != 0)
-                GetWindowsDirectoryW(profile_home, PATH_MAX);
+		user_sid = user_sid_local;
+	}
 
-        if ((uname_utf8 = _strdup(user_utf8)) == NULL ||
-            (pw_home_utf8 = utf16_to_utf8(profile_home)) == NULL ||
-	    (user_sid_utf8 = utf16_to_utf8(user_sid)) == NULL)  {
-                errno = ENOMEM;
-                goto done;
-        }
-        
-        pw.pw_name = uname_utf8;
-        uname_utf8 = NULL;
-        pw.pw_dir = pw_home_utf8;
-        pw_home_utf8 = NULL;
-	pw.pw_sid =  user_sid_utf8;
+	/* if one of below fails, set profile path to Windows directory */
+	if (swprintf(reg_path, PATH_MAX, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", user_sid) == PATH_MAX ||
+	    RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY, &reg_key) != 0 ||
+	    RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, (LPBYTE)profile_home, &tmp_len) != 0)
+		GetWindowsDirectoryW(profile_home, PATH_MAX);
+
+	if ((uname_utf8 = utf16_to_utf8(uname_utf16)) == NULL ||
+	    (udom_utf16 && (udom_utf8 = utf16_to_utf8(udom_utf16)) == NULL) ||
+	    (pw_home_utf8 = utf16_to_utf8(profile_home)) == NULL ||
+	    (user_sid_utf8 = utf16_to_utf8(user_sid)) == NULL) {
+		errno = ENOMEM;
+		goto done;
+	}
+
+	pw.pw_name = uname_utf8;
+	uname_utf8 = NULL;
+	pw.pw_domain = udom_utf8;
+	udom_utf8 = NULL;
+	pw.pw_dir = pw_home_utf8;
+	pw_home_utf8 = NULL;
+	pw.pw_sid = user_sid_utf8;
 	user_sid_utf8 = NULL;
-        ret = &pw;
+	ret = &pw;
 
 done:
-        if (user_utf16)
-                free(user_utf16);
-        if (uname_utf8)
-                free(uname_utf8);
-        if (pw_home_utf8)
-                free(pw_home_utf8);
-        if (user_info)
-                NetApiBufferFree(user_info);
-        if (user_sid_local)
-                LocalFree(user_sid_local);
-        if (reg_key)
-                RegCloseKey(reg_key);
-        if (pdc)
-            NetApiBufferFree(pdc);
+	if (user_utf16)
+		free(user_utf16);
+	if (uname_utf8)
+		free(uname_utf8);
+	if (udom_utf8)
+		free(udom_utf8);
+	if (pw_home_utf8)
+		free(pw_home_utf8);
 	if (user_sid_utf8)
 		free(user_sid_utf8);
-        return ret;
+	if (user_info)
+		NetApiBufferFree(user_info);
+	if (user_sid_local)
+		LocalFree(user_sid_local);
+	if (reg_key)
+		RegCloseKey(reg_key);
+	if (pdc)
+		NetApiBufferFree(pdc);
+	return ret;
 }
 
 struct passwd*
-w32_getpwnam(const char *user_utf8) {
-        return get_passwd(user_utf8, NULL);
+	w32_getpwnam(const char *user_utf8) {
+	return get_passwd(user_utf8, NULL);
 }
 
 struct passwd*
-w32_getpwuid(uid_t uid) {
-        wchar_t* wuser = NULL;
-        char* user_utf8 = NULL;
-        ULONG needed = 0;
-        struct passwd *ret = NULL;
-        HANDLE token = 0;
-        DWORD info_len = 0;
-        TOKEN_USER* info = NULL;
-        LPWSTR user_sid = NULL;
+	w32_getpwuid(uid_t uid) {
+	wchar_t* wuser = NULL;
+	char* user_utf8 = NULL;
+	ULONG needed = 0;
+	struct passwd *ret = NULL;
+	HANDLE token = 0;
+	DWORD info_len = 0;
+	TOKEN_USER* info = NULL;
+	LPWSTR user_sid = NULL;
 
-        errno = 0;
-       
-        if (GetUserNameExW(NameSamCompatible, NULL, &needed) != 0 ||
-                (wuser = malloc(needed * sizeof(wchar_t))) == NULL ||
-                GetUserNameExW(NameSamCompatible, wuser, &needed) == 0 ||
-                (user_utf8 = utf16_to_utf8(wuser)) == NULL  ||
-                OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &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 ||
-                ConvertSidToStringSidW(info->User.Sid, &user_sid) == FALSE){
-                errno = ENOMEM;
-                goto done;
-        }
-        ret = get_passwd(user_utf8, user_sid);
+	errno = 0;
+
+	if (GetUserNameExW(NameSamCompatible, NULL, &needed) != 0 ||
+	    (wuser = malloc(needed * sizeof(wchar_t))) == NULL ||
+	    GetUserNameExW(NameSamCompatible, wuser, &needed) == 0 ||
+	    (user_utf8 = utf16_to_utf8(wuser)) == NULL  ||
+	    OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &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 ||
+	    ConvertSidToStringSidW(info->User.Sid, &user_sid) == FALSE) {
+		errno = ENOMEM;
+		goto done;
+	}
+	ret = get_passwd(user_utf8, user_sid);
 
 done:
-        if (wuser)
-                free(wuser);
-        if (user_utf8)
-                free(user_utf8);
-        if (token)
-                CloseHandle(token);
-        if (info)
-                free(info);
-        if (user_sid)
-                LocalFree(user_sid);
-        return ret;
+	if (wuser)
+		free(wuser);
+	if (user_utf8)
+		free(user_utf8);
+	if (token)
+		CloseHandle(token);
+	if (info)
+		free(info);
+	if (user_sid)
+		LocalFree(user_sid);
+	return ret;
 }
 
 
diff --git a/contrib/win32/win32compat/ssh-agent/authagent-request.c b/contrib/win32/win32compat/ssh-agent/authagent-request.c
index a9e24ec7c..45f0af833 100644
--- a/contrib/win32/win32compat/ssh-agent/authagent-request.c
+++ b/contrib/win32/win32compat/ssh-agent/authagent-request.c
@@ -39,351 +39,314 @@
 #include "agent-request.h"
 #include "key.h"
 
-static void 
+static void
 InitLsaString(LSA_STRING *lsa_string, const char *str)
 {
-        if (str == NULL)
-                memset(lsa_string, 0, sizeof(LSA_STRING));
-        else {
-                lsa_string->Buffer = (char *)str;
-                lsa_string->Length = strlen(str);
-                lsa_string->MaximumLength = lsa_string->Length + 1;
-        }
+	if (str == NULL)
+		memset(lsa_string, 0, sizeof(LSA_STRING));
+	else {
+		lsa_string->Buffer = (char *)str;
+		lsa_string->Length = strlen(str);
+		lsa_string->MaximumLength = lsa_string->Length + 1;
+	}
 }
 
 static void
 EnablePrivilege(const char *privName, int enabled)
 {
-        TOKEN_PRIVILEGES tp;
-        HANDLE hProcToken = NULL;
-        LUID luid;
+	TOKEN_PRIVILEGES tp;
+	HANDLE hProcToken = NULL;
+	LUID luid;
 
-        int exitCode = 1;
+	int exitCode = 1;
 
-        if (LookupPrivilegeValueA(NULL, privName, &luid) == FALSE ||
-                OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hProcToken) == FALSE)
-                goto done;
+	if (LookupPrivilegeValueA(NULL, privName, &luid) == FALSE ||
+		OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hProcToken) == FALSE)
+		goto done;
 
-        tp.PrivilegeCount = 1;
-        tp.Privileges[0].Luid = luid;
-        tp.Privileges[0].Attributes = enabled ? SE_PRIVILEGE_ENABLED : 0;
+	tp.PrivilegeCount = 1;
+	tp.Privileges[0].Luid = luid;
+	tp.Privileges[0].Attributes = enabled ? SE_PRIVILEGE_ENABLED : 0;
 
-        AdjustTokenPrivileges(hProcToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
+	AdjustTokenPrivileges(hProcToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
 
 done:
-        if (hProcToken)
-                CloseHandle(hProcToken);
-        
-        return;
+	if (hProcToken)
+		CloseHandle(hProcToken);
+
+	return;
 }
 
 
 void
 LoadProfile(struct agent_connection* con, wchar_t* user, wchar_t* domain) {
-        PROFILEINFOW profileInfo;
-        profileInfo.dwFlags = PI_NOUI;
-        profileInfo.lpProfilePath = NULL;
-        profileInfo.lpUserName = user;
-        profileInfo.lpDefaultPath = NULL;
-        profileInfo.lpServerName = domain;
-        profileInfo.lpPolicyPath = NULL;
-        profileInfo.hProfile = NULL;
-        profileInfo.dwSize = sizeof(profileInfo);
-        EnablePrivilege("SeBackupPrivilege", 1);
-        EnablePrivilege("SeRestorePrivilege", 1);
-        if (LoadUserProfileW(con->auth_token, &profileInfo) == FALSE)
-                debug("Loading user (%ls,%ls) profile failed ERROR: %d", user, domain, GetLastError());
-        else
-                con->hProfile = profileInfo.hProfile;
-        EnablePrivilege("SeBackupPrivilege", 0);
-        EnablePrivilege("SeRestorePrivilege", 0);
+	PROFILEINFOW profileInfo;
+	profileInfo.dwFlags = PI_NOUI;
+	profileInfo.lpProfilePath = NULL;
+	profileInfo.lpUserName = user;
+	profileInfo.lpDefaultPath = NULL;
+	profileInfo.lpServerName = domain;
+	profileInfo.lpPolicyPath = NULL;
+	profileInfo.hProfile = NULL;
+	profileInfo.dwSize = sizeof(profileInfo);
+	EnablePrivilege("SeBackupPrivilege", 1);
+	EnablePrivilege("SeRestorePrivilege", 1);
+	if (LoadUserProfileW(con->auth_token, &profileInfo) == FALSE)
+		debug("Loading user (%ls,%ls) profile failed ERROR: %d", user, domain, GetLastError());
+	else
+		con->hProfile = profileInfo.hProfile;
+	EnablePrivilege("SeBackupPrivilege", 0);
+	EnablePrivilege("SeRestorePrivilege", 0);
 }
 
-#define MAX_USER_LEN 256
-static HANDLE 
-generate_user_token(wchar_t* user) {
-        HANDLE lsa_handle = 0, token = 0;
-        LSA_OPERATIONAL_MODE mode;
-        ULONG auth_package_id;
-        NTSTATUS ret, subStatus;
-        void * logon_info = NULL;
-        size_t logon_info_size;
-        LSA_STRING logon_process_name, auth_package_name, originName;
-        TOKEN_SOURCE sourceContext;
-        PKERB_INTERACTIVE_PROFILE pProfile = NULL;
-        LUID logonId;
-        QUOTA_LIMITS quotas;
-        DWORD cbProfile;
-        BOOL domain_user;
-        wchar_t user_copy[MAX_USER_LEN];
-        
-        /* prep user name - TODO: implment an accurate check if user is domain account*/
-        if (wcsnlen(user, MAX_USER_LEN) == MAX_USER_LEN) {
-                debug("user length is not supported");
-                goto done;
-        }
+#define MAX_USER_LEN 64
+/* https://technet.microsoft.com/en-us/library/active-directory-maximum-limits-scalability(v=ws.10).aspx */
+#define MAX_FQDN_LEN 64 
+#define MAX_PW_LEN 64
 
-        if (wcschr(user, L'\\') != NULL) {
-                wchar_t *un = NULL, *dn = NULL;
-                DWORD un_len = 0, dn_len = 0;
-                dn = user;
-                dn_len = wcschr(user, L'\\') - user;
-                un = wcschr(user, L'\\') + 1;
-                un_len = wcsnlen(user, MAX_USER_LEN) - dn_len - 1;
-                if (dn_len == 0 || un_len == 0) {
-                        debug("cannot get user token - bad user name");
-                        goto done;
-                }
-                memcpy(user_copy, un, un_len * sizeof(wchar_t));
-                user_copy[un_len] = L'@';
-                memcpy(user_copy + un_len + 1, dn, dn_len * sizeof(wchar_t));
-                user_copy[dn_len + 1 + un_len] = L'\0';
-                user = user_copy;
-        }
-        
-        domain_user = (wcschr(user, L'@') != NULL) ? TRUE : FALSE;
+static HANDLE
+generate_user_token(wchar_t* user, wchar_t* domain) {
+	HANDLE lsa_handle = 0, token = 0;
+	LSA_OPERATIONAL_MODE mode;
+	ULONG auth_package_id;
+	NTSTATUS ret, subStatus;
+	void * logon_info = NULL;
+	size_t logon_info_size;
+	LSA_STRING logon_process_name, auth_package_name, originName;
+	TOKEN_SOURCE sourceContext;
+	PKERB_INTERACTIVE_PROFILE pProfile = NULL;
+	LUID logonId;
+	QUOTA_LIMITS quotas;
+	DWORD cbProfile;
+	BOOL domain_user;
 
-        InitLsaString(&logon_process_name, "ssh-agent");
-        if (domain_user)
-                InitLsaString(&auth_package_name, MICROSOFT_KERBEROS_NAME_A);
-        else 
-                InitLsaString(&auth_package_name, "SSH-LSA");
+	domain_user = (*domain != L'\0') ? TRUE : FALSE;
 
-        InitLsaString(&originName, "sshd");
-        if (ret = LsaRegisterLogonProcess(&logon_process_name, &lsa_handle, &mode) != STATUS_SUCCESS)
-                goto done;
+	InitLsaString(&logon_process_name, "ssh-agent");
+	if (domain_user)
+		InitLsaString(&auth_package_name, MICROSOFT_KERBEROS_NAME_A);
+	else
+		InitLsaString(&auth_package_name, "SSH-LSA");
 
-        if (ret = LsaLookupAuthenticationPackage(lsa_handle, &auth_package_name, &auth_package_id) != STATUS_SUCCESS)
-                goto done;
+	InitLsaString(&originName, "sshd");
+	if (ret = LsaRegisterLogonProcess(&logon_process_name, &lsa_handle, &mode) != STATUS_SUCCESS)
+		goto done;
 
-        if (domain_user) {
-                KERB_S4U_LOGON *s4u_logon;
-                logon_info_size = sizeof(KERB_S4U_LOGON);
-                logon_info_size += (wcslen(user) * 2 + 2);
-                logon_info = malloc(logon_info_size);
-                if (logon_info == NULL)
-                        goto done;
-                s4u_logon = (KERB_S4U_LOGON*)logon_info;
-                s4u_logon->MessageType = KerbS4ULogon;
-                s4u_logon->Flags = 0;
-                s4u_logon->ClientUpn.Length = wcslen(user) * 2;
-                s4u_logon->ClientUpn.MaximumLength = s4u_logon->ClientUpn.Length;
-                s4u_logon->ClientUpn.Buffer = (WCHAR*)(s4u_logon + 1);
-                memcpy(s4u_logon->ClientUpn.Buffer, user, s4u_logon->ClientUpn.Length + 2);
-                s4u_logon->ClientRealm.Length = 0;
-                s4u_logon->ClientRealm.MaximumLength = 0;
-                s4u_logon->ClientRealm.Buffer = 0;
-        }
-        else {
-                logon_info_size = (wcslen(user) + 1)*sizeof(wchar_t);
-                logon_info = malloc(logon_info_size);
-                if (logon_info == NULL)
-                        goto done;
-                memcpy(logon_info, user, logon_info_size);
-        }
+	if (ret = LsaLookupAuthenticationPackage(lsa_handle, &auth_package_name, &auth_package_id) != STATUS_SUCCESS)
+		goto done;
 
-        memcpy(sourceContext.SourceName,"sshagent", sizeof(sourceContext.SourceName));
+	if (domain_user) {
+		KERB_S4U_LOGON *s4u_logon;
+		wchar_t user_cpn[MAX_USER_LEN + 1 + MAX_FQDN_LEN + 1];
+		memcpy(user_cpn, user, wcslen(user) * 2);
+		user_cpn[wcslen(user)] = L'@';
+		memcpy(user_cpn + wcslen(user) + 1, domain, wcslen(domain) * 2 + 2);
+		logon_info_size = sizeof(KERB_S4U_LOGON);
+		logon_info_size += (wcslen(user_cpn) * 2 + 2);
+		logon_info = malloc(logon_info_size);
+		if (logon_info == NULL)
+			goto done;
+		s4u_logon = (KERB_S4U_LOGON*)logon_info;
+		s4u_logon->MessageType = KerbS4ULogon;
+		s4u_logon->Flags = 0;
+		s4u_logon->ClientUpn.Length = wcslen(user_cpn) * 2;
+		s4u_logon->ClientUpn.MaximumLength = s4u_logon->ClientUpn.Length;
+		s4u_logon->ClientUpn.Buffer = (WCHAR*)(s4u_logon + 1);
+		memcpy(s4u_logon->ClientUpn.Buffer, user_cpn, s4u_logon->ClientUpn.Length + 2);
+		s4u_logon->ClientRealm.Length = 0;
+		s4u_logon->ClientRealm.MaximumLength = 0;
+		s4u_logon->ClientRealm.Buffer = 0;
+	} else {
+		logon_info_size = (wcslen(user) + 1)*sizeof(wchar_t);
+		logon_info = malloc(logon_info_size);
+		if (logon_info == NULL)
+			goto done;
+		memcpy(logon_info, user, logon_info_size);
+	}
 
-        if (AllocateLocallyUniqueId(&sourceContext.SourceIdentifier) != TRUE)
-                goto done;
+	memcpy(sourceContext.SourceName,"sshagent", sizeof(sourceContext.SourceName));
 
-        if (ret = LsaLogonUser(lsa_handle,
-            &originName,
-            Network,
-            auth_package_id,
-            logon_info,
-            logon_info_size,
-            NULL,
-            &sourceContext,
-            (PVOID*)&pProfile,
-            &cbProfile,
-            &logonId,
-            &token,
-            &quotas,
-            &subStatus) != STATUS_SUCCESS) {
-            debug("LsaLogonUser failed %d", ret);
-                goto done;
-        }
-		debug3("LsaLogonUser succeeded");
+	if (AllocateLocallyUniqueId(&sourceContext.SourceIdentifier) != TRUE)
+		goto done;
+
+	if (ret = LsaLogonUser(lsa_handle,
+		&originName,
+		Network,
+		auth_package_id,
+		logon_info,
+		logon_info_size,
+		NULL,
+		&sourceContext,
+		(PVOID*)&pProfile,
+		&cbProfile,
+		&logonId,
+		&token,
+		&quotas,
+		&subStatus) != STATUS_SUCCESS) {
+		debug("LsaLogonUser failed %d", ret);
+		goto done;
+	}
+	debug3("LsaLogonUser succeeded");
 done:
-        if (lsa_handle)
-                LsaDeregisterLogonProcess(lsa_handle);
-        if (logon_info)
-                free(logon_info);
-        if (pProfile)
-                LsaFreeReturnBuffer(pProfile);
+	if (lsa_handle)
+		LsaDeregisterLogonProcess(lsa_handle);
+	if (logon_info)
+		free(logon_info);
+	if (pProfile)
+		LsaFreeReturnBuffer(pProfile);
 
-        return token;
+	return token;
 }
 
-#define PUBKEY_AUTH_REQUEST "pubkey"
-#define PASSWD_AUTH_REQUEST "password"
-#define MAX_USER_NAME_LEN 256
-#define MAX_PW_LEN 128
-
+/* TODO - SecureZeroMemory password */
 int process_passwordauth_request(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) {
-        char *user = NULL, *pwd = NULL;
-        wchar_t userW_buf[MAX_USER_NAME_LEN], pwdW_buf[MAX_PW_LEN];
-        wchar_t *userW = userW_buf, *domW = NULL, *pwdW = pwdW_buf, *tmp;
-        size_t user_len = 0, pwd_len = 0, dom_len = 0;
-        int r = -1;
-        HANDLE token = 0, dup_token, client_proc = 0;
-        ULONG client_pid;
+	char *user = NULL, *domain = NULL, *pwd = NULL;
+	wchar_t userW_buf[MAX_USER_LEN], domainW_buf[MAX_FQDN_LEN], pwdW_buf[MAX_PW_LEN];
+	wchar_t *userW = userW_buf, *domW = domainW_buf, *pwdW = pwdW_buf, *tmp;
+	size_t user_len = 0, domain_len = 0, pwd_len = 0, dom_len = 0;
+	int r = -1;
+	HANDLE token = 0, dup_token, client_proc = 0;
+	ULONG client_pid;
 
-        if (sshbuf_get_cstring(request, &user, &user_len) != 0 ||
-            sshbuf_get_cstring(request, &pwd, &pwd_len) != 0 ||
-            user_len == 0 ||
-            pwd_len == 0 ){
-                debug("bad password auth request");
-                goto done;
-        }
+	if (sshbuf_get_cstring(request, &user, &user_len) != 0 ||
+	    sshbuf_get_cstring(request, &domain, &domain_len) != 0 ||
+	    sshbuf_get_cstring(request, &pwd, &pwd_len) != 0 ||
+	    user_len == 0 ||
+	    pwd_len == 0 ||
+	    user_len > MAX_USER_LEN ||
+	    domain_len > MAX_FQDN_LEN ||
+	    pwd_len > MAX_PW_LEN) {
+		debug("bad password auth request");
+		goto done;
+	}
 
-        userW[0] = L'\0';
-        if (MultiByteToWideChar(CP_UTF8, 0, user, user_len + 1, userW, MAX_USER_NAME_LEN) == 0 ||
-            MultiByteToWideChar(CP_UTF8, 0, pwd, pwd_len + 1, pwdW, MAX_PW_LEN) == 0) {
-                debug("unable to convert user (%s) or password to UTF-16", user);
-                goto done;
-        }
-        
-        if ((tmp = wcschr(userW, L'\\')) != NULL) {
-                domW = userW;
-                userW = tmp + 1;
-                *tmp = L'\0';
+	userW[0] = L'\0';
+	domW[0] = L'\0';
+	if ((MultiByteToWideChar(CP_UTF8, 0, user, user_len + 1, userW, MAX_USER_LEN) == 0) ||
+	    (domain_len != 0 && MultiByteToWideChar(CP_UTF8, 0, domain, domain_len + 1, domW, MAX_FQDN_LEN) == 0) ||
+	    (MultiByteToWideChar(CP_UTF8, 0, pwd, pwd_len + 1, pwdW, MAX_PW_LEN) == 0)) {
+		debug("unable to convert user (%s) or password to UTF-16", user);
+		goto done;
+	}
 
-        }
-        else if ((tmp = wcschr(userW, L'@')) != NULL) {
-                domW = tmp + 1;
-                *tmp = L'\0';
-        }
+	if (LogonUserW(userW, domW, pwdW, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token) == FALSE) {
+		debug("failed to logon user");
+		goto done;
+	}
 
-        if (LogonUserW(userW, domW, pwdW, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token) == FALSE) {
-                debug("failed to logon user");
-                goto done;
-        }
-                
-        if ((FALSE == GetNamedPipeClientProcessId(con->connection, &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)) {
-                debug("failed to duplicate user token");
-                goto done;
-        }
+	if ((FALSE == GetNamedPipeClientProcessId(con->connection, &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)) {
+		debug("failed to duplicate user token");
+		goto done;
+	}
 
-        con->auth_token = token;
-        LoadProfile(con, userW, domW);
-        r = 0;
+	con->auth_token = token;
+	LoadProfile(con, userW, domW);
+	r = 0;
 done:
-        /* TODO Fix this hacky protocol*/
-        if ((r == -1) && (sshbuf_put_u8(response, SSH_AGENT_FAILURE) == 0))
-                r = 0;
-        
-        if (user)
-                free(user);
-        if (pwd)
-                free(pwd);
-        if (client_proc)
-                CloseHandle(client_proc);
+	/* TODO Fix this hacky protocol*/
+	if ((r == -1) && (sshbuf_put_u8(response, SSH_AGENT_FAILURE) == 0))
+		r = 0;
 
-        return r;
+	if (user)
+		free(user);
+	if (pwd)
+		free(pwd);
+	if (client_proc)
+		CloseHandle(client_proc);
+
+	return r;
 }
 
 int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) {
-        int r = -1;
-        char *key_blob, *user, *sig, *blob;
-        size_t key_blob_len, user_len, sig_len, blob_len;
-        struct sshkey *key = NULL;
-        HANDLE token = NULL, dup_token = NULL, client_proc = NULL;
-        wchar_t wuser[MAX_USER_NAME_LEN];
-        PWSTR wuser_home = NULL;
-        ULONG client_pid;
+	int r = -1;
+	char *key_blob, *user, *domain, *usernameWithDomain, *sig, *blob;
+	size_t key_blob_len, user_len, domain_len, sig_len, blob_len;
+	struct sshkey *key = NULL;
+	HANDLE token = NULL, dup_token = NULL, client_proc = NULL;
+	wchar_t wuser[MAX_USER_LEN], wdomain[MAX_FQDN_LEN];
+	PWSTR wuser_home = NULL;
+	ULONG client_pid;
 
-        user = NULL;
-        if (sshbuf_get_string_direct(request, &key_blob, &key_blob_len) != 0 ||
-            sshbuf_get_cstring(request, &user, &user_len) != 0 ||
-            sshbuf_get_string_direct(request, &sig, &sig_len) != 0 ||
-            sshbuf_get_string_direct(request, &blob, &blob_len) != 0 ||
-            sshkey_from_blob(key_blob, key_blob_len, &key) != 0) {
-                debug("invalid pubkey auth request");
-                goto done;
-        }
+	user = NULL;
+	domain = NULL;
+	if (sshbuf_get_string_direct(request, &key_blob, &key_blob_len) != 0 ||
+	    sshbuf_get_cstring(request, &user, &user_len) != 0 ||
+	    sshbuf_get_cstring(request, &domain, &domain_len) != 0 ||
+	    user_len > MAX_USER_LEN ||
+	    domain_len > MAX_FQDN_LEN ||
+	    sshbuf_get_string_direct(request, &sig, &sig_len) != 0 ||
+	    sshbuf_get_string_direct(request, &blob, &blob_len) != 0 ||
+	    sshkey_from_blob(key_blob, key_blob_len, &key) != 0) {
+		debug("invalid pubkey auth request");
+		goto done;
+	}
 
-        wuser[0] = L'\0';
-        if (MultiByteToWideChar(CP_UTF8, 0, user, user_len + 1, wuser, MAX_USER_NAME_LEN) == 0 ||
-            (token = generate_user_token(wuser)) == 0) {
-                debug("unable to generate token for user %ls", wuser);
-                goto done;
-        }
+	wuser[0] = L'\0';
+	wdomain[0] = L'\0';
+	if (MultiByteToWideChar(CP_UTF8, 0, user, user_len + 1, wuser, MAX_USER_LEN) == 0 ||
+	    (domain_len != 0 && MultiByteToWideChar(CP_UTF8, 0, domain, domain_len + 1, wdomain, MAX_FQDN_LEN) == 0) ||
+	    (token = generate_user_token(wuser, wdomain)) == 0) {
+		debug("unable to generate token for user %ls", wuser);
+		goto done;
+	}
 
-        con->auth_token = token;
+	con->auth_token = token;
 
-        if (SHGetKnownFolderPath(&FOLDERID_Profile, 0, token, &wuser_home) != S_OK ||
-                pubkey_allowed(key, wuser, wuser_home) != 1) {
-                debug("unable to verify public key for user %ls (profile:%ls)", wuser, wuser_home);
-                goto done;
-        }
+	if (SHGetKnownFolderPath(&FOLDERID_Profile, 0, token, &wuser_home) != S_OK ||
+	    pubkey_allowed(key, wuser, wuser_home) != 1) {
+		debug("unable to verify public key for user %ls (profile:%ls)", wuser, wuser_home);
+		goto done;
+	}
 
-        if (key_verify(key, sig, sig_len, blob, blob_len) != 1) {
-                debug("signature verification failed");
-                goto done;
-        }
-        
-        if ((FALSE == GetNamedPipeClientProcessId(con->connection, &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) ) {
-                debug("failed to authorize user");
-                goto done;
-        }
-        
-        {
-                wchar_t *tmp, *userW, *domW;
-                userW = wuser;
-                domW = NULL;
-                if ((tmp = wcschr(userW, L'\\')) != NULL) {
-                        domW = userW;
-                        userW = tmp + 1;
-                        *tmp = L'\0';
+	if (key_verify(key, sig, sig_len, blob, blob_len) != 1) {
+		debug("signature verification failed");
+		goto done;
+	}
 
-                }
-                else if ((tmp = wcschr(userW, L'@')) != NULL) {
-                        domW = tmp + 1;
-                        *tmp = L'\0';
-                }
-                LoadProfile(con, userW, domW);
-        }
+	if ((FALSE == GetNamedPipeClientProcessId(con->connection, &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)) {
+		debug("failed to authorize user");
+		goto done;
+	}
 
-        r = 0;
+	LoadProfile(con, wuser, wdomain);
+
+	r = 0;
 done:
-        /* TODO Fix this hacky protocol*/
-        if ((r == -1) && (sshbuf_put_u8(response, SSH_AGENT_FAILURE) == 0))
-                r = 0;
+	/* TODO Fix this hacky protocol*/
+	if ((r == -1) && (sshbuf_put_u8(response, SSH_AGENT_FAILURE) == 0))
+		r = 0;
 
-        if (user)
-                free(user);
-        if (key)
-                sshkey_free(key);
-        if (wuser_home)
-                CoTaskMemFree(wuser_home);
-        if (client_proc)
-                CloseHandle(client_proc);
-        return r;
+	if (user)
+		free(user);
+	if (key)
+		sshkey_free(key);
+	if (wuser_home)
+		CoTaskMemFree(wuser_home);
+	if (client_proc)
+		CloseHandle(client_proc);
+	return r;
 }
 
 int process_authagent_request(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) {
-        char *opn;
-        size_t opn_len;
-        if (sshbuf_get_string_direct(request, &opn, &opn_len) != 0) {
-                debug("invalid auth request");
-                return -1;
-        }
+	char *opn;
+	size_t opn_len;
+	if (sshbuf_get_string_direct(request, &opn, &opn_len) != 0) {
+		debug("invalid auth request");
+		return -1;
+	}
 
-        if (opn_len == strlen(PUBKEY_AUTH_REQUEST) && memcmp(opn, PUBKEY_AUTH_REQUEST, opn_len) == 0)
-                return process_pubkeyauth_request(request, response, con);
-        else if (opn_len == strlen(PASSWD_AUTH_REQUEST) && memcmp(opn, PASSWD_AUTH_REQUEST, opn_len) == 0)
-                return process_passwordauth_request(request, response, con);
-        else {
-                debug("unknown auth request: %s", opn);
-                return -1;
-        }
-                
+	if (memcmp(opn, PUBKEY_AUTH_REQUEST, opn_len) == 0)
+		return process_pubkeyauth_request(request, response, con);
+	else if (memcmp(opn, PASSWD_AUTH_REQUEST, opn_len) == 0)
+		return process_passwordauth_request(request, response, con);
+	else {
+		debug("unknown auth request: %s", opn);
+		return -1;
+	}
 }
\ No newline at end of file
diff --git a/contrib/win32/win32compat/ssh-agent/connection.c b/contrib/win32/win32compat/ssh-agent/connection.c
index b45a00522..d95973236 100644
--- a/contrib/win32/win32compat/ssh-agent/connection.c
+++ b/contrib/win32/win32compat/ssh-agent/connection.c
@@ -167,9 +167,6 @@ done:
 	return r;
 }
 
-/* TODO - move this to common header*/
-#define SSH_AGENT_AUTHENTICATE			100
-
 static int
 process_request(struct agent_connection* con) {
 	int r = -1;
@@ -179,7 +176,7 @@ process_request(struct agent_connection* con) {
 		if ((con->client_process = get_con_client_type(con->connection)) == -1)
 			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))
diff --git a/misc.c b/misc.c
index 3dfcef6f4..9cf39827a 100644
--- a/misc.c
+++ b/misc.c
@@ -225,6 +225,13 @@ pwcopy(struct passwd *pw)
 #endif
 	copy->pw_dir = xstrdup(pw->pw_dir);
 	copy->pw_shell = xstrdup(pw->pw_shell);
+#ifdef WINDOWS
+	if (pw->pw_domain != NULL)
+		copy->pw_domain = xstrdup(pw->pw_domain);
+	else
+		copy->pw_domain = NULL;
+#endif // WINDOWS
+
 	return copy;
 }