Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contrib/win32/openssh/OpenSSH-build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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')]
Expand Down
12 changes: 11 additions & 1 deletion contrib/win32/openssh/OpenSSHBuildHelper.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 <PlatformToolset>v143</PlatformToolset>,
# 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
}
Expand Down
46 changes: 44 additions & 2 deletions contrib/win32/openssh/README.txt
Original file line number Diff line number Diff line change
@@ -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.

Expand All @@ -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:

Expand Down
19 changes: 19 additions & 0 deletions contrib/win32/openssh/sshd-auth.vcxproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
<?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" />
<!-- sshd-auth is a privsep helper spawned by sshd as a different user and has
no desktop/window-station access. user32's DllMain binds to the process
window station and fails with STATUS_DLL_INIT_FAILED in restricted
environments (e.g. WinPE). Two mitigations: (1) add delayimp.lib and
delay-load user32 so its DLL is only loaded when a user32 API is
actually called, and (2) keep user32.lib (needed for the delay-load
thunks). sshd-auth only transitively references ShowWindow /
GetWindowPlacement from console.c's ConRestoreViewRect_NoPtyHack
helper, which sshd-auth does not execute, so in practice user32 is
never loaded. The ItemDefinitionGroup with /DELAYLOAD is placed after
Microsoft.Cpp.props (where the Link item type becomes defined). -->
<PropertyGroup>
<AdditionalDependentLibs>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</AdditionalDependentLibs>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
Expand Down Expand Up @@ -112,6 +126,11 @@
<VcpkgEnableManifest>true</VcpkgEnableManifest>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ItemDefinitionGroup>
<Link>
<AdditionalOptions>/DELAYLOAD:user32.dll %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
Expand Down
2 changes: 1 addition & 1 deletion contrib/win32/win32compat/win32_usertoken_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading