diff --git a/Makefile.in b/Makefile.in
index 5870e9e6..e247c0de 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -80,7 +80,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
 	canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \
 	cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
 	compat.o crc32.o deattack.o fatal.o hostfile.o \
-	log.o match.o md-sha256.o moduli.o nchan.o packet.o opacket.o \
+	log.o match.o moduli.o nchan.o packet.o opacket.o \
 	readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \
 	atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o utf8.o \
 	monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \
diff --git a/appveyor.yml b/appveyor.yml
index a9a77d0e..bf622a1b 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
-version: 0.0.10.0.{build}
+version: 0.0.12.0.{build}
 image: Visual Studio 2015
 
 branches:
@@ -18,10 +18,6 @@ after_build:
   - ps: |
       Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1 -DisableNameChecking
       Install-OpenSSH
-  - ps: Write-Verbose "Restart computer ..."
-  - ps: Restart-Computer -Force
-  - ps: Start-Sleep -s 5 # Needs to be proceeded with -ps: as it's interpreted by AppVeyor
-  - ps: Write-Verbose "Restart computer completed!"
 
 before_test:
   - ps: |
diff --git a/auth-pam.c b/auth-pam.c
index bc8e5e02..9574d9ac 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -106,7 +106,6 @@ extern char *__progname;
 
 extern ServerOptions options;
 extern Buffer loginmsg;
-extern int compat20;
 extern u_int utmp_len;
 
 /* so we don't silently change behaviour */
@@ -468,18 +467,16 @@ sshpam_thread(void *ctxtp)
 	if (sshpam_err != PAM_SUCCESS)
 		goto auth_fail;
 
-	if (compat20) {
-		if (!do_pam_account()) {
-			sshpam_err = PAM_ACCT_EXPIRED;
+	if (!do_pam_account()) {
+		sshpam_err = PAM_ACCT_EXPIRED;
+		goto auth_fail;
+	}
+	if (sshpam_authctxt->force_pwchange) {
+		sshpam_err = pam_chauthtok(sshpam_handle,
+		    PAM_CHANGE_EXPIRED_AUTHTOK);
+		if (sshpam_err != PAM_SUCCESS)
 			goto auth_fail;
-		}
-		if (sshpam_authctxt->force_pwchange) {
-			sshpam_err = pam_chauthtok(sshpam_handle,
-			    PAM_CHANGE_EXPIRED_AUTHTOK);
-			if (sshpam_err != PAM_SUCCESS)
-				goto auth_fail;
-			sshpam_password_change_required(0);
-		}
+		sshpam_password_change_required(0);
 	}
 
 	buffer_put_cstring(&buffer, "OK");
diff --git a/configure.ac b/configure.ac
index 82b28ce9..f7a04d55 100644
--- a/configure.ac
+++ b/configure.ac
@@ -179,6 +179,7 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int main(void) { return 0; }]])],
 CFLAGS="$saved_CFLAGS"
 
 if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
+	OSSH_CHECK_CFLAG_COMPILE([-pipe])
 	OSSH_CHECK_CFLAG_COMPILE([-Qunused-arguments])
 	OSSH_CHECK_CFLAG_COMPILE([-Wunknown-warning-option])
 	OSSH_CHECK_CFLAG_COMPILE([-Wall])
@@ -2769,9 +2770,6 @@ if test "x$openssl" = "xyes" ; then
 	#include <openssl/evp.h>
 	#include <openssl/objects.h>
 	#include <openssl/opensslv.h>
-	#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
-	# error "OpenSSL < 0.9.8g has unreliable ECC code"
-	#endif
 		]], [[
 		EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
 		const EVP_MD *m = EVP_sha256(); /* We need this too */
@@ -2790,9 +2788,6 @@ if test "x$openssl" = "xyes" ; then
 	#include <openssl/evp.h>
 	#include <openssl/objects.h>
 	#include <openssl/opensslv.h>
-	#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
-	# error "OpenSSL < 0.9.8g has unreliable ECC code"
-	#endif
 		]], [[
 		EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1);
 		const EVP_MD *m = EVP_sha384(); /* We need this too */
@@ -2811,9 +2806,6 @@ if test "x$openssl" = "xyes" ; then
 	#include <openssl/evp.h>
 	#include <openssl/objects.h>
 	#include <openssl/opensslv.h>
-	#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
-	# error "OpenSSL < 0.9.8g has unreliable ECC code"
-	#endif
 		]], [[
 		EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1);
 		const EVP_MD *m = EVP_sha512(); /* We need this too */
diff --git a/contrib/win32/openssh/AppveyorHelper.psm1 b/contrib/win32/openssh/AppveyorHelper.psm1
index f0f97c0f..3157150e 100644
--- a/contrib/win32/openssh/AppveyorHelper.psm1
+++ b/contrib/win32/openssh/AppveyorHelper.psm1
@@ -81,8 +81,6 @@ function Invoke-AppVeyorFull
         Set-OpenSSHTestParams
         Invoke-AppVeyorBuild
         Install-OpenSSH
-        Install-OpenSSHTestDependencies
-        Deploy-OpenSSHTests
         Setup-OpenSSHTestEnvironment
         Run-OpenSSHTests
         Publish-Artifact
diff --git a/contrib/win32/openssh/OpenSSHBuildHelper.psm1 b/contrib/win32/openssh/OpenSSHBuildHelper.psm1
index 21adf883..345c7c7f 100644
--- a/contrib/win32/openssh/OpenSSHBuildHelper.psm1
+++ b/contrib/win32/openssh/OpenSSHBuildHelper.psm1
@@ -299,7 +299,10 @@ function Package-OpenSSH
         [string]$NativeHostArch = "x64",
 
         [ValidateSet('Debug', 'Release', '')]
-        [string]$Configuration = "Release"
+        [string]$Configuration = "Release",
+
+        # Copy payload to DestinationPath instead of packaging
+        [string]$DestinationPath = ""
     )
 
     [System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
@@ -311,9 +314,8 @@ function Package-OpenSSH
     }
     $buildDir = Join-Path $repositoryRoot ("bin\" + $folderName + "\" + $Configuration)
     $payload = "sshd.exe", "ssh.exe", "ssh-agent.exe", "ssh-add.exe", "sftp.exe"
-    $payload += "sftp-server.exe", "scp.exe", "ssh-lsa.dll", "ssh-shellhost.exe", "ssh-keygen.exe" 
+    $payload += "sftp-server.exe", "scp.exe", "ssh-shellhost.exe", "ssh-keygen.exe" 
     $payload += "sshd_config", "install-sshd.ps1", "uninstall-sshd.ps1"
-    $payload += "install-sshlsa.ps1", "uninstall-sshlsa.ps1"
 
     $packageName = "OpenSSH-Win64"
     if ($NativeHostArch -eq 'x86') {
@@ -343,12 +345,29 @@ function Package-OpenSSH
         }
     }
 
-    Remove-Item ($packageDir + '.zip') -Force -ErrorAction SilentlyContinue
-    Compress-Archive -Path $packageDir -DestinationPath ($packageDir + '.zip')
+    if ($DestinationPath -ne "") {
+        if (Test-Path $DestinationPath) {
+            Remove-Item $DestinationPath\* -Force
+        }
+        else {
+            New-Item -ItemType Directory $DestinationPath | Out-Null
+        }
+        Copy-Item -Path $packageDir\* -Destination $DestinationPath -Force -Recurse
+    }
+    else {
+        Remove-Item ($packageDir + '.zip') -Force -ErrorAction SilentlyContinue
+        Compress-Archive -Path $packageDir -DestinationPath ($packageDir + '.zip')
+    }
     Remove-Item $packageDir -Recurse -Force -ErrorAction SilentlyContinue
 
-    Remove-Item ($symbolsDir + '.zip') -Force -ErrorAction SilentlyContinue
-    Compress-Archive -Path $symbolsDir -DestinationPath ($symbolsDir + '.zip')
+    
+    if ($DestinationPath -ne "") {
+        Copy-Item -Path $symbolsDir\* -Destination $DestinationPath -Force -Recurse
+    }
+    else {
+        Remove-Item ($symbolsDir + '.zip') -Force -ErrorAction SilentlyContinue
+        Compress-Archive -Path $symbolsDir -DestinationPath ($symbolsDir + '.zip')
+    }
     Remove-Item $symbolsDir -Recurse -Force -ErrorAction SilentlyContinue
 }
 
@@ -436,97 +455,41 @@ function Get-SolutionFile
 
 <#
     .Synopsis
-    Deploy all required files to build a package and create zip file.
+    Deploy all required files to a location and install the binaries
 #>
-function Deploy-Win32OpenSSHBinaries
+function Install-OpenSSH
 {
     [CmdletBinding()]
     param
-    (
+    ( 
         [ValidateSet('Debug', 'Release', '')]
         [string]$Configuration = "",
+
         [ValidateSet('x86', 'x64', '')]
         [string]$NativeHostArch = "",
+
         [string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
     )
 
-    if (-not (Test-Path -Path $OpenSSHDir -PathType Container))
+    if ($Configuration -eq "")
     {
-        $null = New-Item -Path $OpenSSHDir -ItemType Directory -Force -ErrorAction Stop
+        $Configuration = 'Release'
     }
 
-    [string] $platform = $env:PROCESSOR_ARCHITECTURE    
-    if(-not [String]::IsNullOrEmpty($NativeHostArch))
+    if ($NativeHostArch -eq "") 
     {
-        $folderName = $NativeHostArch
-        if($NativeHostArch -ieq 'x86')
-        {
-            $folderName = "Win32"
-        }
-    }
-    else
-    {
-        if($platform -ieq "AMD64")
-        {
-            $folderName = "x64"
-        }
-        else
-        {
-            $folderName = "Win32"
-        }
-    }
-    
-    if([String]::IsNullOrEmpty($Configuration))
-    {
-        if( $folderName -ieq "Win32" )
-        {
-            $RealConfiguration = "Debug"
-        }
-        else
-        {
-            $RealConfiguration = "Release"
+        $NativeHostArch = 'x64'
+        if ($env:PROCESSOR_ARCHITECTURE  -eq 'x86') {
+            $NativeHostArch = 'x86'
         }
     }
-    else
-    {
-        $RealConfiguration = $Configuration
-    }
 
-    [System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
-    
-    $sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$RealConfiguration"
-    if((Get-Service ssh-agent -ErrorAction Ignore) -ne $null) {
-        Stop-Service ssh-agent -Force
-    }
-    Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHDir -Include *.exe,*.dll -Exclude *unittest*.* -Force -ErrorAction Stop
-    $sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "contrib\win32\openssh"
-    Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHDir -Include *.ps1,sshd_config -Exclude AnalyzeCodeDiff.ps1 -Force -ErrorAction Stop
-}
-
-<#
-    .Synopsis
-    Deploy all required files to a location and install the binaries
-#>
-function Install-OpenSSH
-{
-    [CmdletBinding()]
-    param
-    ( 
-        [ValidateSet('Debug', 'Release', '')]
-        [string]$Configuration = "",
-
-        [ValidateSet('x86', 'x64', '')]
-        [string]$NativeHostArch = "",
-
-        [string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
-    )
-
-    Deploy-Win32OpenSSHBinaries @PSBoundParameters
+    Package-OpenSSH -NativeHostArch $NativeHostArch -Configuration $Configuration -DestinationPath $OpenSSHDir
 
     Push-Location $OpenSSHDir 
     & ( "$OpenSSHDir\install-sshd.ps1") 
     .\ssh-keygen.exe -A
-    & ( "$OpenSSHDir\install-sshlsa.ps1")
+
 
     #machine will be reboot after Install-openssh anyway
     $machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
diff --git a/contrib/win32/openssh/Win32-OpenSSH.sln b/contrib/win32/openssh/Win32-OpenSSH.sln
index f808422c..e70453bf 100644
--- a/contrib/win32/openssh/Win32-OpenSSH.sln
+++ b/contrib/win32/openssh/Win32-OpenSSH.sln
@@ -55,11 +55,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sshd", "sshd.vcxproj", "{F5
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "config", "config.vcxproj", "{8F9D3B74-8D33-448E-9762-26E8DCC6B2F4}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssh-lsa", "ssh-lsa.vcxproj", "{02FB3D98-6516-42C6-9762-98811A99960F}"
-	ProjectSection(ProjectDependencies) = postProject
-		{8F9D3B74-8D33-448E-9762-26E8DCC6B2F4} = {8F9D3B74-8D33-448E-9762-26E8DCC6B2F4}
-	EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "posix_compat", "win32iocompat.vcxproj", "{0D02F0F0-013B-4EE3-906D-86517F3822C0}"
 	ProjectSection(ProjectDependencies) = postProject
 		{8F9D3B74-8D33-448E-9762-26E8DCC6B2F4} = {8F9D3B74-8D33-448E-9762-26E8DCC6B2F4}
@@ -226,14 +221,6 @@ Global
 		{8F9D3B74-8D33-448E-9762-26E8DCC6B2F4}.Release|x64.Build.0 = Release|x64
 		{8F9D3B74-8D33-448E-9762-26E8DCC6B2F4}.Release|x86.ActiveCfg = Release|Win32
 		{8F9D3B74-8D33-448E-9762-26E8DCC6B2F4}.Release|x86.Build.0 = Release|Win32
-		{02FB3D98-6516-42C6-9762-98811A99960F}.Debug|x64.ActiveCfg = Debug|x64
-		{02FB3D98-6516-42C6-9762-98811A99960F}.Debug|x64.Build.0 = Debug|x64
-		{02FB3D98-6516-42C6-9762-98811A99960F}.Debug|x86.ActiveCfg = Debug|Win32
-		{02FB3D98-6516-42C6-9762-98811A99960F}.Debug|x86.Build.0 = Debug|Win32
-		{02FB3D98-6516-42C6-9762-98811A99960F}.Release|x64.ActiveCfg = Release|x64
-		{02FB3D98-6516-42C6-9762-98811A99960F}.Release|x64.Build.0 = Release|x64
-		{02FB3D98-6516-42C6-9762-98811A99960F}.Release|x86.ActiveCfg = Release|Win32
-		{02FB3D98-6516-42C6-9762-98811A99960F}.Release|x86.Build.0 = Release|Win32
 		{0D02F0F0-013B-4EE3-906D-86517F3822C0}.Debug|x64.ActiveCfg = Debug|x64
 		{0D02F0F0-013B-4EE3-906D-86517F3822C0}.Debug|x64.Build.0 = Debug|x64
 		{0D02F0F0-013B-4EE3-906D-86517F3822C0}.Debug|x86.ActiveCfg = Debug|Win32
@@ -343,7 +330,6 @@ Global
 		{6657614F-7821-4D55-96EF-7C3C4B551880} = {17322AAF-808F-4646-AD37-5B0EDDCB8F3E}
 		{F58FF6BA-098B-4DB9-9609-A030DFB4D03F} = {17322AAF-808F-4646-AD37-5B0EDDCB8F3E}
 		{8F9D3B74-8D33-448E-9762-26E8DCC6B2F4} = {17322AAF-808F-4646-AD37-5B0EDDCB8F3E}
-		{02FB3D98-6516-42C6-9762-98811A99960F} = {17322AAF-808F-4646-AD37-5B0EDDCB8F3E}
 		{0D02F0F0-013B-4EE3-906D-86517F3822C0} = {17322AAF-808F-4646-AD37-5B0EDDCB8F3E}
 		{C0AE8A30-E4FA-49CE-A2B5-0C072C77EC64} = {17322AAF-808F-4646-AD37-5B0EDDCB8F3E}
 		{F6644EC5-D6B6-42A1-828C-75E2977470E0} = {17322AAF-808F-4646-AD37-5B0EDDCB8F3E}
diff --git a/contrib/win32/openssh/config.h.vs b/contrib/win32/openssh/config.h.vs
index 7d5ea2ec..bb5030ec 100644
--- a/contrib/win32/openssh/config.h.vs
+++ b/contrib/win32/openssh/config.h.vs
@@ -297,7 +297,7 @@
 
 /* Define to 1 if you have the declaration of `O_NONBLOCK', and to 0 if you
    don't. */
-#define HAVE_DECL_O_NONBLOCK 0
+#define HAVE_DECL_O_NONBLOCK 1
 
 /* Define to 1 if you have the declaration of `passwdexpired', and to 0 if you
    don't. */
diff --git a/contrib/win32/openssh/keygen.vcxproj b/contrib/win32/openssh/keygen.vcxproj
index 690ec33d..ac196225 100644
--- a/contrib/win32/openssh/keygen.vcxproj
+++ b/contrib/win32/openssh/keygen.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="paths.targets" />
   <ItemGroup Label="ProjectConfigurations">
@@ -186,6 +186,7 @@
   <ItemGroup>
     <ClCompile Include="$(OpenSSH-Src-Path)ssh-keygen.c" />
     <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c" />
+    <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32-utf8.c" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="version.rc" />
@@ -193,4 +194,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/contrib/win32/openssh/keygen.vcxproj.filters b/contrib/win32/openssh/keygen.vcxproj.filters
index dd9dd237..8c39fa3e 100644
--- a/contrib/win32/openssh/keygen.vcxproj.filters
+++ b/contrib/win32/openssh/keygen.vcxproj.filters
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
     <Filter Include="Source Files">
@@ -21,10 +21,13 @@
     <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32-utf8.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="version.rc">
       <Filter>Resource Files</Filter>
     </ResourceCompile>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/contrib/win32/openssh/libssh.vcxproj b/contrib/win32/openssh/libssh.vcxproj
index 16fff961..dc6ce550 100644
--- a/contrib/win32/openssh/libssh.vcxproj
+++ b/contrib/win32/openssh/libssh.vcxproj
@@ -240,7 +240,6 @@
     <ClCompile Include="$(OpenSSH-Src-Path)log.c" />
     <ClCompile Include="$(OpenSSH-Src-Path)mac.c" />
     <ClCompile Include="$(OpenSSH-Src-Path)match.c" />
-    <ClCompile Include="$(OpenSSH-Src-Path)md-sha256.c" />
     <ClCompile Include="$(OpenSSH-Src-Path)misc.c" />
     <ClCompile Include="$(OpenSSH-Src-Path)moduli.c" />
     <ClCompile Include="$(OpenSSH-Src-Path)monitor_fdpass.c" />
diff --git a/contrib/win32/openssh/libssh.vcxproj.filters b/contrib/win32/openssh/libssh.vcxproj.filters
index 1959987d..2af40a2d 100644
--- a/contrib/win32/openssh/libssh.vcxproj.filters
+++ b/contrib/win32/openssh/libssh.vcxproj.filters
@@ -177,9 +177,6 @@
     <ClCompile Include="$(OpenSSH-Src-Path)match.c">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="$(OpenSSH-Src-Path)md-sha256.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="$(OpenSSH-Src-Path)misc.c">
       <Filter>Source Files</Filter>
     </ClCompile>
diff --git a/contrib/win32/openssh/scp.vcxproj b/contrib/win32/openssh/scp.vcxproj
index 7a922545..1a473315 100644
--- a/contrib/win32/openssh/scp.vcxproj
+++ b/contrib/win32/openssh/scp.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="paths.targets" />
   <ItemGroup Label="ProjectConfigurations">
@@ -22,6 +22,7 @@
   <ItemGroup>
     <ClCompile Include="$(OpenSSH-Src-Path)scp.c" />
     <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c" />
+    <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32-utf8.c" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="version.rc" />
@@ -191,4 +192,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/contrib/win32/openssh/scp.vcxproj.filters b/contrib/win32/openssh/scp.vcxproj.filters
index fccf50e0..e3784380 100644
--- a/contrib/win32/openssh/scp.vcxproj.filters
+++ b/contrib/win32/openssh/scp.vcxproj.filters
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
     <Filter Include="Source Files">
@@ -21,10 +21,13 @@
     <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32-utf8.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="version.rc">
       <Filter>Resource Files</Filter>
     </ResourceCompile>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/contrib/win32/openssh/sftp.vcxproj b/contrib/win32/openssh/sftp.vcxproj
index b5580335..c7ffb6da 100644
--- a/contrib/win32/openssh/sftp.vcxproj
+++ b/contrib/win32/openssh/sftp.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="paths.targets" />
   <ItemGroup Label="ProjectConfigurations">
@@ -26,6 +26,7 @@
     <ClCompile Include="$(OpenSSH-Src-Path)sftp-glob.c" />
     <ClCompile Include="$(OpenSSH-Src-Path)sftp.c" />
     <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c" />
+    <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32-utf8.c" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="version.rc" />
@@ -197,4 +198,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/contrib/win32/openssh/sftp.vcxproj.filters b/contrib/win32/openssh/sftp.vcxproj.filters
index 04bc6520..60da32cc 100644
--- a/contrib/win32/openssh/sftp.vcxproj.filters
+++ b/contrib/win32/openssh/sftp.vcxproj.filters
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
     <Filter Include="Source Files">
@@ -33,10 +33,13 @@
     <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32-utf8.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="version.rc">
       <Filter>Resource Files</Filter>
     </ResourceCompile>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/contrib/win32/openssh/ssh.vcxproj b/contrib/win32/openssh/ssh.vcxproj
index d7279344..83c43367 100644
--- a/contrib/win32/openssh/ssh.vcxproj
+++ b/contrib/win32/openssh/ssh.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="paths.targets" />
   <ItemGroup Label="ProjectConfigurations">
@@ -298,8 +298,9 @@
     <ClCompile Include="$(OpenSSH-Src-Path)sshconnect.c" />
     <ClCompile Include="$(OpenSSH-Src-Path)sshconnect1.c" />
     <ClCompile Include="$(OpenSSH-Src-Path)sshconnect2.c" />
-    <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c" />    
+    <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c" />
     <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32_sshtty.c" />
+    <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32-utf8.c" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="version.rc" />
@@ -307,4 +308,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/contrib/win32/openssh/ssh.vcxproj.filters b/contrib/win32/openssh/ssh.vcxproj.filters
index 8acdd0e2..fae9a0fd 100644
--- a/contrib/win32/openssh/ssh.vcxproj.filters
+++ b/contrib/win32/openssh/ssh.vcxproj.filters
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
     <Filter Include="Source Files">
@@ -311,10 +311,13 @@
     <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32_sshtty.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32-utf8.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="version.rc">
       <Filter>Resource Files</Filter>
     </ResourceCompile>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/contrib/win32/openssh/version.rc b/contrib/win32/openssh/version.rc
index c3fdf824..035ec265 100644
Binary files a/contrib/win32/openssh/version.rc and b/contrib/win32/openssh/version.rc differ
diff --git a/contrib/win32/openssh/win32iocompat.vcxproj b/contrib/win32/openssh/win32iocompat.vcxproj
index c2b0024b..51c41999 100644
--- a/contrib/win32/openssh/win32iocompat.vcxproj
+++ b/contrib/win32/openssh/win32iocompat.vcxproj
@@ -160,7 +160,6 @@
     <ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tncon.c" />
     <ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tnnet.c" />
     <ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\utf.c" />
-    <ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\win32-utf8.c" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\w32fd.h" />
diff --git a/contrib/win32/openssh/win32iocompat.vcxproj.filters b/contrib/win32/openssh/win32iocompat.vcxproj.filters
index 2152b5fa..456abfed 100644
--- a/contrib/win32/openssh/win32iocompat.vcxproj.filters
+++ b/contrib/win32/openssh/win32iocompat.vcxproj.filters
@@ -19,7 +19,6 @@
     <ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tncon.c" />
     <ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tnnet.c" />
     <ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\utf.c" />
-    <ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\win32-utf8.c" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\w32fd.h" />
diff --git a/contrib/win32/win32compat/console.c b/contrib/win32/win32compat/console.c
index 11650126..04c04ffe 100644
--- a/contrib/win32/win32compat/console.c
+++ b/contrib/win32/win32compat/console.c
@@ -1581,11 +1581,11 @@ get_console_handle(FILE *stream, DWORD * mode)
 
 	file_num = (_fileno)(stream);
 	if (file_num == -1) {
-		return -1;
+		return INVALID_HANDLE_VALUE;
 	}
 	lHandle = _get_osfhandle(file_num);
 	if (lHandle == -1 && errno == EBADF) {
-		return -1;
+		return INVALID_HANDLE_VALUE;
 	}
 	type = GetFileType((HANDLE)lHandle);
 	if (type == FILE_TYPE_CHAR && file_num >= 0 && file_num <= 2) {
diff --git a/contrib/win32/win32compat/fileio.c b/contrib/win32/win32compat/fileio.c
index 49da1ad5..7a6cc107 100644
--- a/contrib/win32/win32compat/fileio.c
+++ b/contrib/win32/win32compat/fileio.c
@@ -29,8 +29,8 @@
 */
 
 #include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
+#include "inc/sys/stat.h"
+#include "inc/sys/types.h"
 #include <io.h>
 #include <errno.h>
 #include <stddef.h>
@@ -55,8 +55,9 @@ struct createFile_flags {
 	DWORD dwFlagsAndAttributes;
 };
 
-int termio_initiate_read(struct w32_io* pio);
-int termio_initiate_write(struct w32_io* pio, DWORD num_bytes);
+int syncio_initiate_read(struct w32_io* pio);
+int syncio_initiate_write(struct w32_io* pio, DWORD num_bytes);
+int syncio_close(struct w32_io* pio);
 
 /* maps Win32 error to errno */
 int
@@ -440,11 +441,10 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max)
 	}
 
 	if (fileio_is_io_available(pio, TRUE) == FALSE) {
-		if (FILETYPE(pio) == FILE_TYPE_CHAR) {
-			if (-1 == termio_initiate_read(pio))
+		if (pio->type == NONSOCK_SYNC_FD || FILETYPE(pio) == FILE_TYPE_CHAR) {
+			if (-1 == syncio_initiate_read(pio))
 				return -1;
-		}
-		else {
+		} else {
 			if (-1 == fileio_ReadFileEx(pio, max)) {
 				if ((FILETYPE(pio) == FILE_TYPE_PIPE)
 					&& (errno == ERROR_BROKEN_PIPE)) {
@@ -571,46 +571,12 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max)
 	bytes_copied = min(max, pio->write_details.buf_size);
 	memcpy(pio->write_details.buf, buf, bytes_copied);
 
-	if (FILETYPE(pio) == FILE_TYPE_CHAR) {
-		if (termio_initiate_write(pio, bytes_copied) == 0) {
+	if (pio->type == NONSOCK_SYNC_FD || FILETYPE(pio) == FILE_TYPE_CHAR) {
+		if (syncio_initiate_write(pio, bytes_copied) == 0) {
 			pio->write_details.pending = TRUE;
 			pio->write_details.remaining = bytes_copied;
-		}
-		else
-			return -1;
-	} else if ( FILETYPE(pio) == FILE_TYPE_PIPE &&
-	    GetNamedPipeInfo(WINHANDLE(pio), &pipe_flags, NULL, NULL, &pipe_instances) &&
-	    pipe_flags == PIPE_CLIENT_END && pipe_instances == 1) {
-		/* 
-		 * TODO - Figure out a better solution to this problem 
-		 * IO handle corresponding to this object (pio->handle) may be referring
-		 * to something that isn't opened in overlapped mode. While all handles
-		 * opened by this POSIX wrapper are opened in overlapped mode, other handles
-		 * that are inherited (ex. via std i/o) are typically not. 
-		 * Ex. When we do this in Powershell
-		 * $o = ssh.exe user@target hostname
-		 * Powershell creates anonymous pipes (that do not support overlapped i.o)
-		 * Calling asynchronous I/O APIs (WriteFileEx) for example will not work in 
-		 * those cases (the callback is never called and it typically manifests as a 
-		 * hang to end user
-		 *
-		 * This conditional logic is put in place to specifically handle Powershell 
-		 * redirection scenarios. Thinking behind these conditions
-		 * - should be a pipe handle. console I/O is handled in termio.c, impacting file i/o
-		 *   scenarios not found yet.
-		 * - pipe should be the client end. This is to skip pipes created internally in POSIX
-		 *   wrapper (by pipe() calls) - The write ends on these pipes are on server
-		 * - pipe_instances == 1. This is to skip pipe handles created as part of Connect(AF_UNIX)
-		 *   sockets (that typically are created for unlimited instances). 
-		 * For such I/O we do a synchronous write. 
-		 */
-		/* DebugBreak() */;
-		if (WriteFile(WINHANDLE(pio), pio->write_details.buf, bytes_copied, &bytes_copied, NULL) == FALSE) {
-			errno = errno_from_Win32LastError();
-			debug3("write - WriteFile() ERROR:%d, io:%p", GetLastError(), pio);
+		} else
 			return -1;
-		}
-		return bytes_copied;
 	} else {
 		if (WriteFileEx(WINHANDLE(pio), pio->write_details.buf, bytes_copied,
 			&pio->write_overlapped, &WriteCompletionRoutine)) {
@@ -753,8 +719,8 @@ fileio_on_select(struct w32_io* pio, BOOL rd)
 
 	if (!pio->read_details.pending && !fileio_is_io_available(pio, rd))
 		/* initiate read, record any error so read() will pick up */
-		if (FILETYPE(pio) == FILE_TYPE_CHAR) {
-			if (termio_initiate_read(pio) != 0) {
+		if (pio->type == NONSOCK_SYNC_FD || FILETYPE(pio) == FILE_TYPE_CHAR) {
+			if (syncio_initiate_read(pio) != 0) {
 				pio->read_details.error = errno;
 				errno = 0;
 				return;
@@ -773,6 +739,9 @@ fileio_close(struct w32_io* pio)
 {
 	debug4("fileclose - pio:%p", pio);
 
+	if (pio->type == NONSOCK_SYNC_FD || FILETYPE(pio) == FILE_TYPE_CHAR)
+		return syncio_close(pio);
+
 	/* handle can be null on AF_UNIX sockets that are not yet connected */
 	if (WINHANDLE(pio) == 0 || WINHANDLE(pio) == INVALID_HANDLE_VALUE) {
 		free(pio);
@@ -782,15 +751,13 @@ fileio_close(struct w32_io* pio)
 	CancelIo(WINHANDLE(pio));
 	/* let queued APCs (if any) drain */
 	SleepEx(0, TRUE);
-	if (pio->type != STD_IO_FD) { /* STD handles are never explicitly closed */
-		CloseHandle(WINHANDLE(pio));
-
+	CloseHandle(WINHANDLE(pio));
+	/* free up non stdio */
+	if (!IS_STDIO(pio)) {
 		if (pio->read_details.buf)
 			free(pio->read_details.buf);
-
 		if (pio->write_details.buf)
 			free(pio->write_details.buf);
-
 		free(pio);
 	}
 	return 0;
diff --git a/contrib/win32/win32compat/inc/fcntl.h b/contrib/win32/win32compat/inc/fcntl.h
index 3f651493..fba482ee 100644
--- a/contrib/win32/win32compat/inc/fcntl.h
+++ b/contrib/win32/win32compat/inc/fcntl.h
@@ -22,7 +22,6 @@ int w32_open(const char *pathname, int flags, ...);
 void* w32_fd_to_handle(int fd);
 int w32_allocate_fd_for_handle(void* h, int is_sock);
 
-#define O_ACCMODE	  0x0003
 #define O_RDONLY     _O_RDONLY
 #define O_WRONLY     _O_WRONLY
 #define O_RDWR       _O_RDWR
@@ -37,4 +36,26 @@ int w32_allocate_fd_for_handle(void* h, int is_sock);
 #define O_NOINHERIT  _O_NOINHERIT
 #define O_SEQUENTIAL _O_SEQUENTIAL
 #define O_RANDOM     _O_RANDOM
-#define O_U16TEXT     _O_U16TEXT
\ No newline at end of file
+#define O_U16TEXT     _O_U16TEXT
+
+/*
+* open() POSIX specific modes and flags.
+* Caution while making changes
+* - cross check conflict with common macros in Windows headers
+* - Ex. #define O_APPEND    0x8
+*/
+#define O_ACCMODE			0x0003
+#define O_NONBLOCK			0x0004  /*io operations wont block*/
+# define S_IXUSR			0000100	/* execute/search permission, */
+# define S_IXGRP			0000010	/* execute/search permission, */
+# define S_IXOTH			0000001	/* execute/search permission, */
+# define _S_IWUSR			0000200	/* write permission, */
+# define S_IWUSR			_S_IWUSR	/* write permission, owner */
+# define S_IWGRP			0000020	/* write permission, group */
+# define S_IWOTH			0000002	/* write permission, other */
+# define S_IRUSR			0000400	/* read permission, owner */
+# define S_IRGRP			0000040	/* read permission, group */
+# define S_IROTH			0000004	/* read permission, other */
+# define S_IRWXU			0000700	/* read, write, execute */
+# define S_IRWXG			0000070	/* read, write, execute */
+# define S_IRWXO			0000007	/* read, write, execute */
\ No newline at end of file
diff --git a/contrib/win32/win32compat/misc.c b/contrib/win32/win32compat/misc.c
index 93b1af39..99bbaf3b 100644
--- a/contrib/win32/win32compat/misc.c
+++ b/contrib/win32/win32compat/misc.c
@@ -404,123 +404,6 @@ w32_ioctl(int d, int request, ...)
 	}
 }
 
-/* 
- * spawn a child process 
- * - specified by cmd with agruments argv
- * - with std handles set to in, out, err
- * - flags are passed to CreateProcess call
- * 
- * cmd will be internally decoarated with a set of '"'
- * to account for any spaces within the commandline
- * this decoration is done only when additional arguments are passed in argv
- */
-int
-spawn_child(char* cmd, char** argv, int in, int out, int err, DWORD flags)
-{
-	PROCESS_INFORMATION pi;
-	STARTUPINFOW si;
-	BOOL b;
-	char *cmdline, *t, **t1;
-	DWORD cmdline_len = 0;
-	wchar_t * cmdline_utf16;
-	int add_module_path = 0, ret = -1;
-
-	/* should module path be added */
-	do {
-		if (!cmd)
-			break;
-		t = cmd;
-		if (*t == '\"')
-			t++;
-		if (t[0] == '\0' || t[0] == '\\' || t[0] == '.' || t[1] == ':')
-			break;
-		add_module_path = 1;
-	} while (0);
-
-	/* compute total cmdline len*/
-	if (add_module_path)
-		cmdline_len += strlen(w32_programdir()) + 1 + strlen(cmd) + 1 + 2;
-	else
-		cmdline_len += strlen(cmd) + 1 + 2;
-
-	if (argv) {
-		t1 = argv;
-		while (*t1)
-			cmdline_len += strlen(*t1++) + 1 + 2;
-	}
-
-	if ((cmdline = malloc(cmdline_len)) == NULL) {
-		errno = ENOMEM;
-		goto cleanup;
-	}
-
-	/* add current module path to start if needed */
-	t = cmdline;
-	if (argv && argv[0])
-		*t++ = '\"';
-	if (add_module_path) {
-		memcpy(t, w32_programdir(), strlen(w32_programdir()));
-		t += strlen(w32_programdir());
-		*t++ = '\\';
-	}
-	
-	memcpy(t, cmd, strlen(cmd));
-	t += strlen(cmd);
-
-	if (argv && argv[0])
-		*t++ = '\"';
-
-	if (argv) {
-		t1 = argv;
-		while (*t1) {
-			*t++ = ' ';
-			*t++ = '\"';
-			memcpy(t, *t1, strlen(*t1));
-			t += strlen(*t1);
-			*t++ = '\"';
-			t1++;
-		}
-	}
-
-	*t = '\0';
-
-	if ((cmdline_utf16 = utf8_to_utf16(cmdline)) == NULL) {
-		errno = ENOMEM;
-		goto cleanup;
-	}
-
-	memset(&si, 0, sizeof(STARTUPINFOW));
-	si.cb = sizeof(STARTUPINFOW);
-	si.hStdInput = w32_fd_to_handle(in);
-	si.hStdOutput = w32_fd_to_handle(out);
-	si.hStdError = w32_fd_to_handle(err);
-	si.dwFlags = STARTF_USESTDHANDLES;
-
-	debug3("spawning %ls", cmdline_utf16);
-	b = CreateProcessW(NULL, cmdline_utf16, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi);
-
-	if (b) {
-		if (register_child(pi.hProcess, pi.dwProcessId) == -1) {
-			TerminateProcess(pi.hProcess, 0);
-			CloseHandle(pi.hProcess);
-			goto cleanup;
-		}
-		CloseHandle(pi.hThread);
-	} else {
-		errno = GetLastError();
-		goto cleanup;
-	}
-
-	ret = pi.dwProcessId;
-cleanup:
-	if (cmdline)
-		free(cmdline);
-	if (cmdline_utf16)
-		free(cmdline_utf16);
-
-	return ret;
-}
-
 void
 strmode(mode_t mode, char *p)
 {
diff --git a/contrib/win32/win32compat/misc_internal.h b/contrib/win32/win32compat/misc_internal.h
index 6150de03..fa9a0d7b 100644
--- a/contrib/win32/win32compat/misc_internal.h
+++ b/contrib/win32/win32compat/misc_internal.h
@@ -1,5 +1,8 @@
 #pragma once
 #define PATH_MAX MAX_PATH
+#define SSH_ASYNC_STDIN "SSH_ASYNC_STDIN"
+#define SSH_ASYNC_STDOUT "SSH_ASYNC_STDOUT"
+#define SSH_ASYNC_STDERR "SSH_ASYNC_STDERR"
 
 /* removes first '/' for Windows paths that are unix styled. Ex: /c:/ab.cd */
 char * sanitized_path(const char *);
diff --git a/contrib/win32/win32compat/signal.c b/contrib/win32/win32compat/signal.c
index 035f79ce..d0499031 100644
--- a/contrib/win32/win32compat/signal.c
+++ b/contrib/win32/win32compat/signal.c
@@ -78,7 +78,7 @@ sigtstp_APCProc(_In_ ULONG_PTR dwParam)
 BOOL WINAPI
 native_sig_handler(DWORD dwCtrlType)
 {
-	debug3("Native Ctrl+C handler, CtrlType %d", dwCtrlType);
+	debug4("Native Ctrl+C handler, CtrlType %d", dwCtrlType);
 	switch (dwCtrlType) {
 	case CTRL_C_EVENT:
 		QueueUserAPC(sigint_APCProc, main_thread, (ULONG_PTR)NULL);
@@ -154,7 +154,7 @@ w32_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
 int
 w32_raise(int sig)
 {
-	debug3("raise sig:%d", sig);
+	debug4("raise sig:%d", sig);
 	if (sig == W32_SIGSEGV)
 		return raise(SIGSEGV); /* raise native exception handler*/
 
@@ -229,7 +229,7 @@ sw_process_pending_signals()
 		DebugBreak();
 
 	if (sig_int) {
-		debug3("process_queued_signals: WARNING - A signal has interrupted and was processed");
+		debug4("process_queued_signals: WARNING - A signal has interrupted and was processed");
 		errno = EINTR;
 		return -1;
 	}
diff --git a/contrib/win32/win32compat/socketio.c b/contrib/win32/win32compat/socketio.c
index f935fe35..5e9d6621 100644
--- a/contrib/win32/win32compat/socketio.c
+++ b/contrib/win32/win32compat/socketio.c
@@ -104,12 +104,20 @@ int
 socketio_acceptEx(struct w32_io* pio)
 {
 	struct acceptEx_context *context;
+	struct sockaddr_storage addr; int addrlen = sizeof addr;
+	
 	debug5("acceptEx - io:%p", pio);
 	context = (struct acceptEx_context *)pio->internal.context;
 	ResetEvent(pio->read_overlapped.hEvent);
 
+	if (getsockname(pio->sock, (struct sockaddr*)&addr, &addrlen) == SOCKET_ERROR) {
+		errno = errno_from_WSALastError();
+		debug("acceptEx - getsockname() ERROR:%d, io:%p", errno, pio);
+		return -1;		
+	}
+
 	/* create accepting socket */
-	context->accept_socket = socket(AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
+	context->accept_socket = socket(addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
 	if (context->accept_socket == INVALID_SOCKET) {
 		errno = errno_from_WSALastError();
 		debug3("acceptEx - socket() ERROR:%d, io:%p", errno, pio);
diff --git a/contrib/win32/win32compat/ssh-agent/authagent-request.c b/contrib/win32/win32compat/ssh-agent/authagent-request.c
index 0fd765eb..291f332f 100644
--- a/contrib/win32/win32compat/ssh-agent/authagent-request.c
+++ b/contrib/win32/win32compat/ssh-agent/authagent-request.c
@@ -127,7 +127,7 @@ generate_user_token(wchar_t* user_cpn) {
 	if (domain_user)
 		InitLsaString(&auth_package_name, MICROSOFT_KERBEROS_NAME_A);
 	else
-		InitLsaString(&auth_package_name, "SSH-LSA");
+		InitLsaString(&auth_package_name, MSV1_0_PACKAGE_NAME);
 
 	InitLsaString(&originName, "sshd");
 	if (ret = LsaRegisterLogonProcess(&logon_process_name, &lsa_handle, &mode) != STATUS_SUCCESS)
@@ -154,11 +154,24 @@ generate_user_token(wchar_t* user_cpn) {
 		s4u_logon->ClientRealm.MaximumLength = 0;
 		s4u_logon->ClientRealm.Buffer = 0;
 	} else {
-		logon_info_size = (wcslen(user_cpn) + 1)*sizeof(wchar_t);
+		MSV1_0_S4U_LOGON *s4u_logon;
+		logon_info_size = sizeof(MSV1_0_S4U_LOGON);
+		/* additional buffer size = size of user_cpn + size of "." and their null terminators */
+		logon_info_size += (wcslen(user_cpn) * 2 + 2) + 4;
 		logon_info = malloc(logon_info_size);
 		if (logon_info == NULL)
 			goto done;
-		memcpy(logon_info, user_cpn, logon_info_size);
+		s4u_logon = (MSV1_0_S4U_LOGON*)logon_info;
+		s4u_logon->MessageType = MsV1_0S4ULogon;
+		s4u_logon->Flags = 0;
+		s4u_logon->UserPrincipalName.Length = wcslen(user_cpn) * 2;
+		s4u_logon->UserPrincipalName.MaximumLength = s4u_logon->UserPrincipalName.Length;
+		s4u_logon->UserPrincipalName.Buffer = (WCHAR*)(s4u_logon + 1);
+		memcpy(s4u_logon->UserPrincipalName.Buffer, user_cpn, s4u_logon->UserPrincipalName.Length + 2);
+		s4u_logon->DomainName.Length = 2;
+		s4u_logon->DomainName.MaximumLength = 2;
+		s4u_logon->DomainName.Buffer = ((WCHAR*)s4u_logon->UserPrincipalName.Buffer) + wcslen(user_cpn) + 1;
+		memcpy(s4u_logon->DomainName.Buffer, L".", 4);
 	}
 
 	memcpy(sourceContext.SourceName,"sshagent", sizeof(sourceContext.SourceName));
@@ -180,7 +193,7 @@ generate_user_token(wchar_t* user_cpn) {
 		&token,
 		&quotas,
 		&subStatus) != STATUS_SUCCESS) {
-		debug("LsaLogonUser failed %d", ret);
+		debug("LsaLogonUser failed NTSTATUS: %d", ret);
 		goto done;
 	}
 	debug3("LsaLogonUser succeeded");
@@ -265,7 +278,7 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response,
 	char *key_blob, *user, *sig, *blob;
 	size_t key_blob_len, user_len, sig_len, blob_len;
 	struct sshkey *key = NULL;
-	HANDLE token = NULL, restricted_token = NULL, dup_token = NULL, client_proc = NULL;
+	HANDLE token = NULL, dup_token = NULL, client_proc = NULL;
 	wchar_t *user_utf16 = NULL, *udom_utf16 = NULL, *tmp;
 	PWSTR wuser_home = NULL;
 	ULONG client_pid;
@@ -292,14 +305,8 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response,
 		goto done;
 	}
 
-	/* for key based auth, remove SeTakeOwnershipPrivilege */
-	if (LookupPrivilegeValueW(NULL, L"SeTakeOwnershipPrivilege", &priv_to_delete[0].Luid) == FALSE ||
-	    CreateRestrictedToken(token, 0, 0, NULL, 1, priv_to_delete, 0, NULL, &restricted_token) == FALSE) {
-		debug("unable to remove SeTakeOwnershipPrivilege privilege");
-		goto done;
-	}
 	
-	if (SHGetKnownFolderPath(&FOLDERID_Profile, 0, restricted_token, &wuser_home) != S_OK ||
+	if (SHGetKnownFolderPath(&FOLDERID_Profile, 0, token, &wuser_home) != S_OK ||
 	    pubkey_allowed(key, user_utf16, wuser_home) != 1) {
 		debug("unable to verify public key for user %ls (profile:%ls)", user_utf16, wuser_home);
 		goto done;
@@ -312,14 +319,14 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response,
 
 	if ((FALSE == GetNamedPipeClientProcessId(con->connection, &client_pid)) ||
 	    ( (client_proc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, client_pid)) == NULL) ||
-	    (FALSE == DuplicateHandle(GetCurrentProcess(), restricted_token, client_proc, &dup_token, TOKEN_QUERY | TOKEN_IMPERSONATE, FALSE, DUPLICATE_SAME_ACCESS)) ||
+	    (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;
 	}
 
-	con->auth_token = restricted_token; 
-	restricted_token = NULL;
+	con->auth_token = token; 
+	token = NULL;
 	if ((tmp = wcschr(user_utf16, L'@')) != NULL) {
 		udom_utf16 = tmp + 1;
 		*tmp = L'\0';
diff --git a/contrib/win32/win32compat/termio.c b/contrib/win32/win32compat/termio.c
index 33ed14ef..945e227b 100644
--- a/contrib/win32/win32compat/termio.c
+++ b/contrib/win32/win32compat/termio.c
@@ -9,6 +9,10 @@
  * Author: Balu <bagajjal@microsoft.com>
  *  Misc fixes and code cleanup
  *
+ * Author: Manoj Ampalam <manojamp@microsoft.com>
+ *  Extended support to other Windows IO that does not support 
+ *  overlapped IO. Ex. pipe handles returned by CreatePipe()
+ * 
  * Copyright (c) 2017 Microsoft Corp.
  * All rights reserved
  *
@@ -71,18 +75,26 @@ ReadAPCProc(_In_ ULONG_PTR dwParam)
 
 /* Read worker thread */
 static DWORD WINAPI
-ReadConsoleThread(_In_ LPVOID lpParameter)
+ReadThread(_In_ LPVOID lpParameter)
 {
 	int nBytesReturned = 0;
 	struct w32_io* pio = (struct w32_io*)lpParameter;
 
 	debug5("TermRead thread, io:%p", pio);
 	memset(&read_status, 0, sizeof(read_status));
-	while (nBytesReturned == 0) {
-		nBytesReturned = ReadConsoleForTermEmul(WINHANDLE(pio),
-			pio->read_details.buf, pio->read_details.buf_size);
+	if (FILETYPE(pio) == FILE_TYPE_CHAR) {
+		while (nBytesReturned == 0) {
+			nBytesReturned = ReadConsoleForTermEmul(WINHANDLE(pio),
+				pio->read_details.buf, pio->read_details.buf_size);
+		}
+		read_status.transferred = nBytesReturned;
+	} else {
+		if (!ReadFile(WINHANDLE(pio), pio->read_details.buf,
+		    pio->read_details.buf_size, &read_status.transferred, NULL)) {
+			read_status.error = GetLastError();
+			debug("ReadThread - ReadFile failed %d, io:%p", GetLastError(), pio);
+		}
 	}
-	read_status.transferred = nBytesReturned;
 	if (0 == QueueUserAPC(ReadAPCProc, main_thread, (ULONG_PTR)pio)) {
 		debug3("TermRead thread - ERROR QueueUserAPC failed %d, io:%p", GetLastError(), pio);
 		pio->read_details.pending = FALSE;
@@ -95,11 +107,11 @@ ReadConsoleThread(_In_ LPVOID lpParameter)
 
 /* Initiates read on tty */
 int
-termio_initiate_read(struct w32_io* pio)
+syncio_initiate_read(struct w32_io* pio)
 {
 	HANDLE read_thread;
 
-	debug5("TermRead initiate io:%p", pio);
+	debug5("syncio_initiate_read io:%p", pio);
 	if (pio->read_details.buf_size == 0) {
 		pio->read_details.buf = malloc(TERM_IO_BUF_SIZE);
 		if (pio->read_details.buf == NULL) {
@@ -109,7 +121,7 @@ termio_initiate_read(struct w32_io* pio)
 		pio->read_details.buf_size = TERM_IO_BUF_SIZE;
 	}
 
-	read_thread = CreateThread(NULL, 0, ReadConsoleThread, pio, 0, NULL);
+	read_thread = CreateThread(NULL, 0, ReadThread, pio, 0, NULL);
 	if (read_thread == NULL) {
 		errno = errno_from_Win32Error(GetLastError());
 		debug3("TermRead initiate - ERROR CreateThread %d, io:%p", GetLastError(), pio);
@@ -148,19 +160,26 @@ WriteThread(_In_ LPVOID lpParameter)
 	size_t resplen = 0;	
 	debug5("TermWrite thread, io:%p", pio);
 
-	pio->write_details.buf[write_status.to_transfer] = '\0';
-	
-	if (0 == in_raw_mode) {
-		wchar_t* t = utf8_to_utf16(pio->write_details.buf);
-		WriteConsoleW(WINHANDLE(pio), t, wcslen(t), 0, 0);
-		free(t);		
+	if (FILETYPE(pio) == FILE_TYPE_CHAR) {
+		pio->write_details.buf[write_status.to_transfer] = '\0';
+		if (0 == in_raw_mode) {
+			wchar_t* t = utf8_to_utf16(pio->write_details.buf);
+			WriteConsoleW(WINHANDLE(pio), t, wcslen(t), 0, 0);
+			free(t);		
+		} else {
+			processBuffer(WINHANDLE(pio), pio->write_details.buf, write_status.to_transfer, &respbuf, &resplen);
+			/* TODO - respbuf is not null in some cases, this needs to be returned back via read stream */
+		}
+		write_status.transferred = write_status.to_transfer;
 	} else {
-		processBuffer(WINHANDLE(pio), pio->write_details.buf, write_status.to_transfer, &respbuf, &resplen);
-		/* TODO - respbuf is not null in some cases, this needs to be returned back via read stream */
+		if (!WriteFile(WINHANDLE(pio), pio->write_details.buf, write_status.to_transfer,
+		    &write_status.transferred, NULL)) {
+			write_status.error = GetLastError();
+			debug("WriteThread - ReadFile WriteFile %d, io:%p", GetLastError(), pio);
+		}
 	}
 
-	write_status.transferred = write_status.to_transfer;
-
+	
 	if (0 == QueueUserAPC(WriteAPCProc, main_thread, (ULONG_PTR)pio)) {
 		debug3("TermWrite thread - ERROR QueueUserAPC failed %d, io:%p", GetLastError(), pio);
 		pio->write_details.pending = FALSE;
@@ -173,7 +192,7 @@ WriteThread(_In_ LPVOID lpParameter)
 
 /* Initiates write on tty */
 int
-termio_initiate_write(struct w32_io* pio, DWORD num_bytes)
+syncio_initiate_write(struct w32_io* pio, DWORD num_bytes)
 {
 	HANDLE write_thread;
 	debug5("TermWrite initiate io:%p", pio);
@@ -193,21 +212,27 @@ termio_initiate_write(struct w32_io* pio, DWORD num_bytes)
 
 /* tty close */
 int 
-termio_close(struct w32_io* pio)
+syncio_close(struct w32_io* pio)
 {
-	debug4("termio_close - pio:%p", pio);
+	debug4("syncio_close - pio:%p", pio);
 	HANDLE h;
 	CancelIoEx(WINHANDLE(pio), NULL);
-	/* If io is pending, let write worker threads exit. The read thread is blocked so terminate it.*/
-	if (pio->read_details.pending)
-		TerminateThread(pio->read_overlapped.hEvent, 0);
+
+	/* If io is pending, let worker threads exit. */
+	if (pio->read_details.pending) {
+		/* For console - the read thread is blocked so terminate it. */
+		if (FILETYPE(pio) == FILE_TYPE_CHAR)
+			TerminateThread(pio->read_overlapped.hEvent, 0);
+		else
+			WaitForSingleObject(pio->read_overlapped.hEvent, INFINITE);
+	}
 	if (pio->write_details.pending)
 		WaitForSingleObject(pio->write_overlapped.hEvent, INFINITE);
 	/* drain queued APCs */
 	SleepEx(0, TRUE);
-	if (pio->type != STD_IO_FD) {
-		/* STD handles are never explicitly closed */
-		CloseHandle(WINHANDLE(pio));
+	CloseHandle(WINHANDLE(pio));
+	/* free up if non stdio */
+	if (!IS_STDIO(pio)) {
 		if (pio->read_details.buf)
 			free(pio->read_details.buf);
 		if (pio->write_details.buf)
diff --git a/contrib/win32/win32compat/ttymodes_windows.c b/contrib/win32/win32compat/ttymodes_windows.c
index 6d8db1fd..4171d49c 100644
--- a/contrib/win32/win32compat/ttymodes_windows.c
+++ b/contrib/win32/win32compat/ttymodes_windows.c
@@ -24,7 +24,7 @@
 
 #include "includes.h"
 
-#include <sys/types.h>
+#include "inc/sys/types.h"
 
 #include <errno.h>
 #include <string.h>
diff --git a/contrib/win32/win32compat/w32fd.c b/contrib/win32/win32compat/w32fd.c
index 4e48f964..3921fd44 100644
--- a/contrib/win32/win32compat/w32fd.c
+++ b/contrib/win32/win32compat/w32fd.c
@@ -36,6 +36,7 @@
 #include "inc\unistd.h"
 #include "inc\fcntl.h"
 #include "inc\sys\un.h"
+#include "inc\utf.h"
 
 #include "w32fd.h"
 #include "signal_internal.h"
@@ -74,15 +75,24 @@ fd_table_initialize()
 	memset(&fd_table, 0, sizeof(fd_table));
 	memset(&w32_io_stdin, 0, sizeof(w32_io_stdin));
 	w32_io_stdin.std_handle = STD_INPUT_HANDLE;
-	w32_io_stdin.type = STD_IO_FD;
+	w32_io_stdin.type = NONSOCK_SYNC_FD;
+	if (getenv(SSH_ASYNC_STDIN) && strcmp(getenv(SSH_ASYNC_STDIN), "1") == 0)
+		w32_io_stdin.type = NONSOCK_FD;
+	_putenv_s(SSH_ASYNC_STDIN, "");
 	fd_table_set(&w32_io_stdin, STDIN_FILENO);
 	memset(&w32_io_stdout, 0, sizeof(w32_io_stdout));
 	w32_io_stdout.std_handle = STD_OUTPUT_HANDLE;
-	w32_io_stdout.type = STD_IO_FD;
+	w32_io_stdout.type = NONSOCK_SYNC_FD;
+	if (getenv(SSH_ASYNC_STDOUT) && strcmp(getenv(SSH_ASYNC_STDOUT), "1") == 0)
+		w32_io_stdout.type = NONSOCK_FD;
+	_putenv_s(SSH_ASYNC_STDOUT, "");
 	fd_table_set(&w32_io_stdout, STDOUT_FILENO);
 	memset(&w32_io_stderr, 0, sizeof(w32_io_stderr));
 	w32_io_stderr.std_handle = STD_ERROR_HANDLE;
-	w32_io_stderr.type = STD_IO_FD;
+	w32_io_stderr.type = NONSOCK_SYNC_FD;
+	if (getenv(SSH_ASYNC_STDERR) && strcmp(getenv(SSH_ASYNC_STDERR), "1") == 0)
+		w32_io_stderr.type = NONSOCK_FD;
+	_putenv_s(SSH_ASYNC_STDERR, "");
 	fd_table_set(&w32_io_stderr, STDERR_FILENO);
 	return 0;
 }
@@ -128,7 +138,6 @@ fd_table_set(struct w32_io* pio, int index)
 static void
 fd_table_clear(int index)
 {
-	fd_table.w32_ios[index]->table_index = -1;
 	fd_table.w32_ios[index] = NULL;
 	FD_CLR(index, &(fd_table.occupied));
 }
@@ -483,6 +492,7 @@ int
 w32_close(int fd)
 {
 	struct w32_io* pio;
+	int r;
 	if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
 		errno = EBADF;
 		return -1;
@@ -492,17 +502,14 @@ w32_close(int fd)
 
 	debug3("close - io:%p, type:%d, fd:%d, table_index:%d", pio, pio->type, fd,
 		pio->table_index);
-	fd_table_clear(pio->table_index);
-
+	
 	if (pio->type == SOCK_FD)
-		return socketio_close(pio);
+		r = socketio_close(pio);
 	else
-		switch (FILETYPE(pio)) {
-		case FILE_TYPE_CHAR:
-			return termio_close(pio);
-		default:
-			return fileio_close(pio);
-		}
+		r = fileio_close(pio);		
+
+	fd_table_clear(fd);
+	return r;
 }
 
 static int
@@ -798,7 +805,7 @@ w32_dup(int oldfd)
 
 	memset(pio, 0, sizeof(struct w32_io));
 	pio->handle = target;
-	pio->type = NONSOCK_FD;
+	pio->type = fd_table.w32_ios[oldfd]->type;
 	fd_table_set(pio, min_index);
 	return min_index;
 }
@@ -866,3 +873,131 @@ w32_fsync(int fd)
 	CHECK_FD(fd);
 	return FlushFileBuffers(w32_fd_to_handle(fd));
 }
+
+
+/*
+* spawn a child process
+* - specified by cmd with agruments argv
+* - with std handles set to in, out, err
+* - flags are passed to CreateProcess call
+*
+* cmd will be internally decoarated with a set of '"'
+* to account for any spaces within the commandline
+* this decoration is done only when additional arguments are passed in argv
+*/
+int
+spawn_child(char* cmd, char** argv, int in, int out, int err, DWORD flags)
+{
+	PROCESS_INFORMATION pi;
+	STARTUPINFOW si;
+	BOOL b;
+	char *cmdline, *t, **t1;
+	DWORD cmdline_len = 0;
+	wchar_t * cmdline_utf16;
+	int add_module_path = 0, ret = -1;
+
+	/* should module path be added */
+	do {
+		if (!cmd)
+			break;
+		t = cmd;
+		if (*t == '\"')
+			t++;
+		if (t[0] == '\0' || t[0] == '\\' || t[0] == '.' || t[1] == ':')
+			break;
+		add_module_path = 1;
+	} while (0);
+
+	/* compute total cmdline len*/
+	if (add_module_path)
+		cmdline_len += strlen(w32_programdir()) + 1 + strlen(cmd) + 1 + 2;
+	else
+		cmdline_len += strlen(cmd) + 1 + 2;
+
+	if (argv) {
+		t1 = argv;
+		while (*t1)
+			cmdline_len += strlen(*t1++) + 1 + 2;
+	}
+
+	if ((cmdline = malloc(cmdline_len)) == NULL) {
+		errno = ENOMEM;
+		goto cleanup;
+	}
+
+	/* add current module path to start if needed */
+	t = cmdline;
+	if (argv && argv[0])
+		*t++ = '\"';
+	if (add_module_path) {
+		memcpy(t, w32_programdir(), strlen(w32_programdir()));
+		t += strlen(w32_programdir());
+		*t++ = '\\';
+	}
+
+	memcpy(t, cmd, strlen(cmd));
+	t += strlen(cmd);
+
+	if (argv && argv[0])
+		*t++ = '\"';
+
+	if (argv) {
+		t1 = argv;
+		while (*t1) {
+			*t++ = ' ';
+			*t++ = '\"';
+			memcpy(t, *t1, strlen(*t1));
+			t += strlen(*t1);
+			*t++ = '\"';
+			t1++;
+		}
+	}
+
+	*t = '\0';
+
+	if ((cmdline_utf16 = utf8_to_utf16(cmdline)) == NULL) {
+		errno = ENOMEM;
+		goto cleanup;
+	}
+
+	memset(&si, 0, sizeof(STARTUPINFOW));
+	si.cb = sizeof(STARTUPINFOW);
+	si.hStdInput = w32_fd_to_handle(in);
+	si.hStdOutput = w32_fd_to_handle(out);
+	si.hStdError = w32_fd_to_handle(err);
+	si.dwFlags = STARTF_USESTDHANDLES;
+
+	debug3("spawning %ls", cmdline_utf16);
+	if (fd_table.w32_ios[in]->type != NONSOCK_SYNC_FD)
+		_putenv_s(SSH_ASYNC_STDIN, "1");
+	if (fd_table.w32_ios[out]->type != NONSOCK_SYNC_FD)
+		_putenv_s(SSH_ASYNC_STDOUT, "1");
+	if (fd_table.w32_ios[err]->type != NONSOCK_SYNC_FD)
+		_putenv_s(SSH_ASYNC_STDERR, "1");
+	b = CreateProcessW(NULL, cmdline_utf16, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi);
+	_putenv_s(SSH_ASYNC_STDIN, "");
+	_putenv_s(SSH_ASYNC_STDOUT, "");
+	_putenv_s(SSH_ASYNC_STDERR, "");
+
+	if (b) {
+		if (register_child(pi.hProcess, pi.dwProcessId) == -1) {
+			TerminateProcess(pi.hProcess, 0);
+			CloseHandle(pi.hProcess);
+			goto cleanup;
+		}
+		CloseHandle(pi.hThread);
+	}
+	else {
+		errno = GetLastError();
+		goto cleanup;
+	}
+
+	ret = pi.dwProcessId;
+cleanup:
+	if (cmdline)
+		free(cmdline);
+	if (cmdline_utf16)
+		free(cmdline_utf16);
+
+	return ret;
+}
diff --git a/contrib/win32/win32compat/w32fd.h b/contrib/win32/win32compat/w32fd.h
index 0387a00f..22f23592 100644
--- a/contrib/win32/win32compat/w32fd.h
+++ b/contrib/win32/win32compat/w32fd.h
@@ -39,7 +39,22 @@ enum w32_io_type {
 	UNKNOWN_FD = 0,
 	SOCK_FD = 1,	/*maps a socket fd*/
 	NONSOCK_FD = 2,	/*maps a file fd, pipe fd or a tty fd*/
-	STD_IO_FD = 5	/*maps a std fd - ex. STDIN_FILE*/
+	/*
+	 * maps a NONSOCK_FD that doesnt support async or overlapped io
+	 * these are typically used for stdio on ssh client side
+	 * executables (ssh, sftp and scp). 
+	 * Ex. ssh ... > output.txt
+	 *   In the above case, stdout passed to ssh.exe is a handle to 
+	 *   output.txt that is opened in non-overlapped mode
+	 * Ex. sample.exe | ssh ...
+	 *   In the above case, stdin passed to ssh.exe is a handle to
+	 *   a pipe opened in non-overlapped mode
+         * Ex. in Powershell
+	 * $o = ssh ...
+	 *   In the above case, stdout passed to ssh.exe is a handle to 
+	 *   a pipe opened in non-overlapped mode 
+	 */
+	NONSOCK_SYNC_FD = 3 
 };
 
 enum w32_io_sock_state {
@@ -51,7 +66,7 @@ enum w32_io_sock_state {
 };
 
 /*
-* This structure encapsulates the state info needed to map a File Descriptor
+* This structure encapsulates the I/O state info needed to map a File Descriptor
 * to Win32 Handle
 */
 struct w32_io {
@@ -94,7 +109,8 @@ struct w32_io {
 	}internal;
 };
 
-#define WINHANDLE(pio) (((pio)->type == STD_IO_FD)? GetStdHandle((pio)->std_handle):(pio)->handle)
+#define IS_STDIO(pio) ((pio)->table_index <= 2)
+#define WINHANDLE(pio) (IS_STDIO(pio)? GetStdHandle((pio)->std_handle):(pio)->handle)
 #define FILETYPE(pio) (GetFileType(WINHANDLE(pio)))
 extern HANDLE main_thread;
 
@@ -102,7 +118,7 @@ BOOL w32_io_is_blocking(struct w32_io*);
 BOOL w32_io_is_io_available(struct w32_io* pio, BOOL rd);
 int wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds);
 
-/*POSIX mimic'ing socket API*/
+/*POSIX mimic'ing socket API and socket helper API*/
 int socketio_initialize();
 int socketio_done();
 BOOL socketio_is_io_available(struct w32_io* pio, BOOL rd);
@@ -122,7 +138,7 @@ int socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags);
 int socketio_shutdown(struct w32_io* pio, int how);
 int socketio_close(struct w32_io* pio);
 
-/*POSIX mimic'ing file API*/
+/*POSIX mimic'ing file API and file helper API*/
 BOOL fileio_is_io_available(struct w32_io* pio, BOOL rd);
 void fileio_on_select(struct w32_io* pio, BOOL rd);
 int fileio_close(struct w32_io* pio);
@@ -136,45 +152,3 @@ int fileio_fstat(struct w32_io* pio, struct _stat64 *buf);
 int fileio_stat(const char *path, struct _stat64 *buf);
 long fileio_lseek(struct w32_io* pio, long offset, int origin);
 FILE* fileio_fdopen(struct w32_io* pio, const char *mode);
-
-/* terminal io specific versions */
-int termio_close(struct w32_io* pio);
-
-/*
-* open() flags and modes
-* all commented out macros are defined in fcntl.h
-* they are listed here so as to cross check any conflicts with macros explicitly
-* defined below.
-*/
-/*open access modes. only one of these can be specified*/
-/* #define O_RDONLY    0x0  */
-/* #define O_WRONLY    0x1 */
-/* #define O_RDWR      0x2 */
-/* open file creation and file status flags can be bitwise-or'd*/
-/* #define O_APPEND    0x8    /*file is opened in append mode*/
-#ifndef O_NONBLOCK
-#define O_NONBLOCK  0x0004    /*io operations wont block*/
-#endif
-/* #define O_CREAT     0x100   /*If the file does not exist it will be created*/
-/*
-* If the file exists and is a regular file, and the file is successfully
-* opened O_RDWR or O_WRONLY, its length shall be truncated to 0, and the mode
-* and owner shall be unchanged
-*/
-/* #define O_TRUNC     0x200    */
-/* If O_CREAT and O_EXCL are set, open() shall fail if the file exists */
-/* #define O_EXCL      0x400   */
-/* #define O_BINARY    0x8000   //Gives raw data (while O_TEXT normalises line endings */
-/* open modes */
-#ifndef  S_IRUSR
-#define S_IRUSR     00400   /* user has read permission */
-#endif /* ! S_IRUSR */
-#ifndef S_IWUSR
-#define S_IWUSR     00200   /* user has write permission */ 
-#endif
-#ifndef S_IRGRP
-#define S_IRGRP     00040   /* group has read permission  */
-#endif
-#ifndef S_IROTH
-#define S_IROTH     00004   /* others have read permission */
-#endif
\ No newline at end of file
diff --git a/contrib/win32/win32compat/w32log.c b/contrib/win32/win32compat/w32log.c
index 1df65d5b..327b366c 100644
--- a/contrib/win32/win32compat/w32log.c
+++ b/contrib/win32/win32compat/w32log.c
@@ -30,7 +30,7 @@
 #include <Windows.h>
 #include <io.h>
 #include <fcntl.h>
-#include <sys/stat.h>
+#include "inc/sys/stat.h"
 
 #include "inc\syslog.h"
 #include "misc_internal.h"
diff --git a/contrib/win32/win32compat/wmain_common.c b/contrib/win32/win32compat/wmain_common.c
index 3d09ceea..fb6ca8f1 100644
--- a/contrib/win32/win32compat/wmain_common.c
+++ b/contrib/win32/win32compat/wmain_common.c
@@ -52,8 +52,9 @@ wmain(int argc, wchar_t **wargv) {
 	if (getenv("SSH_AUTH_SOCK") == NULL)
 		_putenv("SSH_AUTH_SOCK=ssh-agent");
 
-        w32posix_initialize();
-        r = main(argc, argv);
-		w32posix_done();
-		return r;
+	w32posix_initialize();
+	
+	r = main(argc, argv);
+	w32posix_done();
+	return r;
 }
diff --git a/kex.c b/kex.c
index cf4ac0dc..98c0597a 100644
--- a/kex.c
+++ b/kex.c
@@ -54,14 +54,6 @@
 #include "sshbuf.h"
 #include "digest.h"
 
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L
-# if defined(HAVE_EVP_SHA256)
-# define evp_ssh_sha256 EVP_sha256
-# else
-extern const EVP_MD *evp_ssh_sha256(void);
-# endif
-#endif
-
 /* prototype */
 static int kex_choose_conf(struct ssh *);
 static int kex_input_newkeys(int, u_int32_t, void *);
diff --git a/openbsd-compat/fmt_scaled.c b/openbsd-compat/fmt_scaled.c
index e5533b2d..7c5193e2 100644
--- a/openbsd-compat/fmt_scaled.c
+++ b/openbsd-compat/fmt_scaled.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fmt_scaled.c,v 1.13 2017/03/11 23:37:23 djm Exp $	*/
+/*	$OpenBSD: fmt_scaled.c,v 1.16 2017/03/16 02:40:46 dtucker Exp $	*/
 
 /*
  * Copyright (c) 2001, 2002, 2003 Ian F. Darwin.  All rights reserved.
@@ -125,22 +125,30 @@ scan_scaled(char *scaled, long long *result)
 				/* ignore extra fractional digits */
 				continue;
 			fract_digits++;		/* for later scaling */
-			if (fpart >= LLONG_MAX / 10) {
+			if (fpart > LLONG_MAX / 10) {
 				errno = ERANGE;
 				return -1;
 			}
 			fpart *= 10;
+			if (i > LLONG_MAX - fpart) {
+				errno = ERANGE;
+				return -1;
+			}
 			fpart += i;
 		} else {				/* normal digit */
 			if (++ndigits >= MAX_DIGITS) {
 				errno = ERANGE;
 				return -1;
 			}
-			if (whole >= LLONG_MAX / 10) {
+			if (whole > LLONG_MAX / 10) {
 				errno = ERANGE;
 				return -1;
 			}
 			whole *= 10;
+			if (i > LLONG_MAX - whole) {
+				errno = ERANGE;
+				return -1;
+			}
 			whole += i;
 		}
 	}
@@ -170,7 +178,9 @@ scan_scaled(char *scaled, long long *result)
 			}
 			scale_fact = scale_factors[i];
 
-			if (whole >= LLONG_MAX / scale_fact) {
+			/* check for overflow and underflow after scaling */
+			if (whole > LLONG_MAX / scale_fact ||
+			    whole < LLONG_MIN / scale_fact) {
 				errno = ERANGE;
 				return -1;
 			}
diff --git a/regress/pesterTests/SSH.Tests.ps1 b/regress/pesterTests/SSH.Tests.ps1
index 58cb7a6e..74223bca 100644
--- a/regress/pesterTests/SSH.Tests.ps1
+++ b/regress/pesterTests/SSH.Tests.ps1
@@ -1,14 +1,30 @@
-#covered -i -q -v -l -c -C
+#todo: -i -q -v -l -c -C
 #todo: -S -F -V -e
-Describe "Tests for ssh command" -Tags "Scenario" {
+$tB = 1
+$tI = 0
+        
+Describe "ssh client tests" -Tags "CI" {
     BeforeAll {        
-        $fileName = "test.txt"
-        $filePath = Join-Path ${TestDrive} $fileName
+        if($OpenSSHTestInfo -eq $null)
+        {
+            Throw "`$OpenSSHTestInfo is null. Please run Setup-OpenSSHTestEnvironment to setup test environment."
+        }
+
+        if(-not (Test-Path $OpenSSHTestInfo["TestDataPath"]))
+        {
+            $null = New-Item $OpenSSHTestInfo["TestDataPath"] -ItemType directory -Force -ErrorAction SilentlyContinue
+        }
 
-        [Machine] $client = [Machine]::new([MachineRole]::Client)
-        [Machine] $server = [Machine]::new([MachineRole]::Server)
-        $client.SetupClient($server)
-        $server.SetupServer($client)
+        $server = $OpenSSHTestInfo["Target"]
+        $port = $OpenSSHTestInfo["Port"]
+        $ssouser = $OpenSSHTestInfo["SSOUser"]
+        $sshCmdDefault = "ssh -p $port $($ssouser)@$($server)"
+
+        $testDir = Join-Path $OpenSSHTestInfo["TestDataPath"] "ssh"
+        if(-not (Test-Path $testDir))
+        {
+            $null = New-Item $testDir -ItemType directory -Force -ErrorAction SilentlyContinue
+        }
 
         $testData = @(
             @{
@@ -55,12 +71,71 @@ Describe "Tests for ssh command" -Tags "Scenario" {
         
     }
 
-    AfterAll {
-        $client.CleanupClient()
-        $server.CleanupServer()
+    BeforeEach {
+        $tI++;
+        $tFile=Join-Path $testDir "$tB.$tI.txt"
+    }        
+
+    Context "$tB - Basic Scenarios" {
+        
+        BeforeAll {$tI=1}
+        AfterAll{$tB++}
+
+        <# these 2 tests dont work on AppVeyor that sniffs stderr channel
+        It "$tB.$tI - test version" {
+            iex "ssh -V 2> $tFile"
+            $tFile | Should Contain "OpenSSH_"
+        }
+
+        It "$tB.$tI - test help" {
+            iex "ssh -? 2> $tFile"
+            $tFile | Should Contain "usage: ssh"
+        }
+        #>
+
+        It "$tB.$tI - remote echo command" {
+            iex "$sshDefaultCmd echo 1234" | Should Be "1234"
+        }
+    }
+
+    Context "$tB - Redirection Scenarios" {
+        
+        BeforeAll {$tI=1}
+        AfterAll{$tB++}
+
+        It "$tB.$tI - stdout to file" {
+            iex "$sshDefaultCmd powershell get-process > $tFile"
+            $tFile | Should Contain "ProcessName"
+        }
+
+        It "$tB.$tI - stdout to PS object" {
+            $o = iex "$sshDefaultCmd echo 1234"
+            $o | Should Be "1234"
+        }
+
+        <#It "$tB.$tI - stdin from PS object" {
+            #if input redirection doesn't work, this would hang
+            0 | ssh -p $port $ssouser@$server pause
+            $true | Should Be $true
+        }#>
     }
 
-    Context "Key is not secured in ssh-agent on server" {
+    Context "$tB - cmdline parameters" {
+        
+        BeforeAll {$tI=1}
+        AfterAll{$tB++}
+
+        It "$tB.$tI - verbose to file" {
+            $logFile = Join-Path $testDir "$tB.$tI.log.txt"
+            $o = ssh -p $port -v -E $logFile $ssouser@$server echo 1234
+            $o | Should Be "1234"
+            #TODO - checks below are very inefficient (time taking). 
+            $logFile | Should Contain "OpenSSH_"
+            $logFile | Should Contain "Exit Status 0"
+        }
+
+    }
+    <#Context "Key is not secured in ssh-agent on server" {
         BeforeAll {            
             $identifyFile = $client.clientPrivateKeyPaths[0]
             Remove-Item -Path $filePath -Force -ea silentlycontinue
@@ -156,5 +231,5 @@ Describe "Tests for ssh command" -Tags "Scenario" {
            #validate file content.           
            Get-Content $filePath | Should be $server.MachineName           
         }
-    }
+    }#>
 }
diff --git a/session.c b/session.c
index 523acf4f..a689b27a 100644
--- a/session.c
+++ b/session.c
@@ -559,6 +559,10 @@ int do_exec_windows(Session *s, const char *command, int pty) {
 		debug("Executing command: %s", exec_command);
 		UTF8_TO_UTF16_FATAL(exec_command_w, exec_command);
 		
+		_putenv_s("SSH_ASYNC_STDIN", "1");
+		_putenv_s("SSH_ASYNC_STDOUT", "1");
+		_putenv_s("SSH_ASYNC_STDERR", "1");
+
 		/* in debug mode launch using sshd.exe user context */
 		if (debug_flag)
 			b = CreateProcessW(NULL, exec_command_w, NULL, NULL, TRUE,
@@ -569,6 +573,10 @@ int do_exec_windows(Session *s, const char *command, int pty) {
 				DETACHED_PROCESS , NULL, pw_dir_w,
 				&si, &pi);
 
+		_putenv_s("SSH_ASYNC_STDIN", "");
+		_putenv_s("SSH_ASYNC_STDOUT", "");
+		_putenv_s("SSH_ASYNC_STDERR", "");
+
 		if (!b)
 			fatal("ERROR. Cannot create process (%u).\n", GetLastError());
 		else if (pty) { /*attach to shell console */
diff --git a/sshd.c b/sshd.c
index 8f80bb58..b52ef567 100644
--- a/sshd.c
+++ b/sshd.c
@@ -233,6 +233,12 @@ int use_privsep = -1;
 #endif
 struct monitor *pmonitor = NULL;
 int privsep_is_preauth = 1;
+#ifdef WINDOWS
+/* Windows does not use Unix privilege separation model */
+static int privsep_chroot = 0;
+#else
+static int privsep_chroot = 1;
+#endif
 
 /* global authentication context */
 Authctxt *the_authctxt = NULL;
@@ -577,7 +583,7 @@ privsep_preauth_child(void)
 	demote_sensitive_data();
 
 	/* Demote the child */
-	if (getuid() == 0 || geteuid() == 0) {
+	if (privsep_chroot) {
 		/* Change our root directory */
 		if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1)
 			fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR,
@@ -1314,6 +1320,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
 					 * automatically be cleaned up on next iteration
 					 */
 					close(startup_p[1]);
+					free(path_utf8);
 					continue;
 				}
                 
@@ -1717,8 +1724,9 @@ main(int ac, char **av)
 
 #ifndef WINDOWS /* not applicable in Windows */
 	/* Store privilege separation user for later use if required. */
+	privsep_chroot = use_privsep && (getuid() == 0 || geteuid() == 0);
 	if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
-		if (use_privsep || options.kerberos_authentication)
+		if (privsep_chroot || options.kerberos_authentication)
 			fatal("Privilege separation user %s does not exist",
 			    SSH_PRIVSEP_USER);
 	} else {
@@ -1847,7 +1855,7 @@ main(int ac, char **av)
 		    key_type(key));
 	}
 
-	if (use_privsep) {
+	if (privsep_chroot) {
 		struct stat st;
 
 		if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) ||
diff --git a/sshkey.c b/sshkey.c
index 53a7674b..3c487849 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -3513,11 +3513,7 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
 	int success, r;
 	int blen, len = strlen(_passphrase);
 	u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
-#if (OPENSSL_VERSION_NUMBER < 0x00907000L)
-	const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
-#else
- 	const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
-#endif
+	const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
 	const u_char *bptr;
 	BIO *bio = NULL;