Removed dependency on sysinternals and psexec. Added PS utility for hostkey management

PowerShell/Win32-OpenSSH#755
This commit is contained in:
Manoj Ampalam 2017-06-06 14:45:10 -07:00 committed by GitHub
parent 3ec7a419ac
commit aa992ff908
4 changed files with 125 additions and 30 deletions

View File

@ -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') {

View File

@ -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
}

View File

@ -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))</Command>
<Message>Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, and sshd_config (if not already present) to build directory</Message>
<Message>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</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -154,8 +155,9 @@ If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))</C
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))</Command>
<Message>Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, and sshd_config (if not already present) to build directory</Message>
<Message>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</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -190,8 +192,9 @@ If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))</C
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))</Command>
<Message>Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, and sshd_config (if not already present) to build directory</Message>
<Message>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</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -226,8 +229,9 @@ If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))</C
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))</Command>
<Message>Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, and sshd_config (if not already present) to build directory</Message>
<Message>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</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -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