diff --git a/contrib/win32/openssh/OpenSSH-build.ps1 b/contrib/win32/openssh/OpenSSH-build.ps1 index 22c6794a84de..190387a45408 100644 --- a/contrib/win32/openssh/OpenSSH-build.ps1 +++ b/contrib/win32/openssh/OpenSSH-build.ps1 @@ -2,7 +2,7 @@ # PowerShell Script to clone, build and package PowerShell from specified fork and branch param ( [string] $repolocation = "$PSScriptRoot\..\..\..", - [string] $destination = "$env:WORKSPACE", + [string] $destination = $(if ($env:WORKSPACE) { $env:WORKSPACE } else { "$PSScriptRoot\..\..\.." }), [ValidateSet('x86', 'x64', 'arm64', 'arm')] [String]$NativeHostArch = 'x64', [ValidateSet('Debug', 'Release')] diff --git a/contrib/win32/openssh/OpenSSHBuildHelper.psm1 b/contrib/win32/openssh/OpenSSHBuildHelper.psm1 index 61a7c4502e13..88ca67f720b9 100644 --- a/contrib/win32/openssh/OpenSSHBuildHelper.psm1 +++ b/contrib/win32/openssh/OpenSSHBuildHelper.psm1 @@ -559,6 +559,11 @@ function Start-OpenSSHBuild $VisualStudioPath = Get-VisualStudioPath -NativeHostArch $NativeHostArch if ($null -ne $VisualStudioPath) { $msbuildCmd = Get-MSBuildPath -VSInstallPath $VisualStudioPath + # Pin vcpkg's CMake to the same VS install / toolset (v143) as the + # OpenSSH vcxproj files, so manifest-mode auto-install doesn't pick a + # newer VS (e.g. VS 2026) whose v14x toolset is unsupported here. + $env:VCPKG_VISUAL_STUDIO_PATH = $VisualStudioPath + $env:VCPKG_PLATFORM_TOOLSET = "v143" } else { $msbuildCmd = Get-VS2015BuildToolPath @@ -614,7 +619,12 @@ function Get-VisualStudioPath { $VSPaths = (& $vsWherePath -products * -requires $requiredVCtools -property installationPath) # for some reason, VSWhere does not seem to find MSBuild so check manually if ($null -ne $VSPaths) { - foreach ($VSPath in $VSPaths) { + # Prefer VS 2022 — the .vcxproj files pin v143, + # which ships with VS 2022. Older VS (2017=v141, 2019=v142) would need v143 build tools + # sideloaded; newer VS (e.g. 2026) defaults to v145 which isn't supported here. + $preferred = @($VSPaths | Where-Object { $_ -match '\\2022\\' }) + $ordered = $preferred + @($VSPaths | Where-Object { $_ -notmatch '\\2022\\' }) + foreach ($VSPath in $ordered) { if (Get-MSBuildPath -VSInstallPath $VSPath) { return $VSPath } diff --git a/contrib/win32/openssh/README.txt b/contrib/win32/openssh/README.txt index 14b250eb6d64..18eb6bed0649 100644 --- a/contrib/win32/openssh/README.txt +++ b/contrib/win32/openssh/README.txt @@ -1,4 +1,4 @@ -Custom paths for the visual studio projects are defined in paths.targets. +Custom paths for the visual studio projects are defined in paths.targets. All projects import this targets file, and it should be in the same directory as the project. @@ -10,12 +10,54 @@ OpenSSH-Lib-Path = The directory path of the location to which libra LibreSSL-x86-Path = The directory path of LibreSSL statically compiled for x86 platform. LibreSSL-x64-Path = The directory path of LibreSSL statically compiled for x64 platform. +Prerequisites +------------- + +Before building OpenSSH for Windows, install the following: + +1. Visual Studio 2022 (Community, Professional, or Build Tools). + Required components (Visual Studio Installer -> Modify): + - Workload: "Desktop development with C++" + This installs MSBuild, the v143 toolset, and the Windows 10/11 SDK. + - Individual component: "MSVC v143 - VS 2022 C++ x64/x86 Spectre-mitigated libs (Latest)" + Required because the vcpkg x64-custom triplet compiles + dependencies (LibreSSL, libfido2, zlib) with /Qspectre, which + demands matching Spectre-mitigated runtime libraries. + - For ARM64 builds, also install "MSVC v143 - VS 2022 C++ ARM64 Spectre-mitigated libs". + + Note: If a newer Visual Studio (e.g. VS 2026) is also installed, + OpenSSH-build.ps1 prefers VS 2022 and pins vcpkg's CMake to the + same install / v143 toolset automatically. + +2. Git for Windows. + The build script expects git.exe to be on PATH (it will add + "%ProgramFiles%\Git\cmd" to the machine PATH if missing). + +3. vcpkg (one-time bootstrap). + Dependencies (LibreSSL, libfido2, zlib, libcbor) are managed via a + vcpkg manifest (vcpkg.json). MSBuild auto-installs them at build + time, but vcpkg must be cloned, bootstrapped, and integrated first: + + git clone https://github.com/microsoft/vcpkg + cd vcpkg + .\bootstrap-vcpkg.bat + .\vcpkg.exe integrate install + + "vcpkg integrate install" registers vcpkg's MSBuild props user-wide; + after that, every OpenSSH-build.ps1 run picks up the manifest + automatically. No need to run "vcpkg install" manually. + +4. Administrator PowerShell. + The build script updates the machine PATH (to add Git / Chocolatey) + and may install the Windows SDK via Chocolatey if missing. Run the + build from an elevated PowerShell session. + Notes on FIDO2 support ---------------------- * How to build: - - Open Windows PowerShell. + - Open Windows PowerShell as Administrator. - Build OpenSSH for Windows: diff --git a/contrib/win32/openssh/sshd-auth.vcxproj b/contrib/win32/openssh/sshd-auth.vcxproj index fd3a28e06214..695afc0fb9dc 100644 --- a/contrib/win32/openssh/sshd-auth.vcxproj +++ b/contrib/win32/openssh/sshd-auth.vcxproj @@ -1,6 +1,20 @@ + + + bcrypt.lib;Userenv.lib;Crypt32.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;kernel32.lib;user32.lib;delayimp.lib;advapi32.lib;Netapi32.lib;Rpcrt4.lib;ntdll.lib + Debug @@ -112,6 +126,11 @@ true + + + /DELAYLOAD:user32.dll %(AdditionalOptions) + + diff --git a/contrib/win32/win32compat/win32_usertoken_utils.c b/contrib/win32/win32compat/win32_usertoken_utils.c index 2b8ede0d43c8..7d932c97603e 100644 --- a/contrib/win32/win32compat/win32_usertoken_utils.c +++ b/contrib/win32/win32compat/win32_usertoken_utils.c @@ -432,7 +432,7 @@ load_user_profile(HANDLE user_token, char* user) EnablePrivilege("SeBackupPrivilege", 1); EnablePrivilege("SeRestorePrivilege", 1); if (LoadUserProfileW(user_token, &profileInfo) == FALSE) { - debug3("%s: LoadUserProfileW() failed for user %S with error %d.", __FUNCTION__, GetLastError()); + debug3("%s: LoadUserProfileW() failed for user %S with error %d.", __FUNCTION__, user_name, GetLastError()); } EnablePrivilege("SeBackupPrivilege", 0); EnablePrivilege("SeRestorePrivilege", 0);