Fix issue install-sshd.ps1 failed on Nano, update it to match inbox manifest, and add setup and uninstall tests (#305)

1. Fix issue install-sshd.ps1 failed on Nano
2. Update settings of services in install-sshd.ps1 to match windows inbox
3. added setup tests and update the test helper scripts to run setup tests before changing configurations on the machine
4. added uninstallation tests
This commit is contained in:
Yanbing 2018-04-24 11:50:44 -07:00 committed by GitHub
parent 82aa56fe86
commit ec3eb7a088
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 931 additions and 104 deletions

View File

@ -16,11 +16,6 @@ after_build:
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1
Install-OpenSSH
before_test:
- ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1
Set-OpenSSHTestEnvironment -Confirm:$false
test_script:
- ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1

View File

@ -271,8 +271,10 @@ function Publish-Artifact
if($Global:OpenSSHTestInfo)
{
Add-Artifact -artifacts $artifacts -FileToAdd $Global:OpenSSHTestInfo["SetupTestResultsFile"]
Add-Artifact -artifacts $artifacts -FileToAdd $Global:OpenSSHTestInfo["UnitTestResultsFile"]
Add-Artifact -artifacts $artifacts -FileToAdd $Global:OpenSSHTestInfo["E2ETestResultsFile"]
Add-Artifact -artifacts $artifacts -FileToAdd $Global:OpenSSHTestInfo["UninstallTestResultsFile"]
Add-Artifact -artifacts $artifacts -FileToAdd $Global:OpenSSHTestInfo["TestSetupLogFile"]
}
@ -289,6 +291,27 @@ function Publish-Artifact
#>
function Invoke-OpenSSHTests
{
Set-BasicTestInfo -Confirm:$false
Invoke-OpenSSHSetupTest
if (($OpenSSHTestInfo -eq $null) -or (-not (Test-Path $OpenSSHTestInfo["SetupTestResultsFile"])))
{
Write-Warning "Test result file $OpenSSHTestInfo["SetupTestResultsFile"] not found after tests."
Write-BuildMessage -Message "Test result file $OpenSSHTestInfo["SetupTestResultsFile"] not found after tests." -Category Error
Set-BuildVariable TestPassed False
Write-Warning "Stop running further tests!"
return
}
$xml = [xml](Get-Content $OpenSSHTestInfo["SetupTestResultsFile"] | out-string)
if ([int]$xml.'test-results'.failures -gt 0)
{
$errorMessage = "$($xml.'test-results'.failures) setup tests in regress\pesterTests failed. Detail test log is at $($OpenSSHTestInfo["SetupTestResultsFile"])."
Write-Warning $errorMessage
Write-BuildMessage -Message $errorMessage -Category Error
Set-BuildVariable TestPassed False
Write-Warning "Stop running further tests!"
return
}
Write-Host "Start running unit tests"
$unitTestFailed = Invoke-OpenSSHUnitTest
@ -303,13 +326,17 @@ function Invoke-OpenSSHTests
Write-Host "All Unit tests passed!"
Write-BuildMessage -Message "All Unit tests passed!" -Category Information
}
# Run all E2E tests.
Set-OpenSSHTestEnvironment -Confirm:$false
Invoke-OpenSSHE2ETest
if (($OpenSSHTestInfo -eq $null) -or (-not (Test-Path $OpenSSHTestInfo["E2ETestResultsFile"])))
{
Write-Warning "Test result file $OpenSSHTestInfo["E2ETestResultsFile"] not found after tests."
Write-BuildMessage -Message "Test result file $OpenSSHTestInfo["E2ETestResultsFile"] not found after tests." -Category Error
Set-BuildVariable TestPassed False
Write-Warning "Stop running further tests!"
return
}
$xml = [xml](Get-Content $OpenSSHTestInfo["E2ETestResultsFile"] | out-string)
if ([int]$xml.'test-results'.failures -gt 0)
@ -318,6 +345,26 @@ function Invoke-OpenSSHTests
Write-Warning $errorMessage
Write-BuildMessage -Message $errorMessage -Category Error
Set-BuildVariable TestPassed False
Write-Warning "Stop running further tests!"
return
}
Invoke-OpenSSHUninstallTest
if (($OpenSSHTestInfo -eq $null) -or (-not (Test-Path $OpenSSHTestInfo["UninstallTestResultsFile"])))
{
Write-Warning "Test result file $OpenSSHTestInfo["UninstallTestResultsFile"] not found after tests."
Write-BuildMessage -Message "Test result file $OpenSSHTestInfo["UninstallTestResultsFile"] not found after tests." -Category Error
Set-BuildVariable TestPassed False
}
else {
$xml = [xml](Get-Content $OpenSSHTestInfo["UninstallTestResultsFile"] | out-string)
if ([int]$xml.'test-results'.failures -gt 0)
{
$errorMessage = "$($xml.'test-results'.failures) uninstall tests in regress\pesterTests failed. Detail test log is at $($OpenSSHTestInfo["UninstallTestResultsFile"])."
Write-Warning $errorMessage
Write-BuildMessage -Message $errorMessage -Category Error
Set-BuildVariable TestPassed False
}
}
# Writing out warning when the $Error.Count is non-zero. Tests Should clean $Error after success.
@ -335,11 +382,25 @@ function Publish-OpenSSHTestResults
{
if ($env:APPVEYOR_JOB_ID)
{
$resultFile = Resolve-Path $Global:OpenSSHTestInfo["E2ETestResultsFile"] -ErrorAction Ignore
if( (Test-Path $Global:OpenSSHTestInfo["E2ETestResultsFile"]) -and $resultFile)
$setupresultFile = Resolve-Path $Global:OpenSSHTestInfo["SetupTestResultsFile"] -ErrorAction Ignore
if( (Test-Path $Global:OpenSSHTestInfo["SetupTestResultsFile"]) -and $setupresultFile)
{
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", $resultFile)
Write-BuildMessage -Message "Test results uploaded!" -Category Information
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", $setupresultFile)
Write-BuildMessage -Message "Setup test results uploaded!" -Category Information
}
$E2EresultFile = Resolve-Path $Global:OpenSSHTestInfo["E2ETestResultsFile"] -ErrorAction Ignore
if( (Test-Path $Global:OpenSSHTestInfo["E2ETestResultsFile"]) -and $E2EresultFile)
{
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", $E2EresultFile)
Write-BuildMessage -Message "E2E test results uploaded!" -Category Information
}
$uninstallResultFile = Resolve-Path $Global:OpenSSHTestInfo["UninstallTestResultsFile"] -ErrorAction Ignore
if( (Test-Path $Global:OpenSSHTestInfo["UninstallTestResultsFile"]) -and $uninstallResultFile)
{
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", $uninstallResultFile)
Write-BuildMessage -Message "Uninstall test results uploaded!" -Category Information
}
}

View File

@ -5,6 +5,8 @@ Import-Module $PSScriptRoot\OpenSSHUtils -Force
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
# test environment parameters initialized with defaults
$SetupTestResultsFileName = "setupTestResults.xml"
$UninstallTestResultsFileName = "UninstallTestResults.xml"
$E2ETestResultsFileName = "E2ETestResults.xml"
$UnitTestResultsFileName = "UnitTestResults.txt"
$TestSetupLogFileName = "TestSetupLog.txt"
@ -16,6 +18,8 @@ $OpenSSHTestAccounts = $Script:SSOUser, $Script:PubKeyUser, $Script:PasswdUser
$OpenSSHConfigPath = Join-Path $env:ProgramData "ssh"
$Script:TestDataPath = "$env:SystemDrive\OpenSSHTests"
$Script:SetupTestResultsFile = Join-Path $TestDataPath $SetupTestResultsFileName
$Script:UninstallTestResultsFile = Join-Path $TestDataPath $UninstallTestResultsFileName
$Script:E2ETestResultsFile = Join-Path $TestDataPath $E2ETestResultsFileName
$Script:UnitTestResultsFile = Join-Path $TestDataPath $UnitTestResultsFileName
$Script:TestSetupLogFile = Join-Path $TestDataPath $TestSetupLogFileName
@ -42,100 +46,43 @@ function Set-OpenSSHTestEnvironment
[Switch] $PostmortemDebugging,
[Switch] $NoLibreSSL
)
$params = $PSBoundParameters
$params.Remove("DebugMode") | Out-Null
$params.Remove("NoAppVerifier") | Out-Null
$params.Remove("PostmortemDebugging") | Out-Null
if($PSBoundParameters.ContainsKey("Verbose"))
{
$verboseInfo = ($PSBoundParameters['Verbose']).IsPresent
}
if($Global:OpenSSHTestInfo -ne $null)
{
$Global:OpenSSHTestInfo.Clear()
$Global:OpenSSHTestInfo = $null
}
$Script:TestDataPath = $TestDataPath;
$Script:E2ETestResultsFile = Join-Path $TestDataPath "E2ETestResults.xml"
$Script:UnitTestResultsFile = Join-Path $TestDataPath "UnitTestResults.txt"
$Script:TestSetupLogFile = Join-Path $TestDataPath "TestSetupLog.txt"
$Script:UnitTestDirectory = Get-UnitTestDirectory
Set-BasicTestInfo @params
$Global:OpenSSHTestInfo.Add("Target", "localhost") # test listener name
$Global:OpenSSHTestInfo.Add("Port", "47002") # test listener port
$Global:OpenSSHTestInfo.Add("SSOUser", $SSOUser) # test user with single sign on capability
$Global:OpenSSHTestInfo.Add("PubKeyUser", $PubKeyUser) # test user to be used with explicit key for key auth
$Global:OpenSSHTestInfo.Add("PasswdUser", $PasswdUser) # test user to be used for password auth
$Global:OpenSSHTestInfo.Add("TestAccountPW", $OpenSSHTestAccountsPassword) # common password for all test accounts
$Global:OpenSSHTestInfo.Add("DebugMode", $DebugMode.IsPresent) # run openssh E2E in debug mode
$Script:EnableAppVerifier = -not ($NoAppVerifier.IsPresent)
$Script:NoLibreSSL = $NoLibreSSL.IsPresent
if($Script:WindowsInBox = $true)
{
$Script:EnableAppVerifier = $false
}
$Global:OpenSSHTestInfo.Add("EnableAppVerifier", $Script:EnableAppVerifier)
if($Script:EnableAppVerifier)
{
$Script:PostmortemDebugging = $PostmortemDebugging.IsPresent
}
$Global:OpenSSHTestInfo = @{
"Target"= "localhost"; # test listener name
"Port"= "47002"; # test listener port
"SSOUser"= $SSOUser; # test user with single sign on capability
"PubKeyUser"= $PubKeyUser; # test user to be used with explicit key for key auth
"PasswdUser"= $PasswdUser; # common password for all test accounts
"TestAccountPW"= $OpenSSHTestAccountsPassword; # common password for all test accounts
"TestDataPath" = $TestDataPath; # openssh tests path
"TestSetupLogFile" = $Script:TestSetupLogFile; # openssh test setup log file
"E2ETestResultsFile" = $Script:E2ETestResultsFile; # openssh E2E test results file
"UnitTestResultsFile" = $Script:UnitTestResultsFile; # openssh unittest test results file
"E2ETestDirectory" = $Script:E2ETestDirectory # the directory of E2E tests
"UnitTestDirectory" = $Script:UnitTestDirectory # the directory of unit tests
"DebugMode" = $DebugMode.IsPresent # run openssh E2E in debug mode
"EnableAppVerifier" = $Script:EnableAppVerifier
"PostmortemDebugging" = $Script:PostmortemDebugging
"NoLibreSSL" = $Script:NoLibreSSL
}
}
$Global:OpenSSHTestInfo.Add("PostmortemDebugging", $Script:PostmortemDebugging)
#start service if not already started
Start-Service -Name sshd
#if user does not set path, pick it up
if([string]::IsNullOrEmpty($OpenSSHBinPath))
{
$sshcmd = get-command ssh.exe -ErrorAction SilentlyContinue
if($sshcmd -eq $null)
{
Throw "Cannot find ssh.exe. Please specify -OpenSSHBinPath to the OpenSSH installed location."
}
else
{
$dirToCheck = split-path $sshcmd.Path
$description = "Pick up ssh.exe from $dirToCheck."
$prompt = "Are you sure you want to pick up ssh.exe from $($dirToCheck)?"
$caption = "Found ssh.exe from $dirToCheck"
if(-not $pscmdlet.ShouldProcess($description, $prompt, $caption))
{
Write-Host "User decided not to pick up ssh.exe from $dirToCheck. Please specify -OpenSSHBinPath to the OpenSSH installed location."
return
}
$script:OpenSSHBinPath = $dirToCheck
}
}
else
{
if (-not (Test-Path (Join-Path $OpenSSHBinPath ssh.exe) -PathType Leaf))
{
Throw "Cannot find OpenSSH binaries under $OpenSSHBinPath. Please specify -OpenSSHBinPath to the OpenSSH installed location"
}
else
{
$script:OpenSSHBinPath = $OpenSSHBinPath
}
}
$Global:OpenSSHTestInfo.Add("OpenSSHBinPath", $script:OpenSSHBinPath)
if (-not ($env:Path.ToLower().Contains($script:OpenSSHBinPath.ToLower())))
{
$env:Path = "$($script:OpenSSHBinPath);$($env:path)"
}
$acl = get-acl (join-path $script:OpenSSHBinPath "ssh.exe")
if($acl.Owner -ieq "NT SERVICE\TrustedInstaller")
{
$Script:WindowsInBox = $true
$Global:OpenSSHTestInfo.Add("WindowsInBox", $true)
$Global:OpenSSHTestInfo["EnableAppVerifier"] = $false
$Script:EnableAppVerifier = $false
}
$description = @"
WARNING: Following changes will be made to OpenSSH configuration
@ -160,12 +107,7 @@ WARNING: Following changes will be made to OpenSSH configuration
return
}
Install-OpenSSHTestDependencies
if(-not (Test-path $TestDataPath -PathType Container))
{
New-Item -ItemType Directory -Path $TestDataPath -Force -ErrorAction SilentlyContinue | out-null
}
Install-OpenSSHTestDependencies
$backupConfigPath = Join-Path $OpenSSHConfigPath sshd_config.ori
$targetsshdConfig = Join-Path $OpenSSHConfigPath sshd_config
@ -194,7 +136,7 @@ WARNING: Following changes will be made to OpenSSH configuration
#copy ca private key to test dir
$ca_priv_key = (Join-Path $Global:OpenSSHTestInfo["TestDataPath"] sshtest_ca_userkeys)
Copy-Item (Join-Path $Script:E2ETestDirectory sshtest_ca_userkeys) $ca_priv_key -Force
Repair-UserSshConfigPermission -FilePath $ca_priv_key -confirm:$false
Repair-UserSshConfigPermission -FilePath $ca_priv_key -confirm:$false
$Global:OpenSSHTestInfo["CA_Private_Key"] = $ca_priv_key
Restart-Service sshd -Force
@ -271,6 +213,98 @@ WARNING: Following changes will be made to OpenSSH configuration
Backup-OpenSSHTestInfo
}
function Set-BasicTestInfo
{
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param
(
[string] $OpenSSHBinPath,
[string] $TestDataPath = "$env:SystemDrive\OpenSSHTests",
[Switch] $NoLibreSSL
)
if($Global:OpenSSHTestInfo -ne $null)
{
$Global:OpenSSHTestInfo.Clear()
$Global:OpenSSHTestInfo = $null
}
$Script:TestDataPath = $TestDataPath;
$Script:E2ETestResultsFile = Join-Path $TestDataPath $E2ETestResultsFileName
$Script:SetupTestResultsFile = Join-Path $TestDataPath $SetupTestResultsFileName
$Script:UninstallTestResultsFile = Join-Path $TestDataPath $UninstallTestResultsFileName
$Script:UnitTestResultsFile = Join-Path $TestDataPath $UnitTestResultsFileName
$Script:TestSetupLogFile = Join-Path $TestDataPath $TestSetupLogFileName
$Script:UnitTestDirectory = Get-UnitTestDirectory
$Script:NoLibreSSL = $NoLibreSSL.IsPresent
$Global:OpenSSHTestInfo = @{
"TestDataPath" = $TestDataPath; # openssh tests path
"TestSetupLogFile" = $Script:TestSetupLogFile; # openssh test setup log file
"E2ETestResultsFile" = $Script:E2ETestResultsFile; # openssh E2E test results file
"SetupTestResultsFile" = $Script:SetupTestResultsFile; # openssh setup test test results file
"UninstallTestResultsFile" = $Script:UninstallTestResultsFile; # openssh Uninstall test test results file
"UnitTestResultsFile" = $Script:UnitTestResultsFile; # openssh unittest test results file
"E2ETestDirectory" = $Script:E2ETestDirectory # the directory of E2E tests
"UnitTestDirectory" = $Script:UnitTestDirectory # the directory of unit tests
"NoLibreSSL" = $Script:NoLibreSSL
"WindowsInBox" = $Script:WindowsInBox
}
#if user does not set path, pick it up
if([string]::IsNullOrEmpty($OpenSSHBinPath))
{
$sshcmd = get-command ssh.exe -ErrorAction SilentlyContinue
if($sshcmd -eq $null)
{
Throw "Cannot find ssh.exe. Please specify -OpenSSHBinPath to the OpenSSH installed location."
}
else
{
$dirToCheck = split-path $sshcmd.Path
$description = "Pick up ssh.exe from $dirToCheck."
$prompt = "Are you sure you want to pick up ssh.exe from $($dirToCheck)?"
$caption = "Found ssh.exe from $dirToCheck"
if(-not $pscmdlet.ShouldProcess($description, $prompt, $caption))
{
Write-Host "User decided not to pick up ssh.exe from $dirToCheck. Please specify -OpenSSHBinPath to the OpenSSH installed location."
return
}
$script:OpenSSHBinPath = $dirToCheck
}
}
else
{
if (-not (Test-Path (Join-Path $OpenSSHBinPath ssh.exe) -PathType Leaf))
{
Throw "Cannot find OpenSSH binaries under $OpenSSHBinPath. Please specify -OpenSSHBinPath to the OpenSSH installed location"
}
else
{
$script:OpenSSHBinPath = $OpenSSHBinPath
}
}
$Global:OpenSSHTestInfo.Add("OpenSSHBinPath", $script:OpenSSHBinPath)
if (-not ($env:Path.ToLower().Contains($script:OpenSSHBinPath.ToLower())))
{
$env:Path = "$($script:OpenSSHBinPath);$($env:path)"
}
$acl = get-acl (join-path $script:OpenSSHBinPath "ssh.exe")
if($acl.Owner -ieq "NT SERVICE\TrustedInstaller")
{
$Script:WindowsInBox = $true
$Global:OpenSSHTestInfo["WindowsInBox"]= $true
}
Install-OpenSSHTestDependencies -TestHarness
if(-not (Test-path $TestDataPath -PathType Container))
{
New-Item -ItemType Directory -Path $TestDataPath -Force -ErrorAction SilentlyContinue | out-null
}
}
#TODO - this is Windows specific. Need to be in PAL
function Get-LocalUserProfile
{
@ -299,7 +333,7 @@ function Get-LocalUserProfile
function Install-OpenSSHTestDependencies
{
[CmdletBinding()]
param ()
param ([Switch] $TestHarness)
#$isOpenSSHUtilsAvailable = Get-Module 'OpenSSHUtils' -ListAvailable
#if (-not ($isOpenSSHUtilsAvailable))
@ -328,6 +362,11 @@ function Install-OpenSSHTestDependencies
choco install Pester --version 3.4.6 -y --force --limitoutput 2>&1 >> $Script:TestSetupLogFile
}
if($TestHarness)
{
return
}
if($Script:PostmortemDebugging -or (($OpenSSHTestInfo -ne $null) -and ($OpenSSHTestInfo["PostmortemDebugging"])))
{
$folderName = "x86"
@ -568,6 +607,36 @@ function Get-UnitTestDirectory
$unitTestDir
}
<#
.Synopsis
Run OpenSSH Setup tests.
#>
function Invoke-OpenSSHSetupTest
{
# Discover all CI tests and run them.
Import-Module pester -force -global
Push-Location $Script:E2ETestDirectory
Write-Log -Message "Running OpenSSH Setup tests..."
$testFolders = @(Get-ChildItem *.tests.ps1 -Recurse | ForEach-Object{ Split-Path $_.FullName} | Sort-Object -Unique)
Invoke-Pester $testFolders -OutputFormat NUnitXml -OutputFile $Script:SetupTestResultsFile -Tag 'Setup' -PassThru
Pop-Location
}
<#
.Synopsis
Run OpenSSH uninstall tests.
#>
function Invoke-OpenSSHUninstallTest
{
# Discover all CI tests and run them.
Import-Module pester -force -global
Push-Location $Script:E2ETestDirectory
Write-Log -Message "Running OpenSSH Uninstall tests..."
$testFolders = @(Get-ChildItem *.tests.ps1 -Recurse | ForEach-Object{ Split-Path $_.FullName} | Sort-Object -Unique)
Invoke-Pester $testFolders -OutputFormat NUnitXml -OutputFile $Script:UninstallTestResultsFile -Tag 'Uninstall' -PassThru
Pop-Location
}
<#
.Synopsis
Run OpenSSH pester tests.
@ -726,4 +795,4 @@ function Write-Log
}
}
Export-ModuleMember -Function Set-OpenSSHTestEnvironment, Clear-OpenSSHTestEnvironment, Invoke-OpenSSHUnitTest, Invoke-OpenSSHE2ETest, Backup-OpenSSHTestInfo, Restore-OpenSSHTestInfo
Export-ModuleMember -Function Set-BasicTestInfo, Set-OpenSSHTestEnvironment, Clear-OpenSSHTestEnvironment, Invoke-OpenSSHSetupTest, Invoke-OpenSSHUnitTest, Invoke-OpenSSHE2ETest, Invoke-OpenSSHUninstallTest, Backup-OpenSSHTestInfo, Restore-OpenSSHTestInfo

View File

@ -33,14 +33,30 @@ wevtutil um `"$etwman`"
[XML]$xml = Get-Content $etwman
$xml.instrumentationManifest.instrumentation.events.provider.resourceFileName = $sshagentpath.ToString()
$xml.instrumentationManifest.instrumentation.events.provider.messageFileName = $sshagentpath.ToString()
$xml.Save($etwman)
$streamWriter = $null
$xmlWriter = $null
try {
$streamWriter = new-object System.IO.StreamWriter($etwman)
$xmlWriter = [System.Xml.XmlWriter]::Create($streamWriter)
$xml.Save($xmlWriter)
}
finally {
if($streamWriter) {
$streamWriter.Close()
}
}
#register etw provider
wevtutil im `"$etwman`"
New-Service -Name ssh-agent -BinaryPathName `"$sshagentpath`" -Description "SSH Agent" -StartupType Manual | Out-Null
cmd.exe /c 'sc.exe sdset ssh-agent D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RP;;;AU)'
$agentDesc = "Agent to hold private keys used for public key authentication."
New-Service -Name ssh-agent -DisplayName "OpenSSH Authentication Agent" -BinaryPathName `"$sshagentpath`" -Description $agentDesc -StartupType Manual | Out-Null
sc.exe sdset ssh-agent "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RP;;;AU)"
sc.exe privs ssh-agent SeImpersonatePrivilege
New-Service -Name sshd -BinaryPathName `"$sshdpath`" -Description "SSH Daemon" -StartupType Manual | Out-Null
$sshdDesc = "SSH protocol based service to provide secure encrypted communications between two untrusted hosts over an insecure network."
New-Service -Name sshd -DisplayName "OpenSSH SSH Server" -BinaryPathName `"$sshdpath`" -Description $sshdDesc -StartupType Manual | Out-Null
sc.exe privs sshd SeAssignPrimaryTokenPrivilege/SeTcbPrivilege/SeBackupPrivilege/SeRestorePrivilege/SeImpersonatePrivilege
Write-Host -ForegroundColor Green "sshd and ssh-agent services successfully installed"

View File

@ -0,0 +1,490 @@
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force
$suite = "Setup"
$tC = 1
$tI = 0
Describe "Setup Tests" -Tags "Setup" {
BeforeAll {
if($OpenSSHTestInfo -eq $null)
{
Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments."
}
$windowsInBox = $OpenSSHTestInfo["WindowsInBox"]
$binPath = $OpenSSHTestInfo["OpenSSHBinPath"]
$dataPath = Join-path $env:ProgramData ssh
$systemSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::LocalSystemSid)
$adminsSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid)
$usersSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::BuiltinUsersSid)
$authenticatedUserSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::AuthenticatedUserSid)
$trustedInstallerSid = Get-UserSID -User "NT SERVICE\TrustedInstaller"
$allApplicationPackagesSid = Get-UserSID -User "ALL APPLICATION PACKAGES"
$allRestrictedApplicationPackagesSid = Get-UserSID -User "ALL RESTRICTED APPLICATION PACKAGES"
$FSReadAccessPerm = ([System.UInt32] [System.Security.AccessControl.FileSystemRights]::ReadAndExecute.value__) -bor `
([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Synchronize.value__)
$FSReadWriteAccessPerm = ([System.UInt32] [System.Security.AccessControl.FileSystemRights]::ReadAndExecute.value__) -bor `
([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Write.value__) -bor `
([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Modify.value__) -bor `
([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Synchronize.value__)
$FSFullControlPerm = [System.UInt32] [System.Security.AccessControl.FileSystemRights]::FullControl.value__
$FSReadAndExecutePerm = ([System.UInt32] [System.Security.AccessControl.FileSystemRights]::ReadAndExecute.value__) -bor `
([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Synchronize.value__)
$RegReadKeyPerm = ([System.UInt32] [System.Security.AccessControl.RegistryRights]::ReadKey.value__)
$RegFullControlPerm = [System.UInt32] [System.Security.AccessControl.RegistryRights]::FullControl.value__
#only validate owner and ACEs of the registry
function ValidateRegistryACL {
param([string]$RegPath, $Ownersid = $adminsSid, $IdAcls)
Test-Path -Path $RegPath | Should Be $true
$myACL = Get-ACL $RegPath
$OwnerSid = Get-UserSid -User $myACL.Owner
$OwnerSid.Equals($Ownersid) | Should Be $true
$myACL.Access | Should Not Be $null
$CAPABILITY_SID = "S-1-15-3-1024-1065365936-1281604716-3511738428-1654721687-432734479-3232135806-4053264122-3456934681"
$nonPropagate = $myACL.Access | ? {($_.PropagationFlags -eq ([System.Security.AccessControl.PropagationFlags]::None)) -and ($_.IdentityReference -ine $CAPABILITY_SID)}
foreach ($a in $nonPropagate) {
$findItem = $IdAcls | ? {
($a.IdentityReference -eq (Get-UserAccount -UserSid ($_.Identity))) -and `
($a.IsInherited -eq $_.IsInherited) -and `
($a.AccessControlType -eq ([System.Security.AccessControl.AccessControlType]::Allow)) -and `
(([System.Int32]$a.RegistryRights.value__) -eq ($_.RegistryRights))
}
$findItem | Should Not Be $null
}
foreach ($expected in $IdAcls) {
$findItem = $nonPropagate | ? {
((Get-UserAccount -UserSid ($expected.Identity)) -eq $_.IdentityReference) -and `
($expected.IsInherited -eq $_.IsInherited) -and `
($expected.RegistryRights -eq ([System.Int32]$_.RegistryRights.value__))
}
$findItem | Should Not Be $null
}
}
#only validate owner and ACEs of the file
function ValidateFileSystem {
param(
[string]$FilePath,
[bool]$IsDirectory = $false,
[switch]$IsDataFile,
$OwnerSid = $trustedInstallerSid)
if($IsDirectory)
{
Test-Path -Path $FilePath -PathType Container | Should Be $true
}
else
{
Test-Path -Path $FilePath -PathType Leaf | Should Be $true
}
$myACL = Get-ACL $FilePath
$currentOwnerSid = Get-UserSid -User $myACL.Owner
if(-not $windowsInBox) {return}
$currentOwnerSid.Equals($OwnerSid) | Should Be $true
$myACL.Access | Should Not Be $null
if($IsDirectory)
{
$identities = @($systemSid, $adminsSid)
}
elseif($IsDataFile)
{
$identities = @($systemSid, $adminsSid, $authenticatedUserSid)
}
else
{
$identities = @($systemSid, $adminsSid, $trustedInstallerSid, $allApplicationPackagesSid, $allRestrictedApplicationPackagesSid, $usersSid)
}
$identities | % {
(Get-UserAccount -UserSid $_) | Should BeIn $myACL.Access.IdentityReference
}
foreach ($a in $myACL.Access) {
$id = Get-UserSid -User $a.IdentityReference
if($id -eq $null)
{
$idRefShortValue = ($a.IdentityReference.Value).split('\')[-1]
$id = Get-UserSID -User $idRefShortValue
}
$id | Should BeIn $identities
switch ($id)
{
{@($systemSid, $adminsSid) -contains $_}
{
if($IsDataFile)
{
([System.UInt32]$a.FileSystemRights.value__) | Should Be $FSFullControlPerm
}
else
{
([System.UInt32]$a.FileSystemRights.value__) | Should Be $FSReadAndExecutePerm
}
break;
}
{@($usersSid, $allApplicationPackagesSid, $allRestrictedApplicationPackagesSid, $authenticatedUserSid) -contains $_}
{
([System.UInt32]$a.FileSystemRights.value__) | Should Be $FSReadAndExecutePerm
break;
}
$trustedInstallerSid
{
([System.UInt32]$a.FileSystemRights.value__) | Should Be $FSFullControlPerm
break;
}
}
$a.AccessControlType | Should Be ([System.Security.AccessControl.AccessControlType]::Allow)
if($IsDirectory)
{
$a.InheritanceFlags | Should Be (([System.Security.AccessControl.InheritanceFlags]::ContainerInherit.value__ -bor `
[System.Security.AccessControl.InheritanceFlags]::ObjectInherit.value__))
}
else
{
$a.InheritanceFlags | Should Be ([System.Security.AccessControl.InheritanceFlags]::None)
}
$a.PropagationFlags | Should Be ([System.Security.AccessControl.PropagationFlags]::None)
}
}
}
Context "$tC - Validate Openssh binary files" {
BeforeAll {
$tI=1
$binaries = @(
@{
Name = 'sshd.exe'
},
@{
Name = 'ssh.exe'
},
@{
Name = 'ssh-agent.exe'
},
@{
Name = 'ssh-add.exe'
},
@{
Name = 'sftp.exe'
},
@{
Name = 'sftp-server.exe'
},
@{
Name = 'scp.exe'
},
@{
Name = 'ssh-shellhost.exe'
},
@{
Name = 'ssh-agent.exe'
},
@{
Name = 'ssh-keyscan.exe'
}
)
$dataFile = @(
@{
Name = 'sshd_config_default'
},
@{
Name = 'install-sshd.ps1'
},
@{
Name = 'uninstall-sshd.ps1'
},
@{
Name = 'FixHostFilePermissions.ps1'
},
@{
Name = 'FixUserFilePermissions.ps1'
},
@{
Name = 'OpenSSHUtils.psm1'
},
@{
Name = 'OpenSSHUtils.psd1'
},
@{
Name = 'openssh-events.man'
}
)
$dataFile1 = @(
@{
Name = "sshd_config"
}
@{
Name = "logs"
IsDirectory = $true
}
)
}
AfterAll{$tC++}
AfterEach { $tI++ }
It "$tC.$tI - Validate Openssh binary files--<Name>" -TestCases:$binaries{
param([string]$Name, [boolean]$IsDirectory = $false)
ValidateFileSystem -FilePath (join-path $binPath $Name)
}
It "$tC.$tI - Validate Openssh script files--<Name>" -TestCases:$dataFile {
param([string]$Name, [boolean]$IsDirectory = $false)
if(-not $WindowsInbox) { ValidateFileSystem -FilePath (join-path $binPath $Name) }
}
It "$tC.$tI - Validate data files--<Name>" -TestCases:$dataFile1 {
param([string]$Name, [boolean]$IsDirectory = $false)
if(-not (Test-Path $dataPath -PathType Container))
{
Start-Service sshd
}
ValidateFileSystem -FilePath (join-path $dataPath $Name) -IsDirectory $IsDirectory -OwnerSid $adminsSid -IsDataFile
}
}
Context "$tC - Validate Openssh registry entries" {
BeforeAll {
$tI=1
$servicePath = "HKLM:\SYSTEM\ControlSet001\Services"
$opensshRegPath = "HKLM:\SOFTWARE\OpenSSH"
$opensshACLs = @(
@{
Identity=$systemSid
IsInherited = $false
RegistryRights = $RegFullControlPerm
PropagationFlags = "None"
},
@{
Identity=$adminsSid
IsInherited = $false
RegistryRights = $RegFullControlPerm
PropagationFlags = "None"
},
@{
Identity=$authenticatedUserSid
IsInherited = $false
RegistryRights = $RegReadKeyPerm -bor ([System.UInt32] [System.Security.AccessControl.RegistryRights]::SetValue.value__)
PropagationFlags = "None"
}
)
}
AfterAll{$tC++}
AfterEach { $tI++ }
It "$tC.$tI - Validate Registry key ssh-agent\Description" {
$p = Get-ItemPropertyValue (Join-Path $servicePath "ssh-agent") -Name "Description"
$p | Should Not Be $null
}
It "$tC.$tI - Validate Registry key ssh-agent\ErrorControl" {
$p = Get-ItemPropertyValue (Join-Path $servicePath "ssh-agent") -Name "ErrorControl"
$p | Should Be 1
}
It "$tC.$tI - Validate Registry key ssh-agent\ImagePath" {
$p = Get-ItemPropertyValue (Join-Path $servicePath "ssh-agent") -Name "ImagePath"
$imagePath = (Join-Path $binPath "ssh-agent.exe").ToLower()
$p | Should Match "[`"]?$($imagePath.Replace("\", "\\"))[`"]?"
}
It "$tC.$tI - Validate Registry key ssh-agent\ObjectName" {
$p = Get-ItemPropertyValue (Join-Path $servicePath "ssh-agent") -Name "ObjectName"
$p | Should Be "LocalSystem"
}
It "$tC.$tI - Validate Registry key ssh-agent\Start" {
$p = Get-ItemPropertyValue (Join-Path $servicePath "ssh-agent") -Name "Start"
$p | Should Be 3
}
It "$tC.$tI - Validate Registry key ssh-agent\Type" {
$p = Get-ItemPropertyValue (Join-Path $servicePath "ssh-agent") -Name "Type"
$p | Should Be 16
}
It "$tC.$tI - Validate Registry key to ssh-agent\Security\Security" {
$p = Get-ItemPropertyValue (Join-Path $servicePath "ssh-agent\Security") -Name Security
$p.Gettype() | Should Be byte[]
}
It "$tC.$tI - Validate Registry key sshd\Description" {
$p = Get-ItemPropertyValue (Join-Path $servicePath "sshd") -Name "Description"
$p | Should not Be $null
}
It "$tC.$tI - Validate Registry key sshd\ErrorControl" {
$p = Get-ItemPropertyValue (Join-Path $servicePath "sshd") -Name "ErrorControl"
$p | Should Be 1
}
It "$tC.$tI - Validate Registry key sshd\ImagePath" {
$p = Get-ItemPropertyValue (Join-Path $servicePath "sshd") -Name "ImagePath"
$imagePath = (Join-Path $binPath "sshd.exe").ToLower()
$p | Should Match "[`"]?$($imagePath.Replace("\", "\\"))[`"]?"
}
It "$tC.$tI - Validate Registry key sshd\ObjectName" {
$p = Get-ItemPropertyValue (Join-Path $servicePath "sshd") -Name "ObjectName"
$p | Should Be "LocalSystem"
}
It "$tC.$tI - Validate Registry key sshd\Start" {
$p = Get-ItemPropertyValue (Join-Path $servicePath "sshd") -Name "Start"
$p | Should Be 3
}
It "$tC.$tI - Validate Registry key sshd\Type" {
$p = Get-ItemPropertyValue (Join-Path $servicePath "sshd") -Name "Type"
$p | Should Be 16
}
It "$tC.$tI - Validate Registry openssh entry" {
ValidateRegistryACL -RegPath $opensshRegPath -IdAcls $opensshACLs
}
It "$tC.$tI - Validate Registry openssh\agent entry" {
$agentPath = Join-Path $opensshRegPath "Agent"
if(-not (Test-Path $agentPath -PathType Container))
{
Start-Service ssh-agent
}
ValidateRegistryACL -RegPath $agentPath -IdAcls $opensshACLs
}
}
Context "$tC - Validate service settings" {
BeforeAll {
$tI=1
}
AfterAll{$tC++}
AfterEach { $tI++ }
It "$tC.$tI - Validate properties of ssh-agent service" {
$sshdSvc = Get-service ssh-agent
$sshdSvc.StartType | Should Be ([System.ServiceProcess.ServiceStartMode]::Manual)
$sshdSvc.ServiceType | Should Be ([System.ServiceProcess.ServiceType]::Win32OwnProcess)
$sshdSvc.ServiceName | Should Be "ssh-agent"
$sshdSvc.DisplayName | Should BeLike "OpenSSH*"
$sshdSvc.Name | Should Be "ssh-agent"
($sshdSvc.DependentServices).Count | Should Be 0
($sshdSvc.ServicesDependedOn).Count | Should Be 0
($sshdSvc.RequiredServices).Count | Should Be 0
}
It "$tC.$tI - Validate properties of sshd service" {
$sshdSvc = Get-service sshd
$sshdSvc.StartType | Should Be ([System.ServiceProcess.ServiceStartMode]::Manual)
$sshdSvc.ServiceType | Should Be ([System.ServiceProcess.ServiceType]::Win32OwnProcess)
$sshdSvc.ServiceName | Should Be "sshd"
$sshdSvc.DisplayName | Should BeLike "OpenSSH*"
$sshdSvc.Name | Should Be "sshd"
($sshdSvc.DependentServices).Count | Should Be 0
($sshdSvc.ServicesDependedOn).Count | Should Be 0
($sshdSvc.RequiredServices).Count | Should Be 0
}
It "$tC.$tI - Validate RequiredPrivileges of ssh-agent" {
$a = sc.exe qprivs ssh-agent 256
$p = @($a | % { if($_ -match "Se[\w]+Privilege" ) {$start = $_.IndexOf("Se");$_.Substring($start, $_.length-$start)}})
$p.count | Should Be 1
$p[0] | Should Be "SeImpersonatePrivilege"
}
It "$tC.$tI - Validate RequiredPrivileges of sshd" {
$expected = @("SeAssignPrimaryTokenPrivilege", "SeTcbPrivilege", "SeBackupPrivilege", "SeRestorePrivilege", "SeImpersonatePrivilege")
$a = sc.exe qprivs sshd 256
$p = $a | % { if($_ -match "Se[\w]+Privilege" ) {$start = $_.IndexOf("Se");$_.Substring($start, $_.length-$start)}}
$expected | % {
$_ | Should BeIn $p
}
$p | % {
$_ | Should BeIn $expected
}
}
It "$tC.$tI - Validate security access to ssh-agent service" {
$a = @(sc.exe sdshow ssh-agent)
$b = $a[-1] -split "[D|S]:"
$expected_dacl_aces = @("(A;;CCLCSWRPWPDTLOCRRC;;;SY)", "(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)", "(A;;CCLCSWLOCRRC;;;IU)", "(A;;CCLCSWLOCRRC;;;SU)", "(A;;RP;;;AU)")
$c = @($b | ? { -not [string]::IsNullOrWhiteSpace($_) })
$dacl = $c[0]
$dacl_aces = $dacl -split "(\([;|\w]+\))"
$actual_dacl_aces = $dacl_aces | ? { -not [string]::IsNullOrWhiteSpace($_) }
$expected_dacl_aces | % {
$_ | Should BeIn $actual_dacl_aces
}
$actual_dacl_aces | % {
$_ | Should BeIn $expected_dacl_aces
}
<# ignore sacl for now
if($c.Count -gt 1) {
$c[1] | Should Be "(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)"
}#>
}
It "$tC.$tI - Validate security access to sshd service" {
$a = @(sc.exe sdshow sshd)
$b = $a[-1] -split "[D|S]:"
$expected_dacl_aces = @("(A;;CCLCSWRPWPDTLOCRRC;;;SY)", "(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)", "(A;;CCLCSWLOCRRC;;;IU)", "(A;;CCLCSWLOCRRC;;;SU)")
$c = @($b | ? { -not [string]::IsNullOrWhiteSpace($_) })
$dacl = $c[0]
$dacl_aces = $dacl -split "(\([;|\w]+\))"
$actual_dacl_aces = $dacl_aces | ? { -not [string]::IsNullOrWhiteSpace($_) }
$expected_dacl_aces | % {
$_ | Should BeIn $actual_dacl_aces
}
$actual_dacl_aces | % {
$_ | Should BeIn $expected_dacl_aces
}
<# ignore sacl for now
if($c.Count -gt 1) {
$c[1] | Should Be "(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)"
}#>
}
}
Context "$tC - Validate Firewall settings" {
BeforeAll {
$firwallRuleName = "OpenSSH-Server-In-TCP"
$tI=1
}
AfterAll{$tC++}
AfterEach { $tI++ }
It "$tC.$tI - Validate Firewall settings" -skip:(!$windowsInBox) {
$rule = Get-NetFirewallRule -Name $firwallRuleName
$rule.Group | Should BeLike "OpenSSH*"
$rule.Description | Should BeLike "*OpenSSH*"
$rule.DisplayName | Should BeLike "OpenSSH*"
$rule.Enabled | Should Be $true
$rule.Profile.ToString() | Should Be 'Any'
$rule.Direction.ToString() | Should Be 'Inbound'
$rule.Action.ToString() | Should Be 'Allow'
$rule.StatusCode | Should Be 65536
$fwportFilter = $rule | Get-NetFirewallPortFilter
$fwportFilter.Protocol | Should Be 'TCP'
$fwportFilter.LocalPort | Should Be 22
$fwportFilter.RemotePort | Should Be 'Any'
}
}
}

View File

@ -0,0 +1,196 @@
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force
$suite = "Uninstall"
$tC = 1
$tI = 0
Describe "Uninstall Tests" -Tags "Uninstall" {
BeforeAll {
if($OpenSSHTestInfo -eq $null)
{
Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments."
}
$windowsInBox = $OpenSSHTestInfo["WindowsInBox"]
$binPath = $OpenSSHTestInfo["OpenSSHBinPath"]
$dataPath = Join-path $env:ProgramData ssh
Stop-Service sshd -ErrorAction SilentlyContinue
Stop-Service ssh-agent -ErrorAction SilentlyContinue
if(Get-Service sshd -ErrorAction SilentlyContinue)
{
if($windowsInBox) {
Remove-WindowsCapability -online -name OpenSSH.Server~~~~0.0.1.0
}
else {
& (Join-Path $binPath "uninstall-sshd.ps1")
}
}
if(Get-Service ssh-agent -ErrorAction SilentlyContinue)
{
if($windowsInBox) {
Remove-WindowsCapability -online -name OpenSSH.Client~~~~0.0.1.0
}
else
{
& (Join-Path $binPath "uninstall-sshd.ps1")
}
}
$systemSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::LocalSystemSid)
$adminsSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid)
$authenticatedUserSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::AuthenticatedUserSid)
$RegReadKeyPerm = ([System.UInt32] [System.Security.AccessControl.RegistryRights]::ReadKey.value__)
$RegFullControlPerm = [System.UInt32] [System.Security.AccessControl.RegistryRights]::FullControl.value__
#only validate owner and ACEs of the registry
function ValidateRegistryACL {
param([string]$RegPath, $Ownersid = $adminsSid, $IdAcls)
Test-Path -Path $RegPath | Should Be $true
$myACL = Get-ACL $RegPath
$OwnerSid = Get-UserSid -User $myACL.Owner
$OwnerSid.Equals($Ownersid) | Should Be $true
$myACL.Access | Should Not Be $null
$CAPABILITY_SID = "S-1-15-3-1024-1065365936-1281604716-3511738428-1654721687-432734479-3232135806-4053264122-3456934681"
$nonPropagate = $myACL.Access | ? {($_.PropagationFlags -eq ([System.Security.AccessControl.PropagationFlags]::None)) -and ($_.IdentityReference -ine $CAPABILITY_SID)}
foreach ($a in $nonPropagate) {
$findItem = $IdAcls | ? {
($a.IdentityReference -eq (Get-UserAccount -UserSid ($_.Identity))) -and `
($a.IsInherited -eq $_.IsInherited) -and `
($a.AccessControlType -eq ([System.Security.AccessControl.AccessControlType]::Allow)) -and `
($a.PropagationFlags -eq ([System.Security.AccessControl.PropagationFlags]::None) -and `
(([System.Int32]$a.RegistryRights.value__) -eq ($_.RegistryRights)))
}
$findItem | Should Not Be $null
}
}
}
Context "$tC - Validate Openssh binary files" {
BeforeAll {
if(-not $Windowsbox)
{
$binaries = $null
return
}
$tI=1
$binaries = @(
@{
Name = 'sshd.exe'
},
@{
Name = 'ssh.exe'
},
@{
Name = 'ssh-agent.exe'
},
@{
Name = 'ssh-add.exe'
},
@{
Name = 'sftp.exe'
},
@{
Name = 'sftp-server.exe'
},
@{
Name = 'scp.exe'
},
@{
Name = 'ssh-shellhost.exe'
},
@{
Name = 'ssh-agent.exe'
},
@{
Name = 'ssh-keyscan.exe'
}
)
}
AfterAll{$tC++}
AfterEach { $tI++ }
It "$tC.$tI - Validate Openssh binary files--<Name> is removed" -TestCases:$binaries{
param([string]$Name, [boolean]$IsDirectory = $false)
if(-not [string]::IsNullOrWhiteSpace($Name)) {
(join-path $binPath $Name) | Should Not Exist
}
}
}
Context "$tC - Validate Openssh registry entries" {
BeforeAll {
$tI=1
$servicePath = "HKLM:\SYSTEM\ControlSet001\Services"
$opensshRegPath = "HKLM:\SOFTWARE\OpenSSH"
$opensshACLs = @(
@{
Identity=$systemSid
IsInherited = $false
RegistryRights = $RegFullControlPerm
PropagationFlags = "None"
},
@{
Identity=$adminsSid
IsInherited = $false
RegistryRights = $RegFullControlPerm
PropagationFlags = "None"
},
@{
Identity=$authenticatedUserSid
IsInherited = $false
RegistryRights = $RegReadKeyPerm -bor ([System.UInt32] [System.Security.AccessControl.RegistryRights]::SetValue.value__)
PropagationFlags = "None"
}
)
}
AfterAll{$tC++}
AfterEach { $tI++ }
It "$tC.$tI - Validate Registry key ssh-agent is removed" {
(Join-Path $servicePath "ssh-agent") | Should Not Exist
}
It "$tC.$tI - Validate Registry key sshd is removed" {
(Join-Path $servicePath "sshd") | Should Not Exist
}
It "$tC.$tI - Validate Registry openssh entry" {
ValidateRegistryACL -RegPath $opensshRegPath -IdAcls $opensshACLs
}
}
Context "$tC - Validate service is removed" {
BeforeAll {
$tI=1
}
AfterAll{$tC++}
AfterEach { $tI++ }
It "$tC.$tI - Validate ssh-agent is removed" {
Get-Service ssh-agent -ErrorAction SilentlyContinue | Should Be $null
}
It "$tC.$tI - Validate sshd is removed" {
Get-Service sshd -ErrorAction SilentlyContinue | Should Be $null
}
}
Context "$tC - Validate Firewall settings" {
BeforeAll {
$firwallRuleName = "OpenSSH-Server-In-TCP"
$tI=1
}
AfterAll{$tC++}
AfterEach { $tI++ }
It "$tC.$tI - Validate Firewall settings" -skip:(!$windowsInBox) {
Get-NetFirewallRule -Name $firwallRuleName -ErrorAction SilentlyContinue | Should Be $null
}
}
}