diff --git a/contrib/win32/openssh/OpenSSHBuildHelper.psm1 b/contrib/win32/openssh/OpenSSHBuildHelper.psm1
index 8f358c97f..a66aa2f33 100644
--- a/contrib/win32/openssh/OpenSSHBuildHelper.psm1
+++ b/contrib/win32/openssh/OpenSSHBuildHelper.psm1
@@ -301,7 +301,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-shellhost.exe", "ssh-keygen.exe", "ssh-keyscan.exe"
- $payload += "sshd_config", "install-sshd.ps1", "uninstall-sshd.ps1", "FixHostFilePermissions.ps1", "FixUserFilePermissions.ps1", "OpenSSHUtils.psm1"
+ $payload += "sshd_config", "install-sshd.ps1", "uninstall-sshd.ps1"
+ $payload +="FixHostFilePermissions.ps1", "FixUserFilePermissions.ps1", "OpenSSHUtils.psm1", "ssh-add-hostkey.ps1"
$packageName = "OpenSSH-Win64"
if ($NativeHostArch -eq 'x86') {
diff --git a/contrib/win32/openssh/OpenSSHTestHelper.psm1 b/contrib/win32/openssh/OpenSSHTestHelper.psm1
index 3c4f16467..40012037a 100644
--- a/contrib/win32/openssh/OpenSSHTestHelper.psm1
+++ b/contrib/win32/openssh/OpenSSHTestHelper.psm1
@@ -158,6 +158,8 @@ WARNING: Following changes will be made to OpenSSH configuration
# copy new sshd_config
Copy-Item (Join-Path $Script:E2ETestDirectory sshd_config) (Join-Path $script:OpenSSHBinPath sshd_config) -Force
+ Start-Service ssh-agent
+
#copy sshtest keys
Copy-Item "$($Script:E2ETestDirectory)\sshtest*hostkey*" $script:OpenSSHBinPath -Force
Get-ChildItem "$($script:OpenSSHBinPath)\sshtest*hostkey*"| % {
@@ -165,17 +167,11 @@ WARNING: Following changes will be made to OpenSSH configuration
(Get-Content $_.FullName -Raw).Replace("`r`n","`n") | Set-Content $_.FullName -Force
Adjust-HostKeyFileACL -FilePath $_.FullName
if (-not ($_.Name.EndsWith(".pub"))) {
- Add-PermissionToFileACL -FilePath $_.FullName -User "NT Service\sshd" -Perm "Read"
+ #register private key with agent
+ ssh-add-hostkey.ps1 $_.FullName
}
}
- #register host keys with agent
- <#Get-ChildItem "$($script:OpenSSHBinPath)\sshtest*hostkey*"| % {
- if (-not ($_.Name.EndsWith(".pub"))) {
- & "$env:ProgramData\chocolatey\lib\sysinternals\tools\psexec" -accepteula -nobanner -i -s -w $($script:OpenSSHBinPath) cmd.exe /c "ssh-add $_"
- Add-PermissionToFileACL -FilePath $_.FullName -User "NT Service\sshd" -Perm "Read"
- }
- }#>
Restart-Service sshd -Force
#Backup existing known_hosts and replace with test version
@@ -255,7 +251,6 @@ function Get-LocalUserProfile
.SYNOPSIS
This function installs the tools required by our tests
1) Pester for running the tests
- 2) sysinternals required by the tests on windows.
#>
function Install-OpenSSHTestDependencies
{
@@ -275,11 +270,6 @@ function Install-OpenSSHTestDependencies
Write-Log -Message "Installing Pester..."
choco install Pester -y --force --limitoutput 2>&1 >> $Script:TestSetupLogFile
}
-
- if ( -not (Test-Path "$env:ProgramData\chocolatey\lib\sysinternals\tools" ) ) {
- Write-Log -Message "sysinternals not present. Installing sysinternals."
- choco install sysinternals -y --force --limitoutput 2>&1 >> $Script:TestSetupLogFile
- }
}
<#
.Synopsis
@@ -309,26 +299,30 @@ function Get-UserSID
Cleanup-OpenSSHTestEnvironment
#>
function Cleanup-OpenSSHTestEnvironment
-{
+{
+ if($Global:OpenSSHTestInfo -eq $null) {
+ throw "OpenSSHTestInfo is not set. Did you run Setup-OpenSShTestEnvironment?"
+ }
+
+ $sshBinPath = $Global:OpenSSHTestInfo["OpenSSHBinPath"]
+
# .exe - Windows specific. TODO - PAL
- if (-not (Test-Path (Join-Path $script:OpenSSHBinPath ssh.exe) -PathType Leaf))
+ if (-not (Test-Path (Join-Path $sshBinPath ssh.exe) -PathType Leaf))
{
Throw "Cannot find OpenSSH binaries under $script:OpenSSHBinPath. "
}
-
+
#unregister test host keys from agent
- Get-ChildItem "$($script:OpenSSHBinPath)\sshtest*hostkey*.pub"| % {
- $cmd = "cmd /c `"$env:ProgramData\chocolatey\lib\sysinternals\tools\psexec -accepteula -nobanner -s -w $($script:OpenSSHBinPath) ssh-add -d $_ 2> tmp.txt`""
- iex $cmd
+ Get-ChildItem "$sshBinPath\sshtest*hostkey*.pub"| % {
+ ssh-add-hostkey.ps1 -Delete_key $_.FullName
}
-
+ Remove-Item $sshBinPath\sshtest*hostkey* -Force -ErrorAction SilentlyContinue
#Restore sshd_config
- $backupConfigPath = Join-Path $Script:OpenSSHBinPath sshd_config.ori
+ $backupConfigPath = Join-Path $sshBinPath sshd_config.ori
if (Test-Path $backupConfigPath -PathType Leaf) {
- Copy-Item $backupConfigPath (Join-Path $Script:OpenSSHBinPath sshd_config) -Force -ErrorAction SilentlyContinue
- Remove-Item (Join-Path $Script:OpenSSHBinPath sshd_config.ori) -Force -ErrorAction SilentlyContinue
- Remove-Item $Script:OpenSSHBinPath\sshtest*hostkey* -Force -ErrorAction SilentlyContinue
+ Copy-Item $backupConfigPath (Join-Path $sshBinPath sshd_config) -Force -ErrorAction SilentlyContinue
+ Remove-Item (Join-Path $sshBinPath sshd_config.ori) -Force -ErrorAction SilentlyContinue
Restart-Service sshd
}
diff --git a/contrib/win32/openssh/config.vcxproj b/contrib/win32/openssh/config.vcxproj
index 8b8245620..3087d5585 100644
--- a/contrib/win32/openssh/config.vcxproj
+++ b/contrib/win32/openssh/config.vcxproj
@@ -122,8 +122,9 @@
copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OutDir)
copy /Y $(SolutionDir)OpenSSHUtils.psm1 $(OutDir)
copy /Y $(SolutionDir)Fix*FilePermissions.ps1 $(OutDir)
+copy /Y $(SolutionDir)ssh-add-hostkey.ps1 $(OutDir)
If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))
- Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, and sshd_config (if not already present) to build directory
+ Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, ssh-add-hostkey.ps1, and sshd_config (if not already present) to build directory
@@ -154,8 +155,9 @@ If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))
- Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, and sshd_config (if not already present) to build directory
+ Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, ssh-add-hostkey.ps1, and sshd_config (if not already present) to build directory
@@ -190,8 +192,9 @@ If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))
- Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, and sshd_config (if not already present) to build directory
+ Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, ssh-add-hostkey.ps1, and sshd_config (if not already present) to build directory
@@ -226,8 +229,9 @@ If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))
- Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, and sshd_config (if not already present) to build directory
+ Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, ssh-add-hostkey.ps1, and sshd_config (if not already present) to build directory
diff --git a/contrib/win32/openssh/ssh-add-hostkey.ps1 b/contrib/win32/openssh/ssh-add-hostkey.ps1
new file mode 100644
index 000000000..ab03f2744
--- /dev/null
+++ b/contrib/win32/openssh/ssh-add-hostkey.ps1
@@ -0,0 +1,96 @@
+<#
+ Author: manoj.ampalam@microsoft.com
+
+ Description: ssh-add.exe like Powershell utility to do host key management.
+ Input parameter mimic ssh-add.exe cmdline arguments.
+
+ Host keys on Windows need to be registered as SYSTEM (i.e ssh-add.exe would
+ need to run as SYSTEM while talking to ssh-agent). This typically requires
+ an external utility like psexec.
+
+ This script tries to use the Task scheduler option:
+ - registers a task scheduler task to run ssh-add.exe operation as SYSTEM
+ - actual output of ssh-add.exe is written to file (both stdout and stderr)
+ - Dumps the file contents to console
+
+#>
+
+# see https://linux.die.net/man/1/ssh-add for what the arguments mean
+[CmdletBinding(DefaultParameterSetName='Add_key')]
+Param(
+ [Parameter(ParameterSetName="List_fingerprints")]
+ [switch]$List_fingerprints, #ssh-add -l
+ [Parameter(ParameterSetName="List_pubkeys")]
+ [switch]$List_pubkeys, #ssh-add -L
+ [Parameter(ParameterSetName="Delete_key")]
+ [switch]$Delete_key, #ssh-add -d
+ [Parameter(ParameterSetName="Delete_all")]
+ [switch]$Delete_all, #ssh-add -D
+ [Parameter(Mandatory, Position=0, ParameterSetName="Delete_key")]
+ [Parameter(Mandatory, Position=0, ParameterSetName="Add_key")]
+ [ValidateNotNullOrEmpty()]
+ [string]$key
+)
+
+$ssh_add_cmd = get-command ssh-add.exe -ErrorAction Ignore
+if($ssh_add_cmd -eq $null)
+{
+ Throw "Cannot find ssh-add.exe."
+}
+
+#create ssh-add cmdlinet
+$ssh_add_cmd_str = $ssh_add_cmd.Path
+if ($List_fingerprints) { $ssh_add_cmd_str += " -l" }
+elseif ($List_pubkeys) { $ssh_add_cmd_str += " -L" }
+elseif ($Delete_key) { $ssh_add_cmd_str += " -d $key" }
+elseif ($Delete_all) { $ssh_add_cmd_str += " -D" }
+else
+{
+ if ( ($key.Length -gt 0) -and (-not($key.Contains("host"))) ) {
+ Do {
+ $input = Read-Host -Prompt "Are you sure the provided key is a host key? [Yes] Y; [No] N (default is `"Y`")"
+ if([string]::IsNullOrEmpty($input))
+ {
+ $input = 'Y'
+ }
+ } until ($input -match "^(y(es)?|N(o)?)$")
+ $result = $Matches[0]
+ if (-not($result.ToLower().Startswith('y'))) { exit }
+ }
+ $ssh_add_cmd_str += " $key"
+}
+
+#globals
+$taskfolder = "\OpenSSHUtils\hostkey_tasks\"
+$taskname = "hostkey_task"
+$ssh_add_output = Join-Path (pwd).Path "ssh-add-hostkey-tmp.txt"
+$task_argument = "/c `"$ssh_add_cmd_str > $ssh_add_output 2>&1 `""
+
+#create TaskScheduler task
+$ac = New-ScheduledTaskAction -Execute "cmd.exe" -Argument $task_argument -WorkingDirectory (pwd).path
+$task = Register-ScheduledTask -TaskName $taskname -User System -Action $ac -TaskPath $taskfolder -Force
+
+#run the task
+if (Test-Path $ssh_add_output) {Remove-Item $ssh_add_output -Force}
+Start-ScheduledTask -TaskPath $taskfolder -TaskName $taskname
+
+#if still running, wait a little while for task to complete
+$num = 0
+while ((Get-ScheduledTask -TaskName $taskname -TaskPath $taskfolder).State -eq "Running")
+{
+ sleep 1
+ $num++
+ if($num -gt 20) { break }
+}
+if (-not(Test-Path $ssh_add_output)) {throw "cannot find task output file. Something went WRONG!!! "}
+
+#dump output to console
+Get-Content $ssh_add_output
+
+#cleanup task and output file
+Remove-Item $ssh_add_output -Force
+Unregister-ScheduledTask -TaskPath $taskfolder -TaskName $taskname -Confirm:$false
+
+
+
+