Yanbing 2017-06-26 21:58:29 -07:00 committed by Manoj Ampalam
parent f8f5e45f02
commit eb0ab1b522
20 changed files with 983 additions and 984 deletions

View File

@ -4,37 +4,36 @@ image: Visual Studio 2015
branches:
only:
- latestw_all
- latestw_all_openssl
init:
- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
build_script:
- ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1 -DisableNameChecking
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1
Invoke-AppVeyorBuild
after_build:
- ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1 -DisableNameChecking
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 -DisableNameChecking
Setup-OpenSSHTestEnvironment -Quiet
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 -DisableNameChecking
Run-OpenSSHTests
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1
Invoke-OpenSSHTests
after_test:
- ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1 -DisableNameChecking
Upload-OpenSSHTestResults
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1
Publish-OpenSSHTestResults
on_finish:
- ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1 -DisableNameChecking
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1
Publish-Artifact

View File

@ -1,12 +1,14 @@
$ErrorActionPreference = 'Stop'
Import-Module $PSScriptRoot\OpenSSHCommonUtils.psm1 -Force -DisableNameChecking
Import-Module $PSScriptRoot\OpenSSHBuildHelper.psm1 -Force -DisableNameChecking
Import-Module $PSScriptRoot\OpenSSHTestHelper.psm1 -Force -DisableNameChecking
Set-StrictMode -Version 2.0
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\OpenSSHCommonUtils.psm1 -Force
Import-Module $PSScriptRoot\OpenSSHBuildHelper.psm1 -Force
Import-Module $PSScriptRoot\OpenSSHTestHelper.psm1 -Force
$repoRoot = Get-RepositoryRoot
$script:messageFile = join-path $repoRoot.FullName "BuildMessage.log"
# Sets a build variable
# Write the build message
Function Write-BuildMessage
{
param(
@ -77,12 +79,11 @@ function Invoke-AppVeyorFull
{
$env:APPVEYOR_SCHEDULED_BUILD = 'True'
}
try {
Set-OpenSSHTestParams
try {
Invoke-AppVeyorBuild
Install-OpenSSH
Setup-OpenSSHTestEnvironment
Run-OpenSSHTests
Set-OpenSSHTestEnvironment -confirm:$false
Invoke-OpenSSHTests
Publish-Artifact
}
finally {
@ -97,8 +98,8 @@ function Invoke-AppVeyorFull
function Invoke-AppVeyorBuild
{
Set-BuildVariable TestPassed True
Build-OpenSSH -Configuration Release -NativeHostArch x64
Build-OpenSSH -Configuration Debug -NativeHostArch x86
Start-OpenSSHBuild -Configuration Release -NativeHostArch x64
Start-OpenSSHBuild -Configuration Release -NativeHostArch x86
Write-BuildMessage -Message "OpenSSH binaries build success!" -Category Information
}
@ -136,6 +137,100 @@ function Add-BuildLog
}
}
<#
.Synopsis
Deploy all required files to a location and install the binaries
#>
function Install-OpenSSH
{
[CmdletBinding()]
param
(
[ValidateSet('Debug', 'Release')]
[string]$Configuration = "Release",
[ValidateSet('x86', 'x64', '')]
[string]$NativeHostArch = "",
[string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
)
if ($NativeHostArch -eq "")
{
$NativeHostArch = 'x64'
if ($env:PROCESSOR_ARCHITECTURE -eq 'x86') {
$NativeHostArch = 'x86'
}
}
Start-OpenSSHPackage -NativeHostArch $NativeHostArch -Configuration $Configuration -DestinationPath $OpenSSHDir
Push-Location $OpenSSHDir
& "$OpenSSHDir\install-sshd.ps1"
& "$OpenSSHDir\ssh-keygen.exe" -A
& "$OpenSSHDir\FixHostFilePermissions.ps1" -Confirm:$false
#machine will be reboot after Install-openssh anyway
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
$newMachineEnvironmentPath = $machinePath
if (-not ($machinePath.ToLower().Contains($OpenSSHDir.ToLower())))
{
$newMachineEnvironmentPath = "$OpenSSHDir;$newMachineEnvironmentPath"
$env:Path = "$OpenSSHDir;$env:Path"
}
# Update machine environment path
if ($newMachineEnvironmentPath -ne $machinePath)
{
[Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE')
}
Set-Service sshd -StartupType Automatic
Set-Service ssh-agent -StartupType Automatic
Pop-Location
Write-BuildMessage -Message "OpenSSH installed!" -Category Information
}
<#
.Synopsis
uninstalled sshd
#>
function UnInstall-OpenSSH
{
[CmdletBinding()]
param
(
[string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
)
if (-not (Test-Path $OpenSSHDir -PathType Container))
{
return
}
Push-Location $OpenSSHDir
if((Get-Service ssh-agent -ErrorAction SilentlyContinue) -ne $null) {
Stop-Service ssh-agent -Force
}
& "$OpenSSHDir\uninstall-sshd.ps1"
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
$newMachineEnvironmentPath = $machinePath
if ($machinePath.ToLower().Contains($OpenSSHDir.ToLower()))
{
$newMachineEnvironmentPath = $newMachineEnvironmentPath.Replace("$OpenSSHDir;", '')
$env:Path = $env:Path.Replace("$OpenSSHDir;", '')
}
if ($newMachineEnvironmentPath -ne $machinePath)
{
[Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE')
}
Pop-Location
Remove-Item -Path $OpenSSHDir -Recurse -Force -ErrorAction SilentlyContinue
}
<#
.Synopsis
Publishes package build artifacts.
@ -170,11 +265,11 @@ function Add-Artifact
function Publish-Artifact
{
Write-Host -ForegroundColor Yellow "Publishing project artifacts"
[System.Collections.ArrayList] $artifacts = [System.Collections.ArrayList]::new()
[System.Collections.ArrayList] $artifacts = new-object System.Collections.ArrayList
# Get the build.log file for each build configuration
Add-BuildLog -artifacts $artifacts -buildLog (Get-BuildLogFile -root $repoRoot.FullName -Configuration Release -NativeHostArch x64)
Add-BuildLog -artifacts $artifacts -buildLog (Get-BuildLogFile -root $repoRoot.FullName -Configuration Debug -NativeHostArch x86)
Add-BuildLog -artifacts $artifacts -buildLog (Get-BuildLogFile -root $repoRoot.FullName -Configuration Release -NativeHostArch x86)
if($Global:OpenSSHTestInfo)
{
@ -186,7 +281,6 @@ function Publish-Artifact
foreach ($artifact in $artifacts)
{
Write-Host "Publishing $artifact as Appveyor artifact"
# NOTE: attempt to publish subsequent artifacts even if the current one fails
Push-AppveyorArtifact $artifact -ErrorAction Continue
}
}
@ -195,10 +289,10 @@ function Publish-Artifact
.Synopsis
Runs the tests for this repo
#>
function Run-OpenSSHTests
function Invoke-OpenSSHTests
{
Write-Host "Start running unit tests"
$unitTestFailed = Run-OpenSSHUnitTest
$unitTestFailed = Invoke-OpenSSHUnitTest
if($unitTestFailed)
{
@ -212,14 +306,14 @@ function Run-OpenSSHTests
Write-BuildMessage -Message "All Unit tests passed!" -Category Information
}
# Run all E2E tests.
Run-OpenSSHE2ETest
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
}
$xml = [xml](Get-Content -raw $OpenSSHTestInfo["E2ETestResultsFile"])
$xml = [xml](Get-Content $OpenSSHTestInfo["E2ETestResultsFile"] | out-string)
if ([int]$xml.'test-results'.failures -gt 0)
{
$errorMessage = "$($xml.'test-results'.failures) tests in regress\pesterTests failed. Detail test log is at $($OpenSSHTestInfo["E2ETestResultsFile"])."
@ -239,7 +333,7 @@ function Run-OpenSSHTests
.Synopsis
upload OpenSSH pester test results.
#>
function Upload-OpenSSHTestResults
function Publish-OpenSSHTestResults
{
if ($env:APPVEYOR_JOB_ID)
{

View File

@ -1,7 +1,7 @@
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param ()
Set-StrictMode -Version 2.0
If (!(Test-Path variable:PSScriptRoot)) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Definition}
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\OpenSSHUtils -Force
#check sshd config file

View File

@ -1,7 +1,7 @@
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param ()
Set-StrictMode -Version 2.0
If (!(Test-Path variable:PSScriptRoot)) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Definition}
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\OpenSSHUtils -Force

View File

@ -1,6 +1,7 @@
Set-StrictMode -Version Latest
Set-StrictMode -Version 2.0
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\OpenSSHCommonUtils.psm1 -Force
Import-Module $PSScriptRoot\OpenSSHCommonUtils.psm1 -force -DisableNameChecking
[string] $script:platform = $env:PROCESSOR_ARCHITECTURE
[string] $script:vcPath = $null
[System.IO.DirectoryInfo] $script:OpenSSHRoot = $null
@ -83,7 +84,7 @@ function Write-BuildMsg
[switch] $Silent
)
if ($AsVerbose)
if($PSBoundParameters.ContainsKey("AsVerbose"))
{
if ($script:Verbose)
{
@ -96,17 +97,24 @@ function Write-BuildMsg
return
}
if ($AsInfo)
if($PSBoundParameters.ContainsKey("AsInfo"))
{
Write-Log -Message "INFO: $message"
if (-not $Silent)
{
Write-Information -MessageData $message -InformationAction Continue
if(Get-Command "Write-Information" -ErrorAction SilentlyContinue )
{
Write-Information -MessageData $message -InformationAction Continue
}
else
{
Write-Verbose -Message $message -Verbose
}
}
return
}
if ($AsWarning)
if($PSBoundParameters.ContainsKey("AsWarning"))
{
Write-Log -Message "WARNING: $message"
if (-not $Silent)
@ -116,7 +124,7 @@ function Write-BuildMsg
return
}
if ($AsError)
if($PSBoundParameters.ContainsKey("AsError"))
{
Write-Log -Message "ERROR: $message"
if (-not $Silent)
@ -137,8 +145,6 @@ function Write-BuildMsg
function Start-OpenSSHBootstrap
{
[bool] $silent = -not $script:Verbose
Set-StrictMode -Version Latest
Write-BuildMsg -AsInfo -Message "Checking tools and dependencies" -Silent:$silent
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
@ -167,7 +173,7 @@ function Start-OpenSSHBootstrap
{
Write-BuildMsg -AsVerbose -Message "$gitCmdPath already present in Path environment variable" -Silent:$silent
}
$nativeMSBuildPath = "${env:ProgramFiles(x86)}\MSBuild\14.0\bin"
if($script:platform -ieq "AMD64")
{
@ -245,7 +251,7 @@ function Start-OpenSSHBootstrap
}
}
function Clone-Win32OpenSSH
function Get-Win32OpenSSHRepo
{
[bool] $silent = -not $script:Verbose
@ -264,7 +270,7 @@ function Clone-Win32OpenSSH
Pop-Location
}
function Delete-Win32OpenSSH
function Remove-Win32OpenSSHRepo
{
Remove-Item -Path $script:win32OpenSSHPath -Recurse -Force -ErrorAction SilentlyContinue
}
@ -282,7 +288,7 @@ function Copy-LibreSSLSDK
}
}
function Package-OpenSSH
function Start-OpenSSHPackage
{
[CmdletBinding(SupportsShouldProcess=$false)]
param
@ -290,7 +296,7 @@ function Package-OpenSSH
[ValidateSet('x86', 'x64')]
[string]$NativeHostArch = "x64",
[ValidateSet('Debug', 'Release', '')]
[ValidateSet('Debug', 'Release')]
[string]$Configuration = "Release",
# Copy payload to DestinationPath instead of packaging
@ -315,7 +321,7 @@ function Package-OpenSSH
if ($NativeHostArch -ieq 'x86') {
$packageName = "OpenSSH-Win32"
}
while((($service = Get-Service ssh-agent -ErrorAction Ignore) -ne $null) -and ($service.Status -ine 'Stopped'))
while((($service = Get-Service ssh-agent -ErrorAction SilentlyContinue) -ne $null) -and ($service.Status -ine 'Stopped'))
{
Stop-Service ssh-agent -Force
#sleep to wait the servicelog file write
@ -361,8 +367,15 @@ function Package-OpenSSH
}
else {
Remove-Item ($packageDir + '.zip') -Force -ErrorAction SilentlyContinue
Compress-Archive -Path $packageDir -DestinationPath ($packageDir + '.zip')
Write-BuildMsg -AsInfo -Message "Packaged Payload - '$packageDir'.zip"
if(get-command Compress-Archive -ErrorAction SilentlyContinue)
{
Compress-Archive -Path $packageDir -DestinationPath ($packageDir + '.zip')
Write-BuildMsg -AsInfo -Message "Packaged Payload - '$packageDir.zip'"
}
else
{
Write-BuildMsg -AsInfo -Message "Packaged Payload not compressed."
}
}
Remove-Item $packageDir -Recurse -Force -ErrorAction SilentlyContinue
@ -373,13 +386,20 @@ function Package-OpenSSH
}
else {
Remove-Item ($symbolsDir + '.zip') -Force -ErrorAction SilentlyContinue
Compress-Archive -Path $symbolsDir -DestinationPath ($symbolsDir + '.zip')
Write-BuildMsg -AsInfo -Message "Packaged Symbols - '$symbolsDir'.zip"
if(get-command Compress-Archive -ErrorAction SilentlyContinue)
{
Compress-Archive -Path $symbolsDir -DestinationPath ($symbolsDir + '.zip')
Write-BuildMsg -AsInfo -Message "Packaged Symbols - '$symbolsDir.zip'"
}
else
{
Write-BuildMsg -AsInfo -Message "Packaged Symbols not compressed."
}
}
Remove-Item $symbolsDir -Recurse -Force -ErrorAction SilentlyContinue
}
function Build-OpenSSH
function Start-OpenSSHBuild
{
[CmdletBinding(SupportsShouldProcess=$false)]
param
@ -387,12 +407,11 @@ function Build-OpenSSH
[ValidateSet('x86', 'x64')]
[string]$NativeHostArch = "x64",
[ValidateSet('Debug', 'Release', '')]
[ValidateSet('Debug', 'Release')]
[string]$Configuration = "Release",
[switch]$NoOpenSSL
)
Set-StrictMode -Version Latest
)
$script:BuildLogFile = $null
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
@ -420,9 +439,9 @@ function Build-OpenSSH
$script:win32OpenSSHPath = join-path $script:gitRoot "Win32-OpenSSH"
if (-not (Test-Path (Join-Path $PSScriptRoot LibreSSLSDK)))
{
Clone-Win32OpenSSH
Get-Win32OpenSSHRepo
Copy-LibreSSLSDK
Delete-Win32OpenSSH
Remove-Win32OpenSSHRepo
}
if ($NoOpenSSL)
@ -465,7 +484,7 @@ function Get-BuildLogFile
[ValidateSet('x86', 'x64')]
[string]$NativeHostArch = "x64",
[ValidateSet('Debug', 'Release', '')]
[ValidateSet('Debug', 'Release')]
[string]$Configuration = "Release"
)
@ -483,122 +502,6 @@ function Get-SolutionFile
return Join-Path -Path $root -ChildPath "contrib\win32\openssh\Win32-OpenSSH.sln"
}
<#
.Synopsis
Deploy all required files to a location and install the binaries
#>
function Install-OpenSSH
{
[CmdletBinding()]
param
(
[ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "",
[ValidateSet('x86', 'x64', '')]
[string]$NativeHostArch = "",
[string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
)
if ($Configuration -eq "")
{
$Configuration = 'Release'
}
if ($NativeHostArch -eq "")
{
$NativeHostArch = 'x64'
if ($env:PROCESSOR_ARCHITECTURE -eq 'x86') {
$NativeHostArch = 'x86'
}
}
Package-OpenSSH -NativeHostArch $NativeHostArch -Configuration $Configuration -DestinationPath $OpenSSHDir
Push-Location $OpenSSHDir
& "$OpenSSHDir\install-sshd.ps1"
& "$OpenSSHDir\ssh-keygen.exe" -A
$keyFiles = Get-ChildItem "$OpenSSHDir\ssh_host_*_key*" | % {
Adjust-HostKeyFileACL -FilePath $_.FullName
}
#machine will be reboot after Install-openssh anyway
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
$newMachineEnvironmentPath = $machinePath
if (-not ($machinePath.ToLower().Contains($OpenSSHDir.ToLower())))
{
$newMachineEnvironmentPath = "$OpenSSHDir;$newMachineEnvironmentPath"
$env:Path = "$OpenSSHDir;$env:Path"
}
# Update machine environment path
if ($newMachineEnvironmentPath -ne $machinePath)
{
[Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE')
}
Set-Service sshd -StartupType Automatic
Set-Service ssh-agent -StartupType Automatic
Pop-Location
Write-Log -Message "OpenSSH installed!"
}
<#
.Synopsis
uninstalled sshd and sshla
#>
function UnInstall-OpenSSH
{
[CmdletBinding()]
param
(
[string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
)
if (-not (Test-Path $OpenSSHDir))
{
return
}
Push-Location $OpenSSHDir
if((Get-Service ssh-agent -ErrorAction Ignore) -ne $null) {
Stop-Service ssh-agent -Force
}
&( "$OpenSSHDir\uninstall-sshd.ps1")
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
$newMachineEnvironmentPath = $machinePath
if ($machinePath.ToLower().Contains($OpenSSHDir.ToLower()))
{
$newMachineEnvironmentPath = $newMachineEnvironmentPath.Replace("$OpenSSHDir;", '')
$env:Path = $env:Path.Replace("$OpenSSHDir;", '')
}
if(Test-Path -Path $OpenSSHDir)
{
Push-Location $OpenSSHDir
&( "$OpenSSHDir\uninstall-sshd.ps1")
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
$newMachineEnvironmentPath = $machinePath
if ($machinePath.ToLower().Contains($OpenSSHDir.ToLower()))
{
$newMachineEnvironmentPath.Replace("$OpenSSHDir;", '')
$env:Path = $env:Path.Replace("$OpenSSHDir;", '')
}
# Update machine environment path
# machine will be reboot after Uninstall-OpenSSH
if ($newMachineEnvironmentPath -ne $machinePath)
{
[Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE')
}
Pop-Location
Remove-Item -Path $OpenSSHDir -Recurse -Force -ErrorAction SilentlyContinue
}
}
Export-ModuleMember -Function Build-OpenSSH, Get-BuildLogFile, Install-OpenSSH, UnInstall-OpenSSH, Package-OpenSSH
Export-ModuleMember -Function Start-OpenSSHBuild, Get-BuildLogFile, Start-OpenSSHPackage

View File

@ -1,20 +1,18 @@
<#
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\OpenSSHUtils -Force
<#
.Synopsis
Finds the root of the git repository
.Outputs
A System.IO.DirectoryInfo for the location of the root.
A System.IO.DirectoryInfo for the location of the root if root is found; otherwise, script root.
.Inputs
None
.Notes
FileNotFoundException is thrown if the current directory does not contain a CMakeLists.txt file.
#>
function Get-RepositoryRoot
{
$currentDir = (Get-Item -Path $PSCommandPath).Directory
{
$start = $currentDir = (Get-Item -Path $PSScriptRoot)
while ($null -ne $currentDir.Parent)
{
$path = Join-Path -Path $currentDir.FullName -ChildPath '.git'
@ -24,147 +22,7 @@ function Get-RepositoryRoot
}
$currentDir = $currentDir.Parent
}
throw new-object System.IO.DirectoryNotFoundException("Could not find the root of the GIT repository")
}
<#
.Synopsis
Set owner of the file to by LOCALSYSTEM account
Set private host key be fully controlled by LOCALSYSTEM and Administrators
Set public host key be fully controlled by LOCALSYSTEM and Administrators, read access by everyone
.Outputs
N/A
.Inputs
FilePath - The path to the file
#>
function Adjust-HostKeyFileACL
{
param (
[parameter(Mandatory=$true)]
[string]$FilePath
)
$myACL = Get-ACL $FilePath
$myACL.SetAccessRuleProtection($True, $FALSE)
Set-Acl -Path $FilePath -AclObject $myACL
$systemAccount = New-Object System.Security.Principal.NTAccount("NT AUTHORITY", "SYSTEM")
$adminAccount = New-Object System.Security.Principal.NTAccount("BUILTIN","Administrators")
$everyoneAccount = New-Object System.Security.Principal.NTAccount("EveryOne")
$myACL = Get-ACL $FilePath
$myACL.SetOwner($systemAccount)
if($myACL.Access)
{
$myACL.Access | % {
if(-not ($myACL.RemoveAccessRule($_)))
{
throw "failed to remove access of $($_.IdentityReference.Value) rule in setup "
}
}
}
$adminACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($adminAccount, "FullControl", "None", "None", "Allow")
$myACL.AddAccessRule($adminACE)
$systemACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($systemAccount, "FullControl", "None", "None", "Allow")
$myACL.AddAccessRule($systemACE)
if($FilePath.EndsWith(".pub"))
{
$everyoneAce = New-Object System.Security.AccessControl.FileSystemAccessRule `
("Everyone", "Read", "None", "None", "Allow")
$myACL.AddAccessRule($everyoneAce)
}
Set-Acl -Path $FilePath -AclObject $myACL
}
<#
.Synopsis
Set owner of the user key file
Set ACL to have private user key be fully controlled by LOCALSYSTEM and Administrators, Read, write access by owner
Set public user key be fully controlled by LOCALSYSTEM and Administrators, Read, write access by owner, read access by everyone
.Outputs
N/A
.Inputs
FilePath - The path to the file
Owner - owner of the file
OwnerPerms - the permissions grant to the owner
#>
function Adjust-UserKeyFileACL
{
param (
[parameter(Mandatory=$true)]
[string]$FilePath,
[System.Security.Principal.NTAccount] $Owner = $null,
[System.Security.AccessControl.FileSystemRights[]] $OwnerPerms = $null
)
$myACL = Get-ACL $FilePath
$myACL.SetAccessRuleProtection($True, $FALSE)
Set-Acl -Path $FilePath -AclObject $myACL
$systemAccount = New-Object System.Security.Principal.NTAccount("NT AUTHORITY", "SYSTEM")
$adminAccount = New-Object System.Security.Principal.NTAccount("BUILTIN","Administrators")
$everyoneAccount = New-Object System.Security.Principal.NTAccount("EveryOne")
$myACL = Get-ACL $FilePath
$actualOwner = $null
if($Owner -eq $null)
{
$actualOwner = New-Object System.Security.Principal.NTAccount($($env:USERDOMAIN), $($env:USERNAME))
}
else
{
$actualOwner = $Owner
}
$myACL.SetOwner($actualOwner)
if($myACL.Access)
{
$myACL.Access | % {
if(-not ($myACL.RemoveAccessRule($_)))
{
throw "failed to remove access of $($_.IdentityReference.Value) rule in setup "
}
}
}
$adminACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($adminAccount, "FullControl", "None", "None", "Allow")
$myACL.AddAccessRule($adminACE)
$systemACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($systemAccount, "FullControl", "None", "None", "Allow")
$myACL.AddAccessRule($systemACE)
if($OwnerPerms)
{
$OwnerPerms | % {
$ownerACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($actualOwner, $_, "None", "None", "Allow")
$myACL.AddAccessRule($ownerACE)
}
}
if($FilePath.EndsWith(".pub"))
{
$everyoneAce = New-Object System.Security.AccessControl.FileSystemAccessRule `
("Everyone", "Read", "None", "None", "Allow")
$myACL.AddAccessRule($everyoneAce)
}
Set-Acl -Path $FilePath -AclObject $myACL
return $start
}
<#
@ -177,9 +35,9 @@ function Adjust-UserKeyFileACL
.Inputs
FilePath - The path to the file
User - account name
Perm - The permission to grant.
Perms - The permission to grant.
#>
function Add-PermissionToFileACL
function Add-PermissionToFileACL
{
param (
[parameter(Mandatory=$true)]
@ -200,8 +58,8 @@ function Add-PermissionToFileACL
$myACL.AddAccessRule($userACE)
}
}
Enable-Privilege SeRestorePrivilege | out-null
Set-Acl -Path $FilePath -AclObject $myACL
}
Export-ModuleMember -Function Get-RepositoryRoot, Add-PermissionToFileACL, Adjust-HostKeyFileACL, Adjust-UserKeyFileACL
Export-ModuleMember -Function Get-RepositoryRoot, Add-PermissionToFileACL

View File

@ -1,5 +1,7 @@
$ErrorActionPreference = 'Stop'
Import-Module $PSScriptRoot\OpenSSHCommonUtils.psm1 -DisableNameChecking -Force
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\OpenSSHCommonUtils.psm1 -Force
Import-Module $PSScriptRoot\OpenSSHUtils -Force
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
# test environment parameters initialized with defaults
@ -17,23 +19,28 @@ $Script:E2ETestResultsFile = Join-Path $TestDataPath $E2ETestResultsFileName
$Script:UnitTestResultsFile = Join-Path $TestDataPath $UnitTestResultsFileName
$Script:TestSetupLogFile = Join-Path $TestDataPath $TestSetupLogFileName
$Script:E2ETestDirectory = Join-Path $repositoryRoot.FullName -ChildPath "regress\pesterTests"
$Script:WindowsInBox = $false
<#
.Synopsis
Setup-OpenSSHTestEnvironment
Set-OpenSSHTestEnvironment
TODO - split these steps into client and server side
#>
function Setup-OpenSSHTestEnvironment
function Set-OpenSSHTestEnvironment
{
[CmdletBinding()]
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param
(
[switch] $Quiet,
(
[string] $OpenSSHBinPath,
[string] $TestDataPath = "$env:SystemDrive\OpenSSHTests",
[Boolean] $DebugMode = $false
)
if($PSBoundParameters.ContainsKey("Verbose"))
{
$verboseInfo = ($PSBoundParameters['Verbose']).IsPresent
}
if($Global:OpenSSHTestInfo -ne $null)
{
$Global:OpenSSHTestInfo.Clear()
@ -65,41 +72,30 @@ function Setup-OpenSSHTestEnvironment
#if user does not set path, pick it up
if([string]::IsNullOrEmpty($OpenSSHBinPath))
{
$sshcmd = get-command ssh.exe -ErrorAction Ignore
$sshcmd = get-command ssh.exe -ErrorAction SilentlyContinue
if($sshcmd -eq $null)
{
Throw "Cannot find ssh.exe. Please specify -OpenSSHBinPath to the OpenSSH installed location."
}
elseif($Quiet)
{
$dirToCheck = split-path $sshcmd.Path
$script:OpenSSHBinPath = $dirToCheck
}
else
{
$dirToCheck = split-path $sshcmd.Path
$message = "Do you want to test openssh installed at $($dirToCheck)? [Yes] Y; [No] N (default is `"Y`")"
$response = Read-Host -Prompt $message
if( ($response -eq "") -or ($response -ieq "Y") -or ($response -ieq "Yes") )
{
$script:OpenSSHBinPath = $dirToCheck
}
elseif( ($response -ieq "N") -or ($response -ieq "No") )
$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
}
else
{
Throw "User entered invalid option ($response). Please specify -OpenSSHBinPath to the OpenSSH installed location"
}
$script:OpenSSHBinPath = $dirToCheck
}
}
else
{
if (-not (Test-Path (Join-Path $OpenSSHBinPath ssh.exe) -PathType Leaf))
{
Throw "Cannot find OpenSSH binaries under $OpenSSHBinPath. Please specify -OpenSSHBinPathto the OpenSSH installed location"
Throw "Cannot find OpenSSH binaries under $OpenSSHBinPath. Please specify -OpenSSHBinPath to the OpenSSH installed location"
}
else
{
@ -113,7 +109,15 @@ function Setup-OpenSSHTestEnvironment
$env:Path = "$($script:OpenSSHBinPath);$($env:path)"
}
$warning = @"
$acl = get-acl (join-path $script:OpenSSHBinPath "ssh.exe")
if($acl.Owner -ieq "NT SERVICE\TrustedInstaller")
{
$Script:WindowsInBox = $true
$Global:OpenSSHTestInfo.Add("WindowsInBox", $true)
}
$description = @"
WARNING: Following changes will be made to OpenSSH configuration
- sshd_config will be backed up as sshd_config.ori
- will be replaced with a test sshd_config
@ -125,21 +129,15 @@ WARNING: Following changes will be made to OpenSSH configuration
- $HOME\.ssh\known_hosts will be modified with test host key entry
- test accounts - ssouser, pubkeyuser, and passwduser will be added
- Setup single signon for ssouser
- To cleanup - Run Cleanup-OpenSSHTestEnvironment
"@
if (-not $Quiet) {
Write-Warning $warning
$continue = Read-Host -Prompt "Do you want to continue with the above changes? [Yes] Y; [No] N (default is `"Y`")"
if( ($continue -ieq "N") -or ($continue -ieq "No") )
{
Write-Host "User decided not to make the changes."
return
}
elseif(($continue -ne "") -and ($continue -ine "Y") -and ($continue -ine "Yes"))
{
Throw "User entered invalid option ($continue). Exit now."
}
- To cleanup - Run Clear-OpenSSHTestEnvironment
"@
$prompt = "Are you sure you want to perform the above operations?"
$caption = $description
if(-not $pscmdlet.ShouldProcess($description, $prompt, $caption))
{
Write-Host "User decided not to make the changes."
return
}
Install-OpenSSHTestDependencies
@ -154,9 +152,15 @@ WARNING: Following changes will be made to OpenSSH configuration
if (-not (Test-Path $backupConfigPath -PathType Leaf)) {
Copy-Item (Join-Path $script:OpenSSHBinPath sshd_config) $backupConfigPath -Force
}
$targetsshdConfig = Join-Path $script:OpenSSHBinPath sshd_config
# copy new sshd_config
Copy-Item (Join-Path $Script:E2ETestDirectory sshd_config) (Join-Path $script:OpenSSHBinPath sshd_config) -Force
if($Script:WindowsInBox -and (Test-Path $targetsshdConfig))
{
$currentUser = New-Object System.Security.Principal.NTAccount($($env:USERDOMAIN), $($env:USERNAME))
Add-PermissionToFileACL -FilePath $targetsshdConfig -User $currentUser -Perm "Read,Write"
}
Copy-Item (Join-Path $Script:E2ETestDirectory sshd_config) $targetsshdConfig -Force
Start-Service ssh-agent
@ -164,12 +168,18 @@ WARNING: Following changes will be made to OpenSSH configuration
Copy-Item "$($Script:E2ETestDirectory)\sshtest*hostkey*" $script:OpenSSHBinPath -Force
Get-ChildItem "$($script:OpenSSHBinPath)\sshtest*hostkey*"| % {
#workaround for the cariggage new line added by git before copy them
(Get-Content $_.FullName -Raw).Replace("`r`n","`n") | Set-Content $_.FullName -Force
Adjust-HostKeyFileACL -FilePath $_.FullName
if (-not ($_.Name.EndsWith(".pub"))) {
#register private key with agent
ssh-add-hostkey.ps1 $_.FullName
}
$filePath = "$($_.FullName)"
$con = (Get-Content $filePath | Out-String).Replace("`r`n","`n")
Set-Content -Path $filePath -Value "$con"
if (-not ($_.Name.EndsWith(".pub")))
{
Repair-SshdHostKeyPermission -FilePath $_.FullName -confirm:$false
if($psversiontable.BuildVersion.Major -gt 6)
{
#register private key with agent
ssh-add-hostkey.ps1 $_.FullName
}
}
}
Restart-Service sshd -Force
@ -192,7 +202,7 @@ WARNING: Following changes will be made to OpenSSH configuration
Copy-Item $sshConfigFilePath (Join-Path $dotSshDirectoryPath config.ori) -Force
}
Copy-Item (Join-Path $Script:E2ETestDirectory ssh_config) $sshConfigFilePath -Force
Adjust-UserKeyFileACL -FilePath $sshConfigFilePath -OwnerPerms "Read,Write"
Repair-UserSshConfigPermission -FilePath $sshConfigFilePath -confirm:$false
# create test accounts
#TODO - this is Windows specific. Need to be in PAL
@ -210,21 +220,22 @@ WARNING: Following changes will be made to OpenSSH configuration
}
}
#setup single sign on for ssouser
#setup single sign on for ssouser
$ssouserProfile = Get-LocalUserProfile -User $SSOUser
$Global:OpenSSHTestInfo.Add("SSOUserProfile", $ssouserProfile)
$Global:OpenSSHTestInfo.Add("PubKeyUserProfile", (Get-LocalUserProfile -User $PubKeyUser))
$Global:OpenSSHTestInfo.Add("PubKeyUserProfile", (Get-LocalUserProfile -User $PubKeyUser))
New-Item -ItemType Directory -Path (Join-Path $ssouserProfile .ssh) -Force -ErrorAction SilentlyContinue | out-null
$authorizedKeyPath = Join-Path $ssouserProfile .ssh\authorized_keys
$testPubKeyPath = Join-Path $Script:E2ETestDirectory sshtest_userssokey_ed25519.pub
$testPubKeyPath = Join-Path $Script:E2ETestDirectory sshtest_userssokey_ed25519.pub
Copy-Item $testPubKeyPath $authorizedKeyPath -Force -ErrorAction SilentlyContinue
$owner = New-Object System.Security.Principal.NTAccount($SSOUser)
Adjust-UserKeyFileACL -FilePath $authorizedKeyPath -Owner $owner -OwnerPerms "Read","Write"
Add-PermissionToFileACL -FilePath $authorizedKeyPath -User "NT Service\sshd" -Perm "Read"
Repair-AuthorizedKeyPermission -FilePath $authorizedKeyPath -confirm:$false
$testPriKeypath = Join-Path $Script:E2ETestDirectory sshtest_userssokey_ed25519
(Get-Content $testPriKeypath -Raw).Replace("`r`n","`n") | Set-Content $testPriKeypath -Force
Adjust-UserKeyFileACL -FilePath $testPriKeypath -OwnerPerms "Read, Write"
$con = (Get-Content $testPriKeypath | Out-String).Replace("`r`n","`n")
Set-Content -Path $testPriKeypath -Value "$con"
cmd /c "ssh-add -D 2>&1 >> $Script:TestSetupLogFile"
Repair-UserKeyPermission -FilePath $testPriKeypath -confirm:$false
cmd /c "ssh-add $testPriKeypath 2>&1 >> $Script:TestSetupLogFile"
Backup-OpenSSHTestInfo
}
@ -256,6 +267,19 @@ function Install-OpenSSHTestDependencies
{
[CmdletBinding()]
param ()
#$isOpenSSHUtilsAvailable = Get-Module 'OpenSSHUtils' -ListAvailable
#if (-not ($isOpenSSHUtilsAvailable))
#{
Write-Log -Message "Installing Module OpenSSHUtils..."
Install-OpenSSHUtilsModule -SourceDir $PSScriptRoot
#}
Import-Module OpensshUtils -Force
if($Script:WindowsInBox)
{
return
}
# Install chocolatey
if(-not (Get-Command "choco" -ErrorAction SilentlyContinue))
@ -267,10 +291,66 @@ function Install-OpenSSHTestDependencies
$isModuleAvailable = Get-Module 'Pester' -ListAvailable
if (-not ($isModuleAvailable))
{
Write-Log -Message "Installing Pester..."
choco install Pester -y --force --limitoutput 2>&1 >> $Script:TestSetupLogFile
Write-Log -Message "Installing Pester..."
choco install Pester -y --force --limitoutput 2>&1 >> $Script:TestSetupLogFile
}
}
function Install-OpenSSHUtilsModule
{
[CmdletBinding()]
param(
[string]$TargetDir = (Join-Path -Path $env:ProgramFiles -ChildPath "WindowsPowerShell\Modules\OpenSSHUtils"),
[string]$SourceDir)
$manifestFile = Join-Path -Path $SourceDir -ChildPath OpenSSHUtils.psd1
$moduleFile = Join-Path -Path $SourceDir -ChildPath OpenSSHUtils.psm1
$targetDirectory = $TargetDir
$manifest = Test-ModuleManifest -Path $manifestFile -WarningAction SilentlyContinue -ErrorAction Stop
if ($PSVersionTable.PSVersion.Major -ge 5)
{
$targetDirectory = Join-Path -Path $targetDir -ChildPath $manifest.Version.ToString()
}
$modulePath = Join-Path -Path $env:ProgramFiles -ChildPath WindowsPowerShell\Modules
if(-not (Test-Path $targetDirectory -PathType Container))
{
New-Item -ItemType Directory -Path $targetDirectory -Force -ErrorAction SilentlyContinue | out-null
}
Copy-item $manifestFile -Destination $targetDirectory -Force -ErrorAction SilentlyContinue | out-null
Copy-item $moduleFile -Destination $targetDirectory -Force -ErrorAction SilentlyContinue | out-null
if ($PSVersionTable.PSVersion.Major -lt 4)
{
$modulePaths = [Environment]::GetEnvironmentVariable('PSModulePath', 'Machine') -split ';'
if ($modulePaths -notcontains $modulePath)
{
Write-Verbose -Message "Adding '$modulePath' to PSModulePath."
$modulePaths = @(
$modulePath
$modulePaths
)
$newModulePath = $modulePaths -join ';'
[Environment]::SetEnvironmentVariable('PSModulePath', $newModulePath, 'Machine')
$env:PSModulePath += ";$modulePath"
}
}
}
function Uninstall-OpenSSHUtilsModule
{
[CmdletBinding()]
param([string]$TargetDir = (Join-Path -Path $env:ProgramFiles -ChildPath "WindowsPowerShell\Modules\OpenSSHUtils"))
if(Test-Path $TargetDir -PathType Container)
{
Remove-item $TargetDir -Recurse -Force -ErrorAction SilentlyContinue | out-null
}
}
<#
.Synopsis
Get-UserSID
@ -296,12 +376,12 @@ function Get-UserSID
<#
.Synopsis
Cleanup-OpenSSHTestEnvironment
Clear-OpenSSHTestEnvironment
#>
function Cleanup-OpenSSHTestEnvironment
function Clear-OpenSSHTestEnvironment
{
if($Global:OpenSSHTestInfo -eq $null) {
throw "OpenSSHTestInfo is not set. Did you run Setup-OpenSShTestEnvironment?"
throw "OpenSSHTestInfo is not set. Did you run Set-OpenSShTestEnvironment?"
}
$sshBinPath = $Global:OpenSSHTestInfo["OpenSSHBinPath"]
@ -356,6 +436,13 @@ function Cleanup-OpenSSHTestEnvironment
$Global:OpenSSHTestInfo.Clear()
$Global:OpenSSHTestInfo = $null
}
$isOpenSSHUtilsAvailable = Get-Module 'OpenSSHUtils' -ListAvailable
if ($isOpenSSHUtilsAvailable)
{
Write-Log -Message "Uninstalling Module OpenSSHUtils..."
Uninstall-OpenSSHUtilsModule
}
}
<#
@ -418,12 +505,13 @@ function Get-UnitTestDirectory
.Synopsis
Run OpenSSH pester tests.
#>
function Run-OpenSSHE2ETest
function Invoke-OpenSSHE2ETest
{
# Discover all CI tests and run them.
# Discover all CI tests and run them.
Import-Module pester -force -global
Push-Location $Script:E2ETestDirectory
Write-Log -Message "Running OpenSSH E2E tests..."
$testFolders = Get-ChildItem *.tests.ps1 -Recurse | ForEach-Object{ Split-Path $_.FullName} | Sort-Object -Unique
$testFolders = @(Get-ChildItem *.tests.ps1 -Recurse | ForEach-Object{ Split-Path $_.FullName} | Sort-Object -Unique)
Invoke-Pester $testFolders -OutputFormat NUnitXml -OutputFile $Script:E2ETestResultsFile -Tag 'CI'
Pop-Location
}
@ -432,35 +520,45 @@ function Run-OpenSSHE2ETest
.Synopsis
Run openssh unit tests.
#>
function Run-OpenSSHUnitTest
function Invoke-OpenSSHUnitTest
{
# Discover all CI tests and run them.
if([string]::Isnullorempty($Script:UnitTestDirectory))
{
$Script:UnitTestDirectory = $OpenSSHTestInfo["UnitTestDirectory"]
}
Push-Location $Script:UnitTestDirectory
Write-Log -Message "Running OpenSSH unit tests..."
if (Test-Path $Script:UnitTestResultsFile)
if (Test-Path $Script:UnitTestResultsFile)
{
$null = Remove-Item -Path $Script:UnitTestResultsFile -Force -ErrorAction SilentlyContinue
}
$testFolders = Get-ChildItem unittest-*.exe -Recurse -Exclude unittest-sshkey.exe,unittest-kex.exe |
$testFolders = Get-ChildItem -filter unittest-*.exe -Recurse -Exclude unittest-sshkey.exe,unittest-kex.exe |
ForEach-Object{ Split-Path $_.FullName} |
Sort-Object -Unique
$testfailed = $false
if ($testFolders -ne $null)
{
$testFolders | % {
Push-Location $_
$testFolders | % {
$unittestFile = "$(Split-Path $_ -Leaf).exe"
Write-log "Running OpenSSH unit $unittestFile ..."
& .\$unittestFile >> $Script:UnitTestResultsFile
$unittestFilePath = join-path $_ $unittestFile
$Error.clear()
$LASTEXITCODE=0
if(Test-Path $unittestFilePath -pathtype leaf)
{
Push-Location $_
Write-Log "Running OpenSSH unit $unittestFile ..."
& "$unittestFilePath" >> $Script:UnitTestResultsFile
Pop-Location
}
$errorCode = $LASTEXITCODE
if ($errorCode -ne 0)
{
$testfailed = $true
$errorMessage = "$($_.FullName) test failed for OpenSSH.`nExitCode: $errorCode. Detail test log is at $($Script:UnitTestResultsFile)."
$errorMessage = "$_ test failed for OpenSSH.`nExitCode: $errorCode. Detail test log is at $($Script:UnitTestResultsFile)."
Write-Warning $errorMessage
}
Pop-Location
}
}
}
Pop-Location
@ -475,7 +573,7 @@ function Backup-OpenSSHTestInfo
)
if ($Global:OpenSSHTestInfo -eq $null) {
Throw "`$OpenSSHTestInfo is null. Did you run Setup-OpenSSHTestEnvironment yet?"
Throw "`$OpenSSHTestInfo is null. Did you run Set-OpenSSHTestEnvironment yet?"
}
$testInfo = $Global:OpenSSHTestInfo
@ -492,7 +590,7 @@ function Backup-OpenSSHTestInfo
}
}
function Recover-OpenSSHTestInfo
function Restore-OpenSSHTestInfo
{
param
(
@ -538,4 +636,4 @@ function Write-Log
}
}
Export-ModuleMember -Function Setup-OpenSSHTestEnvironment, Cleanup-OpenSSHTestEnvironment, Run-OpenSSHUnitTest, Run-OpenSSHE2ETest, Backup-OpenSSHTestInfo, Recover-OpenSSHTestInfo
Export-ModuleMember -Function Set-OpenSSHTestEnvironment, Clear-OpenSSHTestEnvironment, Invoke-OpenSSHUnitTest, Invoke-OpenSSHE2ETest, Backup-OpenSSHTestInfo, Restore-OpenSSHTestInfo

View File

@ -2,48 +2,48 @@
<#
.Synopsis
Get-UserAccount
Get-UserSID
#>
function Get-UserAccount
{
[CmdletBinding(DefaultParameterSetName='SidString')]
function Get-UserSID
{
[CmdletBinding(DefaultParameterSetName='User')]
param
( [parameter(Mandatory=$true, ParameterSetName="SidString")]
[ValidateNotNullOrEmpty()]
[string]$UserSid,
( [parameter(Mandatory=$true, ParameterSetName="User")]
[ValidateNotNull()]
[System.Security.Principal.NTAccount]$User,
[parameter(Mandatory=$true, ParameterSetName="WellKnownSidType")]
[ValidateNotNull()]
[System.Security.Principal.WellKnownSidType]$WellKnownSidType
)
try
{
if($PSBoundParameters.ContainsKey("UserSid"))
{
if($PSBoundParameters.ContainsKey("User"))
{
$objSID = New-Object System.Security.Principal.SecurityIdentifier($UserSid)
$objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
$sid = $User.Translate([System.Security.Principal.SecurityIdentifier])
}
elseif($PSBoundParameters.ContainsKey("WellKnownSidType"))
{
{
$sid = New-Object System.Security.Principal.SecurityIdentifier($WellKnownSidType, $null)
$objUser = $sid.Translate( [System.Security.Principal.NTAccount])
}
$objUser
$sid
}
catch {
return $null
}
}
# get the local System user
$systemAccount = Get-UserAccount -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::LocalSystemSid)
$systemSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::LocalSystemSid)
# get the Administrators group
$adminsAccount = Get-UserAccount -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid)
$adminsSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid)
# get the everyone
$everyone = Get-UserAccount -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::WorldSid)
$everyoneSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::WorldSid)
$currentUser = New-Object System.Security.Principal.NTAccount($($env:USERDOMAIN), $($env:USERNAME))
$sshdAccount = New-Object System.Security.Principal.NTAccount("NT SERVICE","sshd")
$sshdSid = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-80-3847866527-469524349-687026318-516638107-1125189541")
$currentUserSid = Get-UserSID -User "$($env:USERDOMAIN)\$($env:USERNAME)"
#Taken from P/Invoke.NET with minor adjustments.
$definition = @'
@ -112,7 +112,7 @@ function Repair-SshdConfigPermission
[ValidateNotNullOrEmpty()]
[string]$FilePath)
Repair-FilePermission -Owners $systemAccount,$adminsAccount -ReadAccessNeeded $sshdAccount @psBoundParameters
Repair-FilePermission -Owners $systemSid,$adminsSid -ReadAccessNeeded $sshdSid @psBoundParameters
}
<#
@ -126,18 +126,18 @@ function Repair-SshdHostKeyPermission
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$FilePath)
[ValidateNotNullOrEmpty()]
[string]$FilePath)
if($PSBoundParameters["FilePath"].EndsWith(".pub"))
{
$PSBoundParameters["FilePath"] = $PSBoundParameters["FilePath"].Replace(".pub", "")
}
Repair-FilePermission -Owners $systemAccount,$adminsAccount -ReadAccessNeeded $sshdAccount @psBoundParameters
Repair-FilePermission -Owners $systemSid,$adminsSid -ReadAccessNeeded $sshdSid @psBoundParameters
$PSBoundParameters["FilePath"] += ".pub"
Repair-FilePermission -Owners $systemAccount,$adminsAccount -ReadAccessOK $everyone -ReadAccessNeeded $sshdAccount @psBoundParameters
$PSBoundParameters["FilePath"] += ".pub"
Repair-FilePermission -Owners $systemSid,$adminsSid -ReadAccessOK $everyoneSid -ReadAccessNeeded $sshdSid @psBoundParameters
}
<#
@ -167,20 +167,14 @@ function Repair-AuthorizedKeyPermission
{
$userProfilePath = $properties.ProfileImagePath
}
$fullPath -ieq "$userProfilePath\.ssh\authorized_keys"
$userProfilePath = $userProfilePath.Replace("\", "\\")
$fullPath -match "^$userProfilePath[\\|\W|\w]+authorized_keys$"
}
if($profileItem)
{
$userSid = $profileItem.PSChildName
$account = Get-UserAccount -UserSid $userSid
if($account)
{
Repair-FilePermission -Owners $account,$adminsAccount,$systemAccount -AnyAccessOK $account -ReadAccessNeeded $sshdAccount @psBoundParameters
}
else
{
Write-host "Can't translate $userSid to an account. skip checking $fullPath..." -ForegroundColor Yellow
}
$userSid = $profileItem.PSChildName
Repair-FilePermission -Owners $userSid,$adminsSid,$systemSid -AnyAccessOK $userSid -ReadAccessNeeded $sshdSid @psBoundParameters
}
else
{
@ -202,16 +196,16 @@ function Repair-UserKeyPermission
[parameter(Mandatory=$true, Position = 0)]
[ValidateNotNullOrEmpty()]
[string]$FilePath,
[System.Security.Principal.NTAccount] $User = $currentUser)
[System.Security.Principal.SecurityIdentifier] $UserSid = $currentUserSid)
if($PSBoundParameters["FilePath"].EndsWith(".pub"))
{
$PSBoundParameters["FilePath"] = $PSBoundParameters["FilePath"].Replace(".pub", "")
}
Repair-FilePermission -Owners $User, $adminsAccount,$systemAccount -AnyAccessOK $User @psBoundParameters
Repair-FilePermission -Owners $UserSid, $adminsSid,$systemSid -AnyAccessOK $UserSid @psBoundParameters
$PSBoundParameters["FilePath"] += ".pub"
Repair-FilePermission -Owners $User, $adminsAccount,$systemAccount -AnyAccessOK $User -ReadAccessOK $everyone @psBoundParameters
Repair-FilePermission -Owners $UserSid, $adminsSid,$systemSid -AnyAccessOK $UserSid -ReadAccessOK $everyoneSid @psBoundParameters
}
<#
@ -225,8 +219,9 @@ function Repair-UserSshConfigPermission
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$FilePath)
Repair-FilePermission -Owners $currentUser,$adminsAccount,$systemAccount -AnyAccessOK $currentUser @psBoundParameters
[string]$FilePath,
[System.Security.Principal.SecurityIdentifier] $UserSid = $currentUserSid)
Repair-FilePermission -Owners $UserSid,$adminsSid,$systemSid -AnyAccessOK $UserSid @psBoundParameters
}
<#
@ -242,10 +237,11 @@ function Repair-FilePermission
[ValidateNotNullOrEmpty()]
[string]$FilePath,
[ValidateNotNull()]
[System.Security.Principal.NTAccount[]] $Owners = $currentUser,
[System.Security.Principal.NTAccount[]] $AnyAccessOK,
[System.Security.Principal.NTAccount[]] $ReadAccessOK,
[System.Security.Principal.NTAccount[]] $ReadAccessNeeded
[System.Security.Principal.SecurityIdentifier[]] $Owners = $currentUserSid,
[System.Security.Principal.SecurityIdentifier[]] $AnyAccessOK = $null,
[System.Security.Principal.SecurityIdentifier[]] $FullAccessNeeded = $null,
[System.Security.Principal.SecurityIdentifier[]] $ReadAccessOK = $null,
[System.Security.Principal.SecurityIdentifier[]] $ReadAccessNeeded = $null
)
if(-not (Test-Path $FilePath -PathType Leaf))
@ -275,10 +271,11 @@ function Repair-FilePermissionInternal {
[ValidateNotNullOrEmpty()]
[string]$FilePath,
[ValidateNotNull()]
[System.Security.Principal.NTAccount[]] $Owners = $currentUser,
[System.Security.Principal.NTAccount[]] $AnyAccessOK,
[System.Security.Principal.NTAccount[]] $ReadAccessOK,
[System.Security.Principal.NTAccount[]] $ReadAccessNeeded
[System.Security.Principal.SecurityIdentifier[]] $Owners = $currentUserSid,
[System.Security.Principal.SecurityIdentifier[]] $AnyAccessOK = $null,
[System.Security.Principal.SecurityIdentifier[]] $FullAccessNeeded = $null,
[System.Security.Principal.SecurityIdentifier[]] $ReadAccessOK = $null,
[System.Security.Principal.SecurityIdentifier[]] $ReadAccessNeeded = $null
)
$acl = Get-Acl $FilePath
@ -286,26 +283,19 @@ function Repair-FilePermissionInternal {
$health = $true
$paras = @{}
$PSBoundParameters.GetEnumerator() | % { if((-not $_.key.Contains("Owners")) -and (-not $_.key.Contains("Access"))) { $paras.Add($_.key,$_.Value) } }
$validOwner = $owners | ? { $_.equals([System.Security.Principal.NTAccount]$acl.owner)}
if($validOwner -eq $null)
{
$caption = "Current owner: '$($acl.Owner)'. '$($Owners[0])' should own '$FilePath'."
$currentOwnerSid = Get-UserSid -User $acl.owner
if($owners -notcontains $currentOwnerSid)
{
$newOwner = Get-UserAccount -User $Owners[0]
$caption = "Current owner: '$($acl.Owner)'. '$newOwner' should own '$FilePath'."
$prompt = "Shall I set the file owner?"
$description = "Set '$($Owners[0])' as owner of '$FilePath'."
$description = "Set '$newOwner' as owner of '$FilePath'."
if($pscmdlet.ShouldProcess($description, $prompt, $caption))
{
{
Enable-Privilege SeRestorePrivilege | out-null
$acl.SetOwner($Owners[0])
Set-Acl -Path $FilePath -AclObject $acl -ErrorVariable e -Confirm:$false
if($e)
{
Write-Warning "Set owner failed with error: $($e[0].ToString())."
}
else
{
Write-Host "'$($Owners[0])' now owns '$FilePath'. " -ForegroundColor Green
}
$acl.SetOwner($newOwner)
Set-Acl -Path $FilePath -AclObject $acl -Confirm:$false
}
else
{
@ -319,52 +309,126 @@ function Repair-FilePermissionInternal {
$ReadAccessPerm = ([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Read.value__) -bor `
([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Synchronize.value__)
$FullControlPerm = [System.UInt32] [System.Security.AccessControl.FileSystemRights]::FullControl.value__
#system and admin groups can have any access to the file; plus the account in the AnyAccessOK list
$realAnyAccessOKList = $AnyAccessOK + @($systemAccount, $adminsAccount)
#if accounts in the ReadAccessNeeded already part of dacl, they are okay; need to make sure they have read access only
$realReadAcessOKList = $ReadAccessOK + $ReadAccessNeeded
$realAnyAccessOKList = @($systemSid, $adminsSid)
if($AnyAccessOK)
{
$realAnyAccessOKList += $AnyAccessOK
}
$realFullAccessNeeded = $FullAccessNeeded
$realReadAccessNeeded = $ReadAccessNeeded
if($realFullAccessNeeded -contains $everyoneSid)
{
$realFullAccessNeeded = @($everyoneSid)
$realReadAccessNeeded = $null
}
if($realReadAccessNeeded -contains $everyoneSid)
{
$realReadAccessNeeded = @($everyoneSid)
}
#this is orginal list requested by the user, the account will be removed from the list if they already part of the dacl
$realReadAccessNeeded = $ReadAccessNeeded
if($realReadAccessNeeded)
{
$realReadAccessNeeded = $realReadAccessNeeded | ? { ($_ -ne $null) -and ($realFullAccessNeeded -notcontains $_) }
}
#if accounts in the ReadAccessNeeded or $realFullAccessNeeded already part of dacl, they are okay;
#need to make sure they have read access only
$realReadAcessOKList = $ReadAccessOK + $realReadAccessNeeded
foreach($a in $acl.Access)
{
if($realAnyAccessOKList -and (($realAnyAccessOKList | ? { $_.equals($a.IdentityReference)}) -ne $null))
$IdentityReferenceSid = Get-UserSid -User $a.IdentityReference
if($IdentityReferenceSid -eq $null)
{
$idRefShortValue = ($a.IdentityReference.Value).split('\')[-1]
$IdentityReferenceSid = Get-UserSID -User $idRefShortValue
if($IdentityReferenceSid -eq $null)
{
Write-Warning "Can't translate '$idRefShortValue'. "
continue
}
}
if($realFullAccessNeeded -contains ($IdentityReferenceSid))
{
$realFullAccessNeeded = $realFullAccessNeeded | ? { ($_ -ne $null) -and (-not $_.Equals($IdentityReferenceSid)) }
if($realReadAccessNeeded)
{
$realReadAccessNeeded = $realReadAccessNeeded | ? { ($_ -ne $null) -and (-not $_.Equals($IdentityReferenceSid)) }
}
if (($a.AccessControlType.Equals([System.Security.AccessControl.AccessControlType]::Allow)) -and `
((([System.UInt32]$a.FileSystemRights.value__) -band $FullControlPerm) -eq $FullControlPerm))
{
continue;
}
#update the account to full control
if($a.IsInherited)
{
if($needChange)
{
Enable-Privilege SeRestorePrivilege | out-null
Set-Acl -Path $FilePath -AclObject $acl -Confirm:$false
}
return Remove-RuleProtection @paras
}
$caption = "'$($a.IdentityReference)' has the following access to '$FilePath': '$($a.AccessControlType)'-'$($a.FileSystemRights)'."
$prompt = "Shall I make it Allow FullControl?"
$description = "Grant '$($a.IdentityReference)' FullControl access to '$FilePath'. "
if($pscmdlet.ShouldProcess($description, $prompt, $caption))
{
$needChange = $true
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule `
($IdentityReferenceSid, "FullControl", "None", "None", "Allow")
$acl.SetAccessRule($ace)
Write-Host "'$($a.IdentityReference)' now has FullControl access to '$FilePath'. " -ForegroundColor Green
}
else
{
$health = $false
if(-not $PSBoundParameters.ContainsKey("WhatIf"))
{
Write-Host "'$($a.IdentityReference)' still has these access to '$FilePath': '$($a.AccessControlType)'-'$($a.FileSystemRights)'." -ForegroundColor Yellow
}
}
}
elseif(($realAnyAccessOKList -contains $everyoneSid) -or ($realAnyAccessOKList -contains $IdentityReferenceSid))
{
#ignore those accounts listed in the AnyAccessOK list.
continue;
}
#If everyone is in the ReadAccessOK list, any user can have read access;
# below block make sure they are granted Read access only
elseif($realReadAcessOKList -and ((($realReadAcessOKList | ? { $_.Equals($everyone)}) -ne $null) -or `
(($realReadAcessOKList | ? { $_.equals($a.IdentityReference)}) -ne $null)))
elseif(($realReadAcessOKList -contains $everyoneSid) -or ($realReadAcessOKList -contains $IdentityReferenceSid))
{
if($realReadAccessNeeded -and ($a.IdentityReference.Equals($everyone)))
if($realReadAccessNeeded -and ($IdentityReferenceSid.Equals($everyoneSid)))
{
$realReadAccessNeeded=@()
$realReadAccessNeeded= $null
}
elseif($realReadAccessNeeded)
{
$realReadAccessNeeded = $realReadAccessNeeded | ? { -not $_.Equals($a.IdentityReference) }
$realReadAccessNeeded = $realReadAccessNeeded | ? { ($_ -ne $null ) -and (-not $_.Equals($IdentityReferenceSid)) }
}
if (-not ($a.AccessControlType.Equals([System.Security.AccessControl.AccessControlType]::Allow)) -or `
(-not (([System.UInt32]$a.FileSystemRights.value__) -band (-bnot $ReadAccessPerm))))
{
continue;
}
}
if($a.IsInherited)
{
if($needChange)
{
Enable-Privilege SeRestorePrivilege | out-null
Set-Acl -Path $FilePath -AclObject $acl -ErrorVariable e -Confirm:$false
if($e)
{
Write-Warning "Repair permission failed with error: $($e[0].ToString())."
}
Set-Acl -Path $FilePath -AclObject $acl -Confirm:$false
}
return Remove-RuleProtection @paras
@ -375,29 +439,12 @@ function Repair-FilePermissionInternal {
if($pscmdlet.ShouldProcess($description, $prompt, $caption))
{
$needChange = $true
if(Get-UserSID -User $a.IdentityReference)
{
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule `
($a.IdentityReference, "Read", "None", "None", "Allow")
}
else
{
$idRefShortValue = ($a.IdentityReference.Value).split('\')[-1]
$ruleIdentity = Get-UserSID -User (New-Object Security.Principal.NTAccount $idRefShortValue)
if($ruleIdentity)
{
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule `
($ruleIdentity, "Read", "None", "None", "Allow")
}
else
{
Write-Warning "Can't translate '$idRefShortValue'. "
continue
}
}
$needChange = $true
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule `
($IdentityReferenceSid, "Read", "None", "None", "Allow")
$acl.SetAccessRule($ace)
Write-Host "'$($a.IdentityReference)' now has Read access to '$FilePath'. " -ForegroundColor Green
Write-Host "'$($a.IdentityReference)' now has Read access to '$FilePath'. " -ForegroundColor Green
}
else
{
@ -417,11 +464,7 @@ function Repair-FilePermissionInternal {
if($needChange)
{
Enable-Privilege SeRestorePrivilege | out-null
Set-Acl -Path $FilePath -AclObject $acl -ErrorVariable e -Confirm:$false
if($e)
{
Write-Warning "Repair permission failed with error: $($e[0].ToString())."
}
Set-Acl -Path $FilePath -AclObject $acl -Confirm:$false
}
return Remove-RuleProtection @paras
}
@ -432,25 +475,8 @@ function Repair-FilePermissionInternal {
if($pscmdlet.ShouldProcess($description, $prompt, "$caption."))
{
$needChange = $true
if(Get-UserSID -User $a.IdentityReference)
{
$ace = $a
}
else
{
$idRefShortValue = ($a.IdentityReference.Value).split('\')[-1]
$ruleIdentity = Get-UserSID -User (New-Object Security.Principal.NTAccount $idRefShortValue)
if($ruleIdentity)
{
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule `
($ruleIdentity, $a.FileSystemRights, $a.InheritanceFlags, $a.PropagationFlags, $a.AccessControlType)
}
else
{
Write-Warning "Can't translate '$idRefShortValue'. "
continue
}
}
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule `
($IdentityReferenceSid, $a.FileSystemRights, $a.InheritanceFlags, $a.PropagationFlags, $a.AccessControlType)
if(-not ($acl.RemoveAccessRule($ace)))
{
@ -471,20 +497,55 @@ function Repair-FilePermissionInternal {
}
}
}
if($realFullAccessNeeded)
{
$realFullAccessNeeded | % {
$account = Get-UserAccount -UserSid $_
if($account -eq $null)
{
Write-Warning "'$_' needs FullControl access to '$FilePath', but it can't be translated on the machine."
}
else
{
$caption = "'$account' needs FullControl access to '$FilePath'."
$prompt = "Shall I make the above change?"
$description = "Set '$account' FullControl access to '$FilePath'. "
if($pscmdlet.ShouldProcess($description, $prompt, $caption))
{
$needChange = $true
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule `
($_, "FullControl", "None", "None", "Allow")
$acl.AddAccessRule($ace)
Write-Host "'$account' now has FullControl to '$FilePath'." -ForegroundColor Green
}
else
{
$health = $false
if(-not $PSBoundParameters.ContainsKey("WhatIf"))
{
Write-Host "'$account' does not have FullControl to '$FilePath'." -ForegroundColor Yellow
}
}
}
}
}
#This is the real account list we need to add read access to the file
if($realReadAccessNeeded)
{
$realReadAccessNeeded | % {
if((Get-UserSID -User $_) -eq $null)
$account = Get-UserAccount -UserSid $_
if($account -eq $null)
{
Write-Warning "'$_' needs Read access to '$FilePath', but it can't be translated on the machine."
}
else
{
$caption = "'$_' needs Read access to '$FilePath'."
$caption = "'$account' needs Read access to '$FilePath'."
$prompt = "Shall I make the above change?"
$description = "Set '$_' Read only access to '$FilePath'. "
$description = "Set '$account' Read only access to '$FilePath'. "
if($pscmdlet.ShouldProcess($description, $prompt, $caption))
{
@ -492,14 +553,14 @@ function Repair-FilePermissionInternal {
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule `
($_, "Read", "None", "None", "Allow")
$acl.AddAccessRule($ace)
Write-Host "'$_' now has Read access to '$FilePath'." -ForegroundColor Green
Write-Host "'$account' now has Read access to '$FilePath'." -ForegroundColor Green
}
else
{
$health = $false
if(-not $PSBoundParameters.ContainsKey("WhatIf"))
{
Write-Host "'$_' does not have Read access to '$FilePath'." -ForegroundColor Yellow
Write-Host "'$account' does not have Read access to '$FilePath'." -ForegroundColor Yellow
}
}
}
@ -509,11 +570,7 @@ function Repair-FilePermissionInternal {
if($needChange)
{
Enable-Privilege SeRestorePrivilege | out-null
Set-Acl -Path $FilePath -AclObject $acl -ErrorVariable e -Confirm:$false
if($e)
{
Write-Warning "Repair permission failed with error: $($e[0].ToString())."
}
Set-Acl -Path $FilePath -AclObject $acl -Confirm:$false
}
if($health)
{
@ -565,23 +622,43 @@ function Remove-RuleProtection
}
}
<#
.Synopsis
Get-UserSID
Get-UserAccount
#>
function Get-UserSID
function Get-UserAccount
{
param ([System.Security.Principal.NTAccount]$User)
[CmdletBinding(DefaultParameterSetName='Sid')]
param
( [parameter(Mandatory=$true, ParameterSetName="Sid")]
[ValidateNotNull()]
[System.Security.Principal.SecurityIdentifier]$UserSid,
[parameter(Mandatory=$true, ParameterSetName="WellKnownSidType")]
[ValidateNotNull()]
[System.Security.Principal.WellKnownSidType]$WellKnownSidType
)
try
{
$User.Translate([System.Security.Principal.SecurityIdentifier])
if($PSBoundParameters.ContainsKey("UserSid"))
{
$objUser = $UserSid.Translate([System.Security.Principal.NTAccount])
}
elseif($PSBoundParameters.ContainsKey("WellKnownSidType"))
{
$objSID = New-Object System.Security.Principal.SecurityIdentifier($WellKnownSidType, $null)
$objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
}
$objUser
}
catch {
return $null
}
}
<#
.Synopsis
Enable-Privilege
#>
function Enable-Privilege {
param(
#The privilege to adjust. This set is taken from
@ -606,4 +683,4 @@ function Enable-Privilege {
$type[0]::EnablePrivilege($Privilege, $Disable)
}
Export-ModuleMember -Function Repair-FilePermission, Repair-SshdConfigPermission, Repair-SshdHostKeyPermission, Repair-AuthorizedKeyPermission, Repair-UserKeyPermission, Repair-UserSshConfigPermission
Export-ModuleMember -Function Repair-FilePermission, Repair-SshdConfigPermission, Repair-SshdHostKeyPermission, Repair-AuthorizedKeyPermission, Repair-UserKeyPermission, Repair-UserSshConfigPermission, Enable-Privilege, Get-UserAccount, Get-UserSID

View File

@ -1,4 +1,6 @@
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force -DisableNameChecking
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force
Import-Module OpenSSHUtils -Force
$tC = 1
$tI = 0
$suite = "authorized_keys_fileperm"
@ -6,7 +8,7 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
BeforeAll {
if($OpenSSHTestInfo -eq $null)
{
Throw "`$OpenSSHTestInfo is null. Please run Setup-OpenSSHTestEnvironment to setup test environment."
Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments."
}
$testDir = "$($OpenSSHTestInfo["TestDataPath"])\$suite"
@ -22,17 +24,31 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
$ssouser = $OpenSSHTestInfo["SSOUser"]
$PwdUser = $OpenSSHTestInfo["PasswdUser"]
$ssouserProfile = $OpenSSHTestInfo["SSOUserProfile"]
Remove-Item -Path (Join-Path $testDir "*$fileName") -Force -ErrorAction ignore
Remove-Item -Path (Join-Path $testDir "*$fileName") -Force -ErrorAction SilentlyContinue
$platform = Get-Platform
$skip = ($platform -eq [PlatformType]::Windows) -and ($PSVersionTable.PSVersion.Major -le 2)
if(($platform -eq [PlatformType]::Windows) -and ($psversiontable.BuildVersion.Major -le 6))
{
#suppress the firewall blocking dialogue on win7
netsh advfirewall firewall add rule name="sshd" program="$($OpenSSHTestInfo['OpenSSHBinPath'])\sshd.exe" protocol=any action=allow dir=in
}
}
AfterEach { $tI++ }
AfterAll {
if(($platform -eq [PlatformType]::Windows) -and ($psversiontable.BuildVersion.Major -le 6))
{
netsh advfirewall firewall delete rule name="sshd" program="$($OpenSSHTestInfo['OpenSSHBinPath'])\sshd.exe" protocol=any dir=in
}
}
Context "Authorized key file permission" {
BeforeAll {
$systemAccount = New-Object System.Security.Principal.NTAccount("NT AUTHORITY", "SYSTEM")
$adminAccount = New-Object System.Security.Principal.NTAccount("BUILTIN","Administrators")
$objUser = New-Object System.Security.Principal.NTAccount($ssouser)
$currentUser = New-Object System.Security.Principal.NTAccount($($env:USERDOMAIN), $($env:USERNAME))
$systemSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::LocalSystemSid)
$adminsSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid)
$currentUserSid = Get-UserSID -User "$($env:USERDOMAIN)\$($env:USERNAME)"
$objUserSid = Get-UserSID -User $ssouser
$ssouserSSHProfilePath = Join-Path $ssouserProfile .testssh
if(-not (Test-Path $ssouserSSHProfilePath -PathType Container)) {
@ -43,21 +59,22 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
$testknownhosts = Join-path $PSScriptRoot testdata\test_known_hosts
Copy-Item $Source $ssouserSSHProfilePath -Force -ErrorAction Stop
Adjust-UserKeyFileACL -Filepath $authorizedkeyPath -Owner $objUser -OwnerPerms "Read, Write"
Repair-AuthorizedKeyPermission -Filepath $authorizedkeyPath -confirm:$false
Get-Process -Name sshd | Where-Object {$_.SI -ne 0} | Stop-process
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
#add wrong password so ssh does not prompt password if failed with authorized keys
Add-PasswordSetting -Pass "WrongPass"
$tI=1
}
AfterAll {
Repair-AuthorizedKeyPermission -Filepath $authorizedkeyPath -confirm:$false
if(Test-Path $authorizedkeyPath) {
Adjust-UserKeyFileACL -Filepath $authorizedkeyPath -Owner $objUser -OwnerPerms "Read, Write"
Remove-Item $authorizedkeyPath -Force -ErrorAction Ignore
Repair-AuthorizedKeyPermission -Filepath $authorizedkeyPath -confirm:$false
Remove-Item $authorizedkeyPath -Force -ErrorAction SilentlyContinue
}
if(Test-Path $ssouserSSHProfilePath) {
Remove-Item $ssouserSSHProfilePath -Force -ErrorAction Ignore -Recurse
Remove-Item $ssouserSSHProfilePath -Force -ErrorAction SilentlyContinue -Recurse
}
Remove-PasswordSetting
$tC++
@ -66,11 +83,12 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
BeforeEach {
$filePath = Join-Path $testDir "$tC.$tI.$fileName"
$logPath = Join-Path $testDir "$tC.$tI.$logName"
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
}
It "$tC.$tI-authorized_keys-positive(pwd user is the owner and running process can access to the file)" {
#setup to have ssouser as owner and grant ssouser read and write, admins group, and local system full control
Adjust-UserKeyFileACL -Filepath $authorizedkeyPath -Owner $objUser -OwnerPerms "Read, Write"
Repair-FilePermission -Filepath $authorizedkeyPath -Owners $objUserSid -FullAccessNeeded $adminsSid,$systemSid,$objUserSid -confirm:$false
#Run
Start-Process -FilePath sshd.exe -WorkingDirectory $($OpenSSHTestInfo['OpenSSHBinPath']) -ArgumentList @("-d", "-p $port", "-o `"AuthorizedKeysFile .testssh/authorized_keys`"", "-E $logPath") -NoNewWindow
@ -78,14 +96,12 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
$o | Should Be "1234"
#Cleanup
Get-Process -Name sshd | % { if($_.SI -ne 0) { Start-sleep 1; Stop-Process $_; Start-sleep 1 } }
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
}
It "$tC.$tI-authorized_keys-positive(authorized_keys is owned by local system)" {
#setup to have system as owner and grant it full control
Set-FileOwnerAndACL -Filepath $authorizedkeyPath -Owner $systemAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath $authorizedkeyPath -User $adminAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath $authorizedkeyPath -User $objUser -Perms "Read, Write"
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $systemSid -FullAccessNeeded $adminsSid,$systemSid,$objUserSid -confirm:$false
#Run
Start-Process -FilePath sshd.exe -WorkingDirectory $($OpenSSHTestInfo['OpenSSHBinPath']) -ArgumentList @("-d", "-p $port", "-o `"AuthorizedKeysFile .testssh/authorized_keys`"", "-E $logPath") -NoNewWindow
@ -93,14 +109,12 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
$o | Should Be "1234"
#Cleanup
Get-Process -Name sshd | % { if($_.SI -ne 0) { Start-sleep 1; Stop-Process $_; Start-sleep 1 } }
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
}
It "$tC.$tI-authorized_keys-positive(authorized_keys is owned by admins group and pwd does not have explict ACE)" {
#setup to have admin group as owner and grant it full control
Set-FileOwnerAndACL -Filepath $authorizedkeyPath -Owner $adminAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath $authorizedkeyPath -User $systemAccount -Perms "FullControl"
#setup to have admin group as owner and grant it full control
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $adminsSid -FullAccessNeeded $adminsSid,$systemSid -confirm:$false
#Run
Start-Process -FilePath sshd.exe -WorkingDirectory $($OpenSSHTestInfo['OpenSSHBinPath']) -ArgumentList @("-d", "-p $port", "-o `"AuthorizedKeysFile .testssh/authorized_keys`"", "-E $logPath") -NoNewWindow
@ -108,15 +122,12 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
$o | Should Be "1234"
#Cleanup
Get-Process -Name sshd | % { if($_.SI -ne 0) { Start-sleep 1; Stop-Process $_; Start-sleep 1 } }
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
}
It "$tC.$tI-authorized_keys-positive(authorized_keys is owned by admins group and pwd have explict ACE)" {
#setup to have admin group as owner and grant it full control
Set-FileOwnerAndACL -Filepath $authorizedkeyPath -Owner $adminAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath $authorizedkeyPath -User $systemAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath $authorizedkeyPath -User $objUser -Perms "Read, Write"
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $adminsSid -FullAccessNeeded $adminsSid,$systemSid,$objUserSid -confirm:$false
#Run
Start-Process -FilePath sshd.exe -WorkingDirectory $($OpenSSHTestInfo['OpenSSHBinPath']) -ArgumentList @("-d", "-p $port", "-o `"AuthorizedKeysFile .testssh/authorized_keys`"", "-E $logPath") -NoNewWindow
@ -124,14 +135,12 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
$o | Should Be "1234"
#Cleanup
Get-Process -Name sshd | % { if($_.SI -ne 0) { Start-sleep 1; Stop-Process $_; Start-sleep 1 } }
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
}
It "$tC.$tI-authorized_keys-negative(authorized_keys is owned by other admin user)" {
#setup to have current user (admin user) as owner and grant it full control
Set-FileOwnerAndACL -Filepath $authorizedkeyPath -Owner $currentUser -OwnerPerms "Read","Write"
Add-PermissionToFileACL -FilePath $authorizedkeyPath -User $systemAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath $authorizedkeyPath -User $adminAccount -Perms "FullControl"
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $currentUserSid -FullAccessNeeded $adminsSid,$systemSid -confirm:$false
#Run
Start-Process -FilePath sshd.exe -WorkingDirectory $($OpenSSHTestInfo['OpenSSHBinPath']) -ArgumentList @("-d", "-p $port", "-o `"AuthorizedKeysFile .testssh/authorized_keys`"", "-E $logPath") -NoNewWindow
@ -141,18 +150,16 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
$matches.Count | Should BeGreaterThan 2
#Cleanup
Get-Process -Name sshd | % { if($_.SI -ne 0) { Start-sleep 1; Stop-Process $_; Start-sleep 1 } }
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
}
It "$tC.$tI-authorized_keys-negative(other account can access private key file)" {
#setup to have current user as owner and grant it full control
Set-FileOwnerAndACL -Filepath $authorizedkeyPath -Owner $objUser -OwnerPerms "Read","Write"
Add-PermissionToFileACL -FilePath $authorizedkeyPath -User $systemAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath $authorizedkeyPath -User $adminAccount -Perms "FullControl"
#setup to have current user as owner and grant it full control
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $objUserSid -FullAccessNeeded $adminsSid,$systemSid,$objUserSid -confirm:$false
#add $PwdUser to access the file authorized_keys
$objPwdUser = New-Object System.Security.Principal.NTAccount($PwdUser)
Add-PermissionToFileACL -FilePath $authorizedkeyPath -User $objPwdUser -Perm "Read"
$objPwdUserSid = Get-UserSid -User $PwdUser
Set-FilePermission -FilePath $authorizedkeyPath -User $objPwdUserSid -Perm "Read"
#Run
Start-Process -FilePath sshd.exe -WorkingDirectory $($OpenSSHTestInfo['OpenSSHBinPath']) -ArgumentList @("-d", "-p $port", "-o `"AuthorizedKeysFile .testssh/authorized_keys`"", "-E $logPath") -NoNewWindow
@ -162,15 +169,13 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
$matches.Count | Should BeGreaterThan 2
#Cleanup
Get-Process -Name sshd | % { if($_.SI -ne 0) { Start-sleep 1; Stop-Process $_; Start-sleep 1 } }
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
}
It "$tC.$tI-authorized_keys-negative(authorized_keys is owned by other non-admin user)" {
#setup to have PwdUser as owner and grant it full control
$objPwdUser = New-Object System.Security.Principal.NTAccount($PwdUser)
Set-FileOwnerAndACL -Filepath $authorizedkeyPath -owner $objPwdUser -OwnerPerms "Read","Write"
Add-PermissionToFileACL -FilePath $authorizedkeyPath -User $systemAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath $authorizedkeyPath -User $adminAccount -Perms "FullControl"
#setup to have PwdUser as owner and grant it full control
$objPwdUserSid = Get-UserSid -User $PwdUser
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $objPwdUserSid -FullAccessNeeded $adminsSid,$systemSid,$objPwdUser -confirm:$false
#Run
Start-Process -FilePath sshd.exe -WorkingDirectory $($OpenSSHTestInfo['OpenSSHBinPath']) -ArgumentList @("-d", "-p $port", "-o `"AuthorizedKeysFile .testssh/authorized_keys`"", "-E $logPath") -NoNewWindow
@ -180,12 +185,12 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
$matches.Count | Should BeGreaterThan 2
#Cleanup
Get-Process -Name sshd | % { if($_.SI -ne 0) { Start-sleep 1; Stop-Process $_; Start-sleep 1 } }
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
}
It "$tC.$tI-authorized_keys-negative(the running process does not have read access to the authorized_keys)" {
It "$tC.$tI-authorized_keys-negative(the running process does not have read access to the authorized_keys)" -skip:$skip {
#setup to have ssouser as owner and grant it full control
Set-FileOwnerAndACL -Filepath $authorizedkeyPath -Owner $objUser -OwnerPerms "Read","Write"
Add-PermissionToFileACL -FilePath $authorizedkeyPath -User $systemAccount -Perms "FullControl"
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $objUserSid -FullAccessNeeded $systemSid,$objUserSid -confirm:$false
Set-FilePermission -Filepath $authorizedkeyPath -UserSid $adminsSid -Action Delete
#Run
Start-Process -FilePath sshd.exe -WorkingDirectory $($OpenSSHTestInfo['OpenSSHBinPath']) -ArgumentList @("-d", "-p $port", "-o `"AuthorizedKeysFile .testssh/authorized_keys`"", "-E $logPath") -NoNewWindow
@ -196,7 +201,7 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
$matches.Count | Should BeGreaterThan 2
#Cleanup
Get-Process -Name sshd | % { if($_.SI -ne 0) { Start-sleep 1; Stop-Process $_; Start-sleep 1 } }
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
}
}
}

View File

@ -1,4 +1,5 @@
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force -DisableNameChecking
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force
$tC = 1
$tI = 0
$suite = "authorized_keys_fileperm"
@ -6,7 +7,7 @@ Describe "Tests for ssh config" -Tags "CI" {
BeforeAll {
if($OpenSSHTestInfo -eq $null)
{
Throw "`$OpenSSHTestInfo is null. Please run Setup-OpenSSHTestEnvironment to setup test environment."
Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments."
}
if(-not (Test-Path $OpenSSHTestInfo["TestDataPath"]))
@ -27,38 +28,39 @@ Describe "Tests for ssh config" -Tags "CI" {
# for the first time, delete the existing log files.
if ($OpenSSHTestInfo['DebugMode'])
{
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" -Force -ErrorAction ignore
Remove-Item -Path (Join-Path $testDir "*log*.log") -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" -Force -ErrorAction SilentlyContinue
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" -Force -ErrorAction SilentlyContinue
Remove-Item -Path (Join-Path $testDir "*log*.log") -Force -ErrorAction SilentlyContinue
}
Remove-Item -Path (Join-Path $testDir "*logName") -Force -ErrorAction ignore
Remove-Item -Path (Join-Path $testDir "*logName") -Force -ErrorAction SilentlyContinue
}
AfterEach {
if( $OpenSSHTestInfo["DebugMode"])
{
Copy-Item "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" "$testDir\agentlog$tC.$tI.log" -Force -ErrorAction ignore
Copy-Item "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" "$testDir\sshdlog$tC.$tI.log" -Force -ErrorAction ignore
Copy-Item "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" "$testDir\agentlog$tC.$tI.log" -Force -ErrorAction SilentlyContinue
Copy-Item "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" "$testDir\sshdlog$tC.$tI.log" -Force -ErrorAction SilentlyContinue
#Clear the ssh-agent, sshd logs so that next testcase will get fresh logs.
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" -Force -ErrorAction SilentlyContinue
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" -Force -ErrorAction SilentlyContinue
}
$tI++
}
Context "$tC-User SSHConfig--ReadConfig" {
BeforeAll {
$systemAccount = New-Object System.Security.Principal.NTAccount("NT AUTHORITY", "SYSTEM")
$adminAccount = New-Object System.Security.Principal.NTAccount("BUILTIN","Administrators")
$objUser = New-Object System.Security.Principal.NTAccount($ssouser)
$currentUser = New-Object System.Security.Principal.NTAccount($($env:USERDOMAIN), $($env:USERNAME))
$systemSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::LocalSystemSid)
$adminsSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid)
$currentUserSid = Get-UserSID -User "$($env:USERDOMAIN)\$($env:USERNAME)"
$objUserSid = Get-UserSID -User $ssouser
$userConfigFile = Join-Path $home ".ssh\config"
if( -not (Test-path $userConfigFile) ) {
Copy-item "$PSScriptRoot\testdata\ssh_config" $userConfigFile -force
}
Enable-Privilege SeRestorePrivilege | out-null
$oldACL = Get-ACL $userConfigFile
$tI=1
}
@ -67,8 +69,8 @@ Describe "Tests for ssh config" -Tags "CI" {
$logPath = Join-Path $testDir "$tC.$tI.$logName"
}
AfterEach {
Set-Acl -Path $userConfigFile -AclObject $oldACL
AfterEach {
Set-Acl -Path $userConfigFile -AclObject $oldACL -confirm:$false
}
AfterAll {
@ -77,9 +79,7 @@ Describe "Tests for ssh config" -Tags "CI" {
It "$tC.$tI-User SSHConfig-ReadConfig positive (current logon user is the owner)" {
#setup
Set-FileOwnerAndACL -Filepath $userConfigFile -Owner $currentUser -OwnerPerms "Read","Write"
Add-PermissionToFileACL -FilePath $userConfigFile -User $systemAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath $userConfigFile -User $adminAccount -Perms "FullControl"
Repair-FilePermission -Filepath $userConfigFile -Owners $currentUserSid -FullAccessNeeded $adminsSid,$systemSid,$currentUserSid -confirm:$false
#Run
$o = ssh test_target echo 1234
@ -88,8 +88,7 @@ Describe "Tests for ssh config" -Tags "CI" {
It "$tC.$tI-User SSHConfig-ReadConfig positive (local system is the owner)" {
#setup
Set-FileOwnerAndACL -Filepath $userConfigFile -Owner $systemAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath $userConfigFile -User $adminAccount -Perms "FullControl"
Repair-FilePermission -Filepath $userConfigFile -Owners $systemSid -FullAccessNeeded $adminsSid,$systemSid -confirm:$false
#Run
$o = ssh test_target echo 1234
@ -98,8 +97,8 @@ Describe "Tests for ssh config" -Tags "CI" {
It "$tC.$tI-User SSHConfig-ReadConfig positive (admin is the owner and current user has no explict ACE)" {
#setup
Set-FileOwnerAndACL -Filepath $userConfigFile -Owner $adminAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath $userConfigFile -User $systemAccount -Perms "FullControl"
Repair-FilePermission -Filepath $userConfigFile -Owners $adminsSid -FullAccessNeeded $adminsSid,$systemSid -confirm:$false
Set-FilePermission -Filepath $userConfigFile -UserSid $currentUserSid -Action Delete
#Run
$o = ssh test_target echo 1234
@ -108,10 +107,8 @@ Describe "Tests for ssh config" -Tags "CI" {
It "$tC.$tI-User SSHConfig-ReadConfig positive (admin is the owner and current user has explict ACE)" {
#setup
Set-FileOwnerAndACL -Filepath $userConfigFile -Owner $adminAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath $userConfigFile -User $systemAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath $userConfigFile -User $currentUser -Perms "Read, Write"
Repair-FilePermission -Filepath $userConfigFile -Owners $adminsSid -FullAccessNeeded $adminsSid,$systemSid,$currentUserSid -confirm:$false
#Run
$o = ssh test_target echo 1234
$o | Should Be "1234"
@ -119,9 +116,7 @@ Describe "Tests for ssh config" -Tags "CI" {
It "$tC.$tI-User SSHConfig-ReadConfig negative (wrong owner)" {
#setup
Set-FileOwnerAndACL -Filepath $userConfigFile -Owner $ssouser -OwnerPerms "Read","Write"
Add-PermissionToFileACL -FilePath $userConfigFile -User $systemAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath $userConfigFile -User $adminAccount -Perms "FullControl"
Repair-FilePermission -Filepath $userConfigFile -Owners $objUserSid -FullAccessNeeded $adminsSid,$systemSid,$objUserSid -confirm:$false
#Run
cmd /c "ssh test_target echo 1234 2> $logPath"
@ -131,10 +126,7 @@ Describe "Tests for ssh config" -Tags "CI" {
It "$tC.$tI-User SSHConfig-ReadConfig negative (others has permission)" {
#setup
Set-FileOwnerAndACL -Filepath $userConfigFile -Owner $currentUser -OwnerPerms "Read","Write"
Add-PermissionToFileACL -FilePath $userConfigFile -User $systemAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath $userConfigFile -User $adminAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath $userConfigFile -User $objUser -Perms "Read"
Repair-FilePermission -Filepath $userConfigFile -Owners $currentUserSid -FullAccessNeeded $adminsSid,$systemSid,$currentUserSid -ReadAccessNeeded $objUserSid -confirm:$false
#Run
cmd /c "ssh test_target echo 1234 2> $logPath"

View File

@ -1,8 +1,13 @@
Enum PlatformType {
Windows
Linux
OSX
}
Import-Module OpenSSHUtils -Force
Add-Type -TypeDefinition @"
public enum PlatformType
{
Windows,
Linux,
OSX
}
"@
function Get-Platform {
# Use the .NET Core APIs to determine the current platform; if a runtime
@ -31,157 +36,59 @@ function Get-Platform {
}
}
<#
.Synopsis
user key should be owned by current user account
private key can be accessed only by the file owner, localsystem and Administrators
public user key can be accessed by only file owner, localsystem and Administrators and read by everyone
.Outputs
N/A
.Inputs
FilePath - The path to the file
Owner - The file owner
OwnerPerms - The permissions grant to owner
#>
function Adjust-UserKeyFileACL
{
param (
[parameter(Mandatory=$true)]
[string]$FilePath,
[System.Security.Principal.NTAccount] $Owner = $null,
[System.Security.AccessControl.FileSystemRights[]] $OwnerPerms = $null
)
$myACL = Get-ACL $FilePath
$myACL.SetAccessRuleProtection($True, $FALSE)
Set-Acl -Path $FilePath -AclObject $myACL
$systemAccount = New-Object System.Security.Principal.NTAccount("NT AUTHORITY", "SYSTEM")
$adminAccount = New-Object System.Security.Principal.NTAccount("BUILTIN","Administrators")
$everyoneAccount = New-Object System.Security.Principal.NTAccount("EveryOne")
$myACL = Get-ACL $FilePath
$actualOwner = $null
if($Owner -eq $null)
{
$actualOwner = New-Object System.Security.Principal.NTAccount($($env:USERDOMAIN), $($env:USERNAME))
}
else
{
$actualOwner = $Owner
}
$myACL.SetOwner($actualOwner)
if($myACL.Access)
{
$myACL.Access | % {
if(-not ($myACL.RemoveAccessRule($_)))
{
throw "failed to remove access of $($_.IdentityReference.Value) rule in setup "
}
}
}
$adminACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($adminAccount, "FullControl", "None", "None", "Allow")
$myACL.AddAccessRule($adminACE)
$systemACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($systemAccount, "FullControl", "None", "None", "Allow")
$myACL.AddAccessRule($systemACE)
if(-not ($actualOwner.Equals($adminAccount)) -and (-not $actualOwner.Equals($systemAccount)) -and $OwnerPerms)
{
$OwnerPerms | % {
$ownerACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($actualOwner, $_, "None", "None", "Allow")
$myACL.AddAccessRule($ownerACE)
}
}
if($FilePath.EndsWith(".pub"))
{
$everyoneAce = New-Object System.Security.AccessControl.FileSystemAccessRule `
("Everyone", "Read", "None", "None", "Allow")
$myACL.AddAccessRule($everyoneAce)
}
Set-Acl -Path $FilePath -AclObject $myACL
}
function Set-FileOwnerAndACL
{
param(
[parameter(Mandatory=$true)]
[string]$FilePath,
[System.Security.Principal.NTAccount]$Owner = $null,
[System.Security.AccessControl.FileSystemRights[]] $OwnerPerms = @("Read", "Write")
)
$myACL = Get-ACL -Path $FilePath
$myACL.SetAccessRuleProtection($True, $FALSE)
Set-Acl -Path $FilePath -AclObject $myACL
$myACL = Get-ACL $FilePath
$actualOwner = $null
if($owner -eq $null)
{
$actualOwner = New-Object System.Security.Principal.NTAccount($($env:USERDOMAIN), $($env:USERNAME))
}
else
{
$actualOwner = $Owner
}
$myACL.SetOwner($actualOwner)
if($myACL.Access)
{
$myACL.Access | % {
if(-not ($myACL.RemoveAccessRule($_)))
{
throw "failed to remove access of $($_.IdentityReference.Value) rule in setup "
}
}
}
if($OwnerPerms)
{
$OwnerPerms | % {
$ownerACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($actualOwner, $_, "None", "None", "Allow")
$myACL.AddAccessRule($ownerACE)
}
}
Set-Acl -Path $FilePath -AclObject $myACL
}
function Add-PermissionToFileACL
function Set-FilePermission
{
param(
[parameter(Mandatory=$true)]
[string]$FilePath,
[System.Security.Principal.NTAccount] $User,
[parameter(Mandatory=$true)]
[System.Security.Principal.SecurityIdentifier] $UserSid,
[System.Security.AccessControl.FileSystemRights[]]$Perms,
[System.Security.AccessControl.AccessControlType] $AccessType = "Allow"
[System.Security.AccessControl.AccessControlType] $AccessType = "Allow",
[ValidateSet("Add", "Delete")]
[string]$Action = "Add"
)
$myACL = Get-ACL $FilePath
if($Perms)
$account = Get-UserAccount -UserSid $UserSid
if($Action -ieq "Delete")
{
$myACL.SetAccessRuleProtection($True, $True)
Enable-Privilege SeRestorePrivilege | out-null
Set-Acl -Path $FilePath -AclObject $myACL
$myACL = Get-ACL $FilePath
if($myACL.Access)
{
$myACL.Access | % {
if($_.IdentityReference.Equals($account))
{
if($_.IsInherited)
{
$myACL.SetAccessRuleProtection($True, $True)
Enable-Privilege SeRestorePrivilege | out-null
Set-Acl -Path $FilePath -AclObject $myACL
$myACL = Get-ACL $FilePath
}
if(-not ($myACL.RemoveAccessRule($_)))
{
throw "failed to remove access of $($_.IdentityReference) rule in setup "
}
}
}
}
}
elseif($Perms)
{
$Perms | % {
$userACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($User, $_, "None", "None", $AccessType)
($UserSid, $_, "None", "None", $AccessType)
$myACL.AddAccessRule($userACE)
}
}
Set-Acl -Path $FilePath -AclObject $myACL
}
Enable-Privilege SeRestorePrivilege | out-null
Set-Acl -Path $FilePath -AclObject $myACL -confirm:$false
}
function Add-PasswordSetting

View File

@ -1,4 +1,5 @@
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force -DisableNameChecking
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force
$tC = 1
$tI = 0
$suite = "hostkey_fileperm"
@ -6,7 +7,7 @@ Describe "Tests for host keys file permission" -Tags "CI" {
BeforeAll {
if($OpenSSHTestInfo -eq $null)
{
Throw "`$OpenSSHTestInfo is null. Please run Setup-OpenSSHTestEnvironment to setup test environment."
Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments."
}
$testDir = "$($OpenSSHTestInfo["TestDataPath"])\$suite"
@ -19,30 +20,57 @@ Describe "Tests for host keys file permission" -Tags "CI" {
$port = 47003
$ssouser = $OpenSSHTestInfo["SSOUser"]
$script:logNum = 0
Remove-Item -Path (Join-Path $testDir "*$logName") -Force -ErrorAction ignore
Remove-Item -Path (Join-Path $testDir "*$logName") -Force -ErrorAction SilentlyContinue
$platform = Get-Platform
$skip = ($platform -eq [PlatformType]::Windows) -and ($PSVersionTable.PSVersion.Major -le 2)
if(($platform -eq [PlatformType]::Windows) -and ($psversiontable.BuildVersion.Major -le 6))
{
#suppress the firewall blocking dialogue on win7
netsh advfirewall firewall add rule name="sshd" program="$($OpenSSHTestInfo['OpenSSHBinPath'])\sshd.exe" protocol=any action=allow dir=in
}
}
AfterEach { $tI++ }
AfterAll {
if(($platform -eq [PlatformType]::Windows) -and ($psversiontable.BuildVersion.Major -le 6))
{
netsh advfirewall firewall delete rule name="sshd" program="$($OpenSSHTestInfo['OpenSSHBinPath'])\sshd.exe" protocol=any dir=in
}
}
Context "$tC - Host key files permission" {
BeforeAll {
$systemAccount = New-Object System.Security.Principal.NTAccount("NT AUTHORITY", "SYSTEM")
$adminAccount = New-Object System.Security.Principal.NTAccount("BUILTIN","Administrators")
$objUser = New-Object System.Security.Principal.NTAccount($ssouser)
$currentUser = New-Object System.Security.Principal.NTAccount($($env:USERDOMAIN), $($env:USERNAME))
$everyone = New-Object System.Security.Principal.NTAccount("EveryOne")
$systemSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::LocalSystemSid)
$adminsSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid)
$currentUserSid = Get-UserSID -User "$($env:USERDOMAIN)\$($env:USERNAME)"
$objUserSid = Get-UserSID -User $ssouser
$everyoneSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::WorldSid)
$hostKeyFilePath = join-path $testDir hostkeyFilePermTest_ed25519_key
if(Test-path $hostKeyFilePath -PathType Leaf) {
Set-FileOwnerAndACL -filepath $hostKeyFilePath
Repair-SshdHostKeyPermission -filepath $hostKeyFilePath -confirm:$false
}
if(Test-path "$hostKeyFilePath.pub" -PathType Leaf){
Set-FileOwnerAndACL -filepath "$hostKeyFilePath.pub"
}
Remove-Item -path "$hostKeyFilePath*" -Force -ErrorAction Ignore
Remove-Item -path "$hostKeyFilePath*" -Force -ErrorAction SilentlyContinue
ssh-keygen.exe -t ed25519 -f $hostKeyFilePath -P `"`"
Get-Process -Name sshd | Where-Object {$_.SI -ne 0} | Stop-process
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
$tI=1
function WaitForValidation
{
param([string]$logPath, [int]$length)
$num = 0
while((-not (Test-Path $logPath -PathType leaf)) -or ((Get-item $logPath).Length -lt $length) -and ($num++ -lt 4))
{
Start-Sleep -Milliseconds 1000
}
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
$num = 0
while ([string]::IsNullorEmpty($(Get-Content $logPath -ErrorAction SilentlyContinue | Out-String)) -and ($num++ -lt 4))
{
Start-Sleep -Milliseconds 1000
}
}
}
BeforeEach {
@ -50,76 +78,59 @@ Describe "Tests for host keys file permission" -Tags "CI" {
}
AfterAll {
if(Test-path $hostKeyFilePath -PathType Leaf){
Adjust-UserKeyFileACL -Filepath $hostKeyFilePath -Owner $systemAccount
}
if(Test-path "$hostKeyFilePath.pub" -PathType Leaf){
Adjust-UserKeyFileACL -Filepath "$hostKeyFilePath.pub" -Owner $systemAccount
if(Test-path $hostKeyFilePath -PathType Leaf) {
Repair-SshdHostKeyPermission -filepath $hostKeyFilePath -confirm:$false
}
$tC++
}
It "$tC.$tI-Host keys-positive (both public and private keys are owned by admin groups and running process can access to public key file)" {
Set-FileOwnerAndACL -Filepath $hostKeyFilePath -Owner $adminAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath $hostKeyFilePath -User $systemAccount -Perms "FullControl"
It "$tC.$tI-Host keys-positive (both public and private keys are owned by admin groups and running process can access to public key file)" {
Repair-FilePermission -Filepath $hostKeyFilePath -Owners $adminsSid -FullAccessNeeded $adminsSid,$systemSid -confirm:$false
Repair-FilePermission -Filepath "$hostKeyFilePath.pub" -Owners $adminsSid -FullAccessNeeded $adminsSid,$systemSid -confirm:$false
#Run
Start-Process -FilePath sshd.exe -WorkingDirectory $($OpenSSHTestInfo['OpenSSHBinPath']) -ArgumentList @("-d", "-p $port", "-h $hostKeyFilePath", "-E $logPath") -NoNewWindow
WaitForValidation -LogPath $logPath -Length 600
#validate file content does not contain unprotected info.
$logPath | Should Not Contain "UNPROTECTED PRIVATE KEY FILE!"
Set-FileOwnerAndACL -Filepath "$hostKeyFilePath.pub" -Owner $adminAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath "$hostKeyFilePath.pub" -User $systemAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath "$hostKeyFilePath.pub" -User $everyOne -Perms "Read"
}
It "$tC.$tI-Host keys-positive (both public and private keys are owned by admin groups and pwd user has explicit ACE)" {
Repair-FilePermission -Filepath $hostKeyFilePath -Owners $adminsSid -FullAccessNeeded $adminsSid,$systemSid -ReadAccessNeeded $currentUserSid -confirm:$false
Repair-FilePermission -Filepath "$hostKeyFilePath.pub" -Owners $adminsSid -FullAccessNeeded $adminsSid,$systemSid -ReadAccessNeeded $everyOneSid -confirm:$false
#Run
Start-Process -FilePath sshd.exe -WorkingDirectory $($OpenSSHTestInfo['OpenSSHBinPath']) -ArgumentList @("-d", "-p $port", "-h $hostKeyFilePath", "-E $logPath") -NoNewWindow
Get-Process -Name sshd | % { if($_.SI -ne 0) { Start-sleep 2; Stop-Process $_; Start-sleep 1 } }
WaitForValidation -LogPath $logPath -Length 600
#validate file content does not contain unprotected info.
$logPath | Should Not Contain "UNPROTECTED PRIVATE KEY FILE!"
}
It "$tC.$tI-Host keys-positive (both public and private keys are owned by admin groups and pwd user has explicit ACE)" {
Set-FileOwnerAndACL -Filepath $hostKeyFilePath -Owner $adminAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath $hostKeyFilePath -User $systemAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath "$hostKeyFilePath.pub" -User $currentUser -Perms "Read"
It "$tC.$tI-Host keys-positive (both public and private keys are owned by system and running process can access to public key file)" -skip:$skip {
Repair-FilePermission -Filepath $hostKeyFilePath -Owners $systemSid -FullAccessNeeded $systemSid,$adminsSid -ReadAccessNeeded $currentUserSid -confirm:$false
Set-FilePermission -Filepath $hostKeyFilePath -UserSid $adminsSid -Action Delete
Repair-FilePermission -Filepath "$hostKeyFilePath.pub" -Owners $systemSid -FullAccessNeeded $systemSid,$adminsSid -ReadAccessNeeded $currentUserSid -confirm:$false
Set-FilePermission -Filepath "$hostKeyFilePath.pub" -UserSid $adminsSid -Action Delete
Set-FileOwnerAndACL -Filepath "$hostKeyFilePath.pub" -Owner $adminAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath "$hostKeyFilePath.pub" -User $systemAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath "$hostKeyFilePath.pub" -User $everyOne -Perms "Read"
#Run
Start-Process -FilePath sshd.exe -WorkingDirectory $($OpenSSHTestInfo['OpenSSHBinPath']) -ArgumentList @("-d", "-p $port", "-h $hostKeyFilePath", "-E $logPath") -NoNewWindow
Get-Process -Name sshd | % { if($_.SI -ne 0) { Start-sleep 2; Stop-Process $_; Start-sleep 1 } }
#validate file content does not contain unprotected info.
$logPath | Should Not Contain "UNPROTECTED PRIVATE KEY FILE!"
}
It "$tC.$tI-Host keys-positive (both public and private keys are owned by system and running process can access to public key file)" {
Set-FileOwnerAndACL -Filepath $hostKeyFilePath -Owner $systemAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath $hostKeyFilePath -User $adminAccount -Perms "Read"
Set-FileOwnerAndACL -Filepath "$hostKeyFilePath.pub" -Owner $systemAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath "$hostKeyFilePath.pub" -User $adminAccount -Perms "Read"
#Run
Start-Process -FilePath sshd.exe -WorkingDirectory $($OpenSSHTestInfo['OpenSSHBinPath']) -ArgumentList @("-d", "-p $port", "-h $hostKeyFilePath", "-E $logPath") -NoNewWindow
Get-Process -Name sshd | % { if($_.SI -ne 0) { Start-sleep 2; Stop-Process $_; Start-sleep 1 } }
WaitForValidation -LogPath $logPath -Length 600
#validate file content does not contain unprotected info.
$logPath | Should Not Contain "UNPROTECTED PRIVATE KEY FILE!"
}
It "$tC.$tI-Host keys-negative (other account can access private key file)" {
Set-FileOwnerAndACL -Filepath $hostKeyFilePath -Owner $systemAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath $hostKeyFilePath -User $adminAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath $hostKeyFilePath -User $objUser -Perms "Read"
Repair-FilePermission -Filepath $hostKeyFilePath -Owners $adminsSid -FullAccessNeeded $systemSid,$adminsSid -ReadAccessNeeded $objUserSid -confirm:$false
Repair-FilePermission -Filepath "$hostKeyFilePath.pub" -Owners $adminsSid -FullAccessNeeded $systemSid,$adminsSid -ReadAccessNeeded $everyOneSid -confirm:$false
Set-FileOwnerAndACL -Filepath "$hostKeyFilePath.pub" -Owner $adminAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath "$hostKeyFilePath.pub" -User $systemAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath "$hostKeyFilePath.pub" -User $everyOne -Perms "Read"
#Run
Start-Process -FilePath sshd.exe -WorkingDirectory $($OpenSSHTestInfo['OpenSSHBinPath']) -ArgumentList @("-d", "-p $port", "-h $hostKeyFilePath", "-E $logPath") -NoNewWindow
Get-Process -Name sshd | % { if($_.SI -ne 0) { Start-sleep 2; Stop-Process $_; Start-sleep 1 } }
WaitForValidation -LogPath $logPath -Length 1100
#validate file content contains unprotected info.
$logPath | Should Contain "key_load_private: bad permissions"
@ -127,32 +138,26 @@ Describe "Tests for host keys file permission" -Tags "CI" {
It "$tC.$tI-Host keys-negative (the private key has wrong owner)" {
#setup to have ssouser as owner and grant it full control
Set-FileOwnerAndACL -FilePath $hostKeyFilePath -Owner $objUser -OwnerPerms "Read","Write"
Add-PermissionToFileACL -FilePath $hostKeyFilePath -User $adminAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath $hostKeyFilePath -User $systemAccount -Perms "FullControl"
Set-FileOwnerAndACL -Filepath "$hostKeyFilePath.pub" -Owner $adminAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath "$hostKeyFilePath.pub" -User $systemAccount -Perms "FullControl"
Add-PermissionToFileACL -FilePath "$hostKeyFilePath.pub" -User $everyOne -Perms "Read"
Repair-FilePermission -Filepath $hostKeyFilePath -Owners $objUserSid -FullAccessNeeded $systemSid,$adminsSid,$objUserSid -confirm:$false
Repair-FilePermission -Filepath "$hostKeyFilePath.pub" -Owners $adminsSid -FullAccessNeeded $systemSid,$adminsSid -ReadAccessNeeded $everyOneSid -confirm:$false
#Run
Start-Process -FilePath sshd.exe -WorkingDirectory $($OpenSSHTestInfo['OpenSSHBinPath']) -ArgumentList @("-d", "-p $port", "-h $hostKeyFilePath", "-E $logPath") -NoNewWindow
Get-Process -Name sshd | % { if($_.SI -ne 0) { Start-sleep 2; Stop-Process $_; Start-sleep 1 } }
WaitForValidation -LogPath $logPath -Length 1100
#validate file content contains unprotected info.
$logPath | Should Contain "key_load_private: bad permissions"
}
It "$tC.$tI-Host keys-negative (the running process does not have read access to public key)" {
It "$tC.$tI-Host keys-negative (the running process does not have read access to public key)" -skip:$skip {
#setup to have ssouser as owner and grant it full control
Set-FileOwnerAndACL -FilePath $hostKeyFilePath -Owner $systemAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath $hostKeyFilePath -User $adminAccount -Perms "Read"
Set-FileOwnerAndACL -Filepath "$hostKeyFilePath.pub" -Owner $systemAccount -OwnerPerms "FullControl"
Repair-FilePermission -Filepath $hostKeyFilePath -Owners $systemSid -FullAccessNeeded $systemSid,$adminsSid -confirm:$false
Repair-FilePermission -Filepath "$hostKeyFilePath.pub" -Owners $systemSid -FullAccessNeeded $systemSid -confirm:$false
Set-FilePermission -Filepath "$hostKeyFilePath.pub" -UserSid $adminsSid -Action Delete
#Run
Start-Process -FilePath sshd.exe -WorkingDirectory $($OpenSSHTestInfo['OpenSSHBinPath']) -ArgumentList @("-d", "-p $port", "-h $hostKeyFilePath", "-E $logPath") -NoNewWindow
Get-Process -Name sshd | % { if($_.SI -ne 0) { Start-sleep 2; Stop-Process $_; Start-sleep 1 } }
WaitForValidation -LogPath $logPath -Length 1100
#validate file content contains unprotected info.
$logPath | Should Contain "key_load_public: Permission denied"

View File

@ -1,4 +1,5 @@
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force -DisableNameChecking
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force
$tC = 1
$tI = 0
$suite = "keyutils"
@ -7,7 +8,7 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" {
BeforeAll {
if($OpenSSHTestInfo -eq $null)
{
Throw "`$OpenSSHTestInfo is null. Please run Setup-OpenSSHTestEnvironment to setup test environment."
Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments."
}
$testDir = "$($OpenSSHTestInfo["TestDataPath"])\$suite"
@ -20,48 +21,58 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" {
$keytypes = @("rsa","dsa","ecdsa","ed25519")
$ssouser = $OpenSSHTestInfo["SSOUser"]
$systemAccount = New-Object System.Security.Principal.NTAccount("NT AUTHORITY", "SYSTEM")
$adminsAccount = New-Object System.Security.Principal.NTAccount("BUILTIN","Administrators")
$currentUser = New-Object System.Security.Principal.NTAccount($($env:USERDOMAIN), $($env:USERNAME))
$everyone = New-Object System.Security.Principal.NTAccount("EveryOne")
$objUser = New-Object System.Security.Principal.NTAccount($ssouser)
$systemSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::LocalSystemSid)
$adminsSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid)
$currentUserSid = Get-UserSID -User "$($env:USERDOMAIN)\$($env:USERNAME)"
$objUserSid = Get-UserSID -User $ssouser
$everyoneSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::WorldSid)
#only validate owner and ACEs of the file
function ValidateKeyFile {
param([string]$FilePath)
$myACL = Get-ACL $FilePath
$myACL.Owner.Equals($currentUser.Value) | Should Be $true
$currentOwnerSid = Get-UserSid -User $myACL.Owner
$currentOwnerSid.Equals($currentUserSid) | Should Be $true
$myACL.Access | Should Not Be $null
$ReadAccessPerm = ([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Read.value__) -bor `
([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Synchronize.value__)
$ReadWriteAccessPerm = ([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Read.value__) -bor `
([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Write.value__) -bor `
([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Synchronize.value__)
$FullControlPerm = [System.UInt32] [System.Security.AccessControl.FileSystemRights]::FullControl.value__
if($FilePath.EndsWith(".pub")) {
$myACL.Access.Count | Should Be 4
$identities = @($systemAccount.Value, $adminsAccount.Value, $currentUser.Value, $everyone.Value)
$identities = @($systemSid, $adminsSid, $currentUserSid, $everyoneSid)
}
else {
$myACL.Access.Count | Should Be 3
$identities = @($systemAccount.Value, $adminsAccount.Value, $currentUser.Value)
$identities = @($systemSid, $adminsSid, $currentUserSid)
}
foreach ($a in $myACL.Access) {
$a.IdentityReference.Value -in $identities | Should Be $true
$id = Get-UserSid -User $a.IdentityReference
$identities -contains $id | Should Be $true
switch ($a.IdentityReference.Value)
switch ($id)
{
{$_ -in @($systemAccount.Value, $adminsAccount.Value)}
{@($systemSid, $adminsSid) -contains $_}
{
$a.FileSystemRights | Should Be "FullControl"
([System.UInt32]$a.FileSystemRights.value__) | Should Be $FullControlPerm
break;
}
$currentUser.Value
$currentUserSid
{
$a.FileSystemRights | Should Be "Write, Read, Synchronize"
([System.UInt32]$a.FileSystemRights.value__) | Should Be $ReadWriteAccessPerm
break;
}
$everyone.Value
$everyoneSid
{
$a.FileSystemRights | Should Be "Read, Synchronize"
([System.UInt32]$a.FileSystemRights.value__) | Should Be $ReadAccessPerm
break;
}
}
@ -106,7 +117,7 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" {
foreach($type in $keytypes)
{
$keyPath = Join-Path $testDir "id_$type"
remove-item $keyPath -ErrorAction ignore
remove-item $keyPath -ErrorAction SilentlyContinue
ssh-keygen -t $type -P $keypassphrase -f $keyPath
ValidateKeyFile -FilePath $keyPath
ValidateKeyFile -FilePath "$keyPath.pub"
@ -116,7 +127,17 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" {
# This uses keys generated in above context
Context "$tC -ssh-add test cases" {
BeforeAll {$tI=1}
BeforeAll {
$tI=1
function WaitForStatus
{
param([string]$ServiceName, [string]$Status)
while((((Get-Service $ServiceName).Status) -ine $Status) -and ($num++ -lt 4))
{
Start-Sleep -Milliseconds 1000
}
}
}
AfterAll{$tC++}
# Executing ssh-agent will start agent service
@ -131,16 +152,21 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" {
(Get-Service sshd).Status | Should Be "Stopped"
ssh-agent
WaitForStatus -ServiceName ssh-agent -Status "Running"
(Get-Service ssh-agent).Status | Should Be "Running"
Stop-Service ssh-agent -Force
WaitForStatus -ServiceName ssh-agent -Status "Stopped"
(Get-Service ssh-agent).Status | Should Be "Stopped"
(Get-Service sshd).Status | Should Be "Stopped"
# this should automatically start both the services
Start-Service sshd
WaitForStatus -ServiceName sshd -Status "Running"
(Get-Service ssh-agent).Status | Should Be "Running"
(Get-Service sshd).Status | Should Be "Running"
}
@ -170,7 +196,7 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" {
{
$keyPath = Join-Path $testDir "id_$type"
$pubkeyraw = ((Get-Content "$keyPath.pub").Split(' '))[1]
($allkeys | where { $_.contains($pubkeyraw) }).count | Should Be 1
@($allkeys | where { $_.contains($pubkeyraw) }).count | Should Be 1
}
#delete added keys
@ -188,7 +214,7 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" {
{
$keyPath = Join-Path $testDir "id_$type"
$pubkeyraw = ((Get-Content "$keyPath.pub").Split(' '))[1]
($allkeys | where { $_.contains($pubkeyraw) }).count | Should Be 0
@($allkeys | where { $_.contains($pubkeyraw) }).count | Should Be 0
}
}
}
@ -197,7 +223,7 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" {
BeforeAll {
$keyFileName = "sshadd_userPermTestkey_ed25519"
$keyFilePath = Join-Path $testDir $keyFileName
Remove-Item -path "$keyFilePath*" -Force -ErrorAction Ignore
Remove-Item -path "$keyFilePath*" -Force -ErrorAction SilentlyContinue
ssh-keygen.exe -t ed25519 -f $keyFilePath -P $keypassphrase
#set up SSH_ASKPASS
Add-PasswordSetting -Pass $keypassphrase
@ -209,7 +235,7 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" {
}
AfterEach {
if(Test-Path $keyFilePath) {
Adjust-UserKeyFileACL -FilePath $keyFilePath -Owner $currentUser -OwnerPerms "Read, Write"
Repair-FilePermission -FilePath $keyFilePath -Owner $currentUserSid -FullAccessNeeded $currentUserSid,$systemSid,$adminsSid -confirm:$false
}
}
@ -220,30 +246,30 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" {
}
It "$tC.$tI- ssh-add - positive (Secured private key owned by current user)" {
#setup to have current user as owner and grant it full control
Set-FileOwnerAndACL -FilePath $keyFilePath -Owner $currentUser -OwnerPerms "FullControl"
#setup to have current user as owner and grant it full control
Repair-FilePermission -FilePath $keyFilePath -Owner $currentUserSid -FullAccessNeeded $currentUserSid,$systemSid,$adminsSid -confirm:$false
# for ssh-add to consume SSh_ASKPASS, stdin should not be TTY
cmd /c "ssh-add $keyFilePath < $nullFile 2> nul"
$LASTEXITCODE | Should Be 0
$allkeys = ssh-add -L
$pubkeyraw = ((Get-Content "$keyFilePath.pub").Split(' '))[1]
($allkeys | where { $_.contains($pubkeyraw) }).count | Should Be 1
@($allkeys | where { $_.contains($pubkeyraw) }).count | Should Be 1
#clean up
cmd /c "ssh-add -d $keyFilePath 2> nul "
}
It "$tC.$tI - ssh-add - positive (Secured private key owned by Administrators group and the current user has no explicit ACE)" {
#setup to have local admin group as owner and grant it full control
Set-FileOwnerAndACL -FilePath $keyFilePath -Owner $adminsAccount -OwnerPerms "FullControl"
#setup to have local admin group as owner and grant it full control
Repair-FilePermission -FilePath $keyFilePath -Owner $adminsSid -FullAccessNeeded $adminsSid,$systemSid -confirm:$false
# for ssh-add to consume SSh_ASKPASS, stdin should not be TTY
cmd /c "ssh-add $keyFilePath < $nullFile 2> nul "
$LASTEXITCODE | Should Be 0
$allkeys = ssh-add -L
$pubkeyraw = ((Get-Content "$keyFilePath.pub").Split(' '))[1]
($allkeys | where { $_.contains($pubkeyraw) }).count | Should Be 1
@($allkeys | where { $_.contains($pubkeyraw) }).count | Should Be 1
#clean up
cmd /c "ssh-add -d $keyFilePath 2> nul "
@ -251,62 +277,56 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" {
It "$tC.$tI - ssh-add - positive (Secured private key owned by Administrators group and the current user has explicit ACE)" {
#setup to have local admin group as owner and grant it full control
Set-FileOwnerAndACL -FilePath $keyFilePath -Owner $adminsAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath $keyFilePath -User $currentUser -Perm "Read, Write"
Repair-FilePermission -FilePath $keyFilePath -Owners $adminsSid -FullAccessNeeded $currentUserSid,$adminsSid,$systemSid -confirm:$false
# for ssh-add to consume SSh_ASKPASS, stdin should not be TTY
cmd /c "ssh-add $keyFilePath < $nullFile 2> nul "
$LASTEXITCODE | Should Be 0
$allkeys = ssh-add -L
$pubkeyraw = ((Get-Content "$keyFilePath.pub").Split(' '))[1]
($allkeys | where { $_.contains($pubkeyraw) }).count | Should Be 1
@($allkeys | where { $_.contains($pubkeyraw) }).count | Should Be 1
#clean up
cmd /c "ssh-add -d $keyFilePath 2> nul "
}
It "$tC.$tI - ssh-add - positive (Secured private key owned by local system group)" {
#setup to have local admin group as owner and grant it full control
Set-FileOwnerAndACL -FilePath $keyFilePath -Owner $systemAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath $keyFilePath -User $adminsAccount -Perm "FullControl"
#setup to have local admin group as owner and grant it full control
Repair-FilePermission -FilePath $keyFilePath -Owners $systemSid -FullAccessNeeded $systemSid,$adminsSid -confirm:$false
# for ssh-add to consume SSh_ASKPASS, stdin should not be TTY
cmd /c "ssh-add $keyFilePath < $nullFile 2> nul "
$LASTEXITCODE | Should Be 0
$allkeys = ssh-add -L
$pubkeyraw = ((Get-Content "$keyFilePath.pub").Split(' '))[1]
($allkeys | where { $_.contains($pubkeyraw) }).count | Should Be 1
@($allkeys | where { $_.contains($pubkeyraw) }).count | Should Be 1
#clean up
cmd /c "ssh-add -d $keyFilePath 2> nul "
}
It "$tC.$tI- ssh-add - negative (other account can access private key file)" {
#setup to have current user as owner and grant it full control
Set-FileOwnerAndACL -FilePath $keyFilePath -Owner $currentUser -OwnerPerms "FullControl"
#add ssouser to access the private key
Add-PermissionToFileACL -FilePath $keyFilePath -User $objUser -Perm "Read"
#setup to have current user as owner and grant it full control
Repair-FilePermission -FilePath $keyFilePath -Owners $currentUserSid -FullAccessNeeded $currentUserSid,$adminsSid, $systemSid -ReadAccessNeeded $objUserSid -confirm:$false
cmd /c "ssh-add $keyFilePath < $nullFile 2> nul "
$LASTEXITCODE | Should Not Be 0
$allkeys = ssh-add -L
$pubkeyraw = ((Get-Content "$keyFilePath.pub").Split(' '))[1]
($allkeys | where { $_.contains($pubkeyraw) }).count | Should Be 0
@($allkeys | where { $_.contains($pubkeyraw) }).count | Should Be 0
}
It "$tC.$tI - ssh-add - negative (the private key has wrong owner)" {
#setup to have ssouser as owner and grant it full control
Set-FileOwnerAndACL -FilePath $keyFilePath -owner $objUser -OwnerPerms "Read, Write"
Add-PermissionToFileACL -FilePath $keyFilePath -User $adminsAccount -Perm "FullControl"
Repair-FilePermission -FilePath $keyFilePath -Owners $objUserSid -FullAccessNeeded $objUserSid,$adminsSid, $systemSid -confirm:$false
cmd /c "ssh-add $keyFilePath < $nullFile 2> nul "
$LASTEXITCODE | Should Not Be 0
$allkeys = ssh-add -L
$pubkeyraw = ((Get-Content "$keyFilePath.pub").Split(' '))[1]
($allkeys | where { $_.contains($pubkeyraw) }).count | Should Be 0
@($allkeys | where { $_.contains($pubkeyraw) }).count | Should Be 0
}
}
@ -314,7 +334,7 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" {
BeforeAll {
$tI=1
$port = $OpenSSHTestInfo["Port"]
Remove-item (join-path $testDir "$tC.$tI.out.txt") -force -ErrorAction Ignore
Remove-item (join-path $testDir "$tC.$tI.out.txt") -force -ErrorAction SilentlyContinue
}
BeforeEach {
$outputFile = join-path $testDir "$tC.$tI.out.txt"

View File

@ -1,4 +1,6 @@
$tC = 1
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force
$tC = 1
$tI = 0
$suite = "log_fileperm"
@ -15,38 +17,52 @@ Describe "Tests for log file permission" -Tags "CI" {
$null = New-Item $testDir -ItemType directory -Force -ErrorAction SilentlyContinue
}
$port = 47003
$logName = "log.txt"
$logName = "log.txt"
$systemSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::LocalSystemSid)
$adminsSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid)
$currentUserSid = Get-UserSID -User "$($env:USERDOMAIN)\$($env:USERNAME)"
$systemAccount = New-Object System.Security.Principal.NTAccount("NT AUTHORITY", "SYSTEM")
$adminsAccount = New-Object System.Security.Principal.NTAccount("BUILTIN","Administrators")
$currentUser = New-Object System.Security.Principal.NTAccount($($env:USERDOMAIN), $($env:USERNAME))
Remove-Item (Join-Path $testDir "*$logName") -Force -ErrorAction Ignore
Remove-Item (Join-Path $testDir "*$logName") -Force -ErrorAction SilentlyContinue
$platform = Get-Platform
if(($platform -eq [PlatformType]::Windows) -and ($psversiontable.BuildVersion.Major -le 6))
{
#suppress the firewall blocking dialogue on win7
netsh advfirewall firewall add rule name="sshd" program="$($OpenSSHTestInfo['OpenSSHBinPath'])\sshd.exe" protocol=any action=allow dir=in
}
#only validate owner and ACEs of the file
function ValiLogFilePerm {
function ValidateLogFilePerm {
param([string]$FilePath)
$myACL = Get-ACL $FilePath
$myACL.Owner.Equals($currentUser.Value) | Should Be $true
$myACL.Access | Should Not Be $null
$currentOwnerSid = Get-UserSid -User $myACL.Owner
$currentOwnerSid.Equals($currentUserSid) | Should Be $true
$myACL.Access | Should Not Be $null
$ReadWriteAccessPerm = ([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Read.value__) -bor `
([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Write.value__) -bor `
([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Synchronize.value__)
$FullControlPerm = [System.UInt32] [System.Security.AccessControl.FileSystemRights]::FullControl.value__
$myACL.Access.Count | Should Be 3
$identities = @($systemAccount.Value, $adminsAccount.Value, $currentUser.Value)
$identities = @($systemSid, $adminsSid, $currentUserSid)
foreach ($a in $myACL.Access) {
$a.IdentityReference.Value -in $identities | Should Be $true
$id = Get-UserSid -User $a.IdentityReference
$identities -contains $id | Should Be $true
switch ($a.IdentityReference.Value)
switch ($id)
{
{$_ -in @($systemAccount.Value, $adminsAccount.Value)}
{@($systemSid, $adminsSid) -contains $_}
{
$a.FileSystemRights | Should Be "FullControl"
([System.UInt32]$a.FileSystemRights.value__) | Should Be $FullControlPerm
break;
}
$currentUser.Value
$currentUserSid
{
$a.FileSystemRights | Should Be "Write, Read, Synchronize"
([System.UInt32]$a.FileSystemRights.value__) | Should Be $ReadWriteAccessPerm
break;
}
}
@ -63,11 +79,17 @@ Describe "Tests for log file permission" -Tags "CI" {
$logPath = Join-Path $testDir "$tC.$tI.$logName"
}
AfterEach {$tI++;}
AfterEach {$tI++;}
AfterAll {
if(($platform -eq [PlatformType]::Windows) -and ($psversiontable.BuildVersion.Major -le 6))
{
netsh advfirewall firewall delete rule name="sshd" program="$($OpenSSHTestInfo['OpenSSHBinPath'])\sshd.exe" protocol=any dir=in
}
}
Context "$tC-SSHD -E Log file permission" {
BeforeAll {
Get-Process -Name sshd | Where-Object {$_.SI -ne 0} | Stop-process
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
$tI=1
}
@ -79,8 +101,8 @@ Describe "Tests for log file permission" -Tags "CI" {
#Run
Start-Process -FilePath sshd.exe -WorkingDirectory $($OpenSSHTestInfo['OpenSSHBinPath']) -ArgumentList @("-d", "-p $port", "-E $logPath") -NoNewWindow
Start-sleep 1;
ValiLogFilePerm -FilePath $logPath
Get-Process -Name sshd | % { if($_.SI -ne 0) { Stop-Process $_; Start-sleep 1 } }
ValidateLogFilePerm -FilePath $logPath
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
}
}
}

View File

@ -1,14 +1,22 @@
$tC = 1
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force
$tC = 1
$tI = 0
$suite = "portfwd"
Describe "E2E scenarios for port forwarding" -Tags "CI" {
BeforeAll {
if($OpenSSHTestInfo -eq $null)
{
Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments."
}
$testDir = Join-Path $OpenSSHTestInfo["TestDataPath"] $suite
if(-not (Test-Path $testDir))
{
$null = New-Item $testDir -ItemType directory -Force -ErrorAction SilentlyContinue
}
$platform = Get-Platform
$skip = ($platform -eq [PlatformType]::Windows) -and ($PSVersionTable.PSVersion.Major -le 2)
}
BeforeEach {
@ -23,12 +31,12 @@ Describe "E2E scenarios for port forwarding" -Tags "CI" {
AfterAll{$tC++}
#TODO - this relies on winrm (that is windows specific)
It "$tC.$tI - local port forwarding" {
It "$tC.$tI - local port forwarding" -skip:$skip {
ssh -L 5432:127.0.0.1:47001 test_target powershell.exe Test-WSMan -computer 127.0.0.1 -port 5432 | Set-Content $stdoutFile
$stdoutFile | Should Contain "wsmid"
}
It "$tC.$tI - remote port forwarding" {
It "$tC.$tI - remote port forwarding" -skip:$skip {
ssh -R 5432:127.0.0.1:47001 test_target powershell.exe Test-WSMan -computer 127.0.0.1 -port 5432 | Set-Content $stdoutFile
$stdoutFile | Should Contain "wsmid"
}

View File

@ -1,11 +1,12 @@

If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force
#covered -i -p -q -r -v -c -S -C
#todo: -F, -l and -P should be tested over the network
Describe "Tests for scp command" -Tags "CI" {
BeforeAll {
if($OpenSSHTestInfo -eq $null)
{
Throw "`$OpenSSHTestInfo is null. Please run Setup-OpenSSHTestEnvironment to setup test environment."
Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments."
}
$fileName1 = "test.txt"
@ -19,8 +20,8 @@ Describe "Tests for scp command" -Tags "CI" {
$NestedSourceFilePath = Join-Path $NestedSourceDir $fileName2
$null = New-Item $SourceDir -ItemType directory -Force -ErrorAction SilentlyContinue
$null = New-Item $NestedSourceDir -ItemType directory -Force -ErrorAction SilentlyContinue
$null = New-item -path $SourceFilePath -force -ErrorAction SilentlyContinue
$null = New-item -path $NestedSourceFilePath -force -ErrorAction SilentlyContinue
$null = New-item -path $SourceFilePath -ItemType file -force -ErrorAction SilentlyContinue
$null = New-item -path $NestedSourceFilePath -ItemType file -force -ErrorAction SilentlyContinue
"Test content111" | Set-content -Path $SourceFilePath
"Test content in nested dir" | Set-content -Path $NestedSourceFilePath
$null = New-Item $DestinationDir -ItemType directory -Force -ErrorAction SilentlyContinue
@ -94,8 +95,8 @@ Describe "Tests for scp command" -Tags "CI" {
# for the first time, delete the existing log files.
if ($OpenSSHTestInfo['DebugMode'])
{
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" -Force -ErrorAction SilentlyContinue
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" -Force -ErrorAction SilentlyContinue
}
function CheckTarget {
@ -110,8 +111,8 @@ Describe "Tests for scp command" -Tags "CI" {
$script:logNum++
# clear the ssh-agent, sshd logs so that next testcase will get fresh logs.
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" -Force -ErrorAction SilentlyContinue
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" -Force -ErrorAction SilentlyContinue
}
return $false
@ -144,6 +145,7 @@ Describe "Tests for scp command" -Tags "CI" {
AfterEach {
Get-ChildItem $DestinationDir -Recurse | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
Start-Sleep 1
}
@ -184,7 +186,7 @@ Describe "Tests for scp command" -Tags "CI" {
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
$equal | Should Be $true
if($Options.contains("-p"))
if($Options.contains("-p") -and ($platform -eq [PlatformType]::Windows) -and ($PSVersionTable.PSVersion.Major -gt 2))
{
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir).LastWriteTime.DateTime (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ).LastWriteTime.DateTime).Length -eq 0
$equal | Should Be $true

View File

@ -1,9 +1,12 @@
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force -DisableNameChecking
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force
Describe "SFTP Test Cases" -Tags "CI" {
BeforeAll {
$serverDirectory = $null
$clientDirectory = $null
if($OpenSSHTestInfo -eq $null)
{
Throw "`$OpenSSHTestInfo is null. Please run Setup-OpenSSHTestEnvironment to setup test environment."
Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments."
}
$rootDirectory = "$($OpenSSHTestInfo["TestDataPath"])\SFTP"
@ -29,8 +32,11 @@ Describe "SFTP Test Cases" -Tags "CI" {
$ssouser = $OpenSSHTestInfo["SSOUser"]
$script:testId = 1
Remove-item (Join-Path $rootDirectory "*.$outputFileName") -Force -ErrorAction Ignore
Remove-item (Join-Path $rootDirectory "*.$batchFileName") -Force -ErrorAction Ignore
Remove-item (Join-Path $rootDirectory "*.$outputFileName") -Force -ErrorAction SilentlyContinue
Remove-item (Join-Path $rootDirectory "*.$batchFileName") -Force -ErrorAction SilentlyContinue
$platform = Get-Platform
$skip = ($platform -eq [PlatformType]::Windows) -and ($PSVersionTable.PSVersion.Major -le 2)
$testData1 = @(
@{
@ -162,9 +168,9 @@ Describe "SFTP Test Cases" -Tags "CI" {
# for the first time, delete the existing log files.
if ($OpenSSHTestInfo['DebugMode'])
{
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sftp-server.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" -Force -ErrorAction SilentlyContinue
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" -Force -ErrorAction SilentlyContinue
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sftp-server.log" -Force -ErrorAction SilentlyContinue
}
function CopyDebugLogs {
@ -175,21 +181,21 @@ Describe "SFTP Test Cases" -Tags "CI" {
Copy-Item "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sftp-server.log" "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sftp-server_$script:testId.log" -Force
# clear the ssh-agent, sshd logs so that next testcase will get fresh logs.
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sftp-server.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" -Force -ErrorAction SilentlyContinue
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" -Force -ErrorAction SilentlyContinue
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sftp-server.log" -Force -ErrorAction SilentlyContinue
}
}
}
AfterAll {
Get-ChildItem $serverDirectory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
Get-ChildItem $clientDirectory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
if($serverDirectory) { Get-ChildItem $serverDirectory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue }
if($clientDirectory) { Get-ChildItem $clientDirectory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue }
}
BeforeEach {
Get-ChildItem $serverDirectory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
Get-ChildItem $clientDirectory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
if($serverDirectory) { Get-ChildItem $serverDirectory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue }
if($clientDirectory) { Get-ChildItem $clientDirectory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue }
$outputFilePath = Join-Path $rootDirectory "$($script:testId).$outputFileName"
$batchFilePath = Join-Path $rootDirectory "$($script:testId).$batchFileName"
}
@ -212,6 +218,7 @@ Describe "SFTP Test Cases" -Tags "CI" {
It '<Title>' -TestCases:$testData2 {
param([string]$Title, $Options, $tmpFileName1, $tmpFilePath1, $tmpFileName2, $tmpFilePath2, $tmpDirectoryName1, $tmpDirectoryPath1, $tmpDirectoryName2, $tmpDirectoryPath2)
if($skip) { return }
#rm (remove file)
$commands = "mkdir $tmpDirectoryPath1
@ -263,16 +270,19 @@ Describe "SFTP Test Cases" -Tags "CI" {
}
It "$script:testId-ls lists items the user has no read permission" {
$adminsSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid)
$currentUserSid = Get-UserSID -User "$($env:USERDOMAIN)\$($env:USERNAME)"
$permTestHasAccessFile = "permTestHasAccessFile.txt"
$permTestHasAccessFilePath = Join-Path $serverDirectory $permTestHasAccessFile
Remove-Item $permTestHasAccessFilePath -Force -ErrorAction Ignore
Remove-Item $permTestHasAccessFilePath -Force -ErrorAction SilentlyContinue
New-Item $permTestHasAccessFilePath -ItemType file -Force -value "perm test has access file data" | Out-Null
$permTestNoAccessFile = "permTestNoAccessFile.txt"
$permTestNoAccessFilePath = Join-Path $serverDirectory $permTestNoAccessFile
Remove-Item $permTestNoAccessFilePath -Force -ErrorAction Ignore
Remove-Item $permTestNoAccessFilePath -Force -ErrorAction SilentlyContinue
New-Item $permTestNoAccessFilePath -ItemType file -Force -value "perm test no access file data" | Out-Null
Set-FileOwnerAndACL -Filepath $permTestNoAccessFilePath -OwnerPerms "Read","Write"
Repair-FilePermission -Filepath $permTestNoAccessFilePath -Owners $currentUserSid -FullAccessNeeded $adminsSid,$currentUserSid -confirm:$false
$Commands = "ls $serverDirectory"
Set-Content $batchFilePath -Encoding UTF8 -value $Commands
@ -282,11 +292,11 @@ Describe "SFTP Test Cases" -Tags "CI" {
#cleanup
$HasAccessPattern = $permTestHasAccessFilePath.Replace("\", "[/\\]")
$matches = $content | select-string -Pattern "^/$HasAccessPattern\s{0,}$"
$matches = @($content | select-string -Pattern "^/$HasAccessPattern\s{0,}$")
$matches.count | Should be 1
$NoAccessPattern = $permTestNoAccessFilePath.Replace("\", "[/\\]")
$matches = $content | select-string -Pattern "^/$NoAccessPattern\s{0,}$"
$matches = @($content | select-string -Pattern "^/$NoAccessPattern\s{0,}$")
$matches.count | Should be 1
}
}

View File

@ -1,4 +1,6 @@
#todo: -i -q -v -l -c -C
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force
#todo: -i -q -v -l -c -C
#todo: -S -F -V -e
$tC = 1
$tI = 0
@ -8,7 +10,7 @@ Describe "E2E scenarios for ssh client" -Tags "CI" {
BeforeAll {
if($OpenSSHTestInfo -eq $null)
{
Throw "`$OpenSSHTestInfo is null. Please run Setup-OpenSSHTestEnvironment to setup test environment."
Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments."
}
$server = $OpenSSHTestInfo["Target"]
@ -20,6 +22,8 @@ Describe "E2E scenarios for ssh client" -Tags "CI" {
{
$null = New-Item $testDir -ItemType directory -Force -ErrorAction SilentlyContinue
}
$platform = Get-Platform
$skip = ($platform -eq [PlatformType]::Windows) -and ($PSVersionTable.PSVersion.Major -le 2)
<#$testData = @(
@{
@ -112,7 +116,7 @@ Describe "E2E scenarios for ssh client" -Tags "CI" {
BeforeAll {$tI=1}
AfterAll{$tC++}
It "$tC.$tI - stdout to file" {
It "$tC.$tI - stdout to file" -skip:$skip {
ssh test_target powershell get-process > $stdoutFile
$stdoutFile | Should Contain "ProcessName"
}

View File

@ -50,7 +50,7 @@
$client.AddPasswordSetting($password)
}
AfterEach {
Remove-Item -Path $filePath -Force -ea ignore
Remove-Item -Path $filePath -Force -ea SilentlyContinue
}
AfterAll {

View File

@ -1,4 +1,5 @@
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force -DisableNameChecking
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force
$tC = 1
$tI = 0
@ -8,7 +9,7 @@ Describe "Tests for user Key file permission" -Tags "CI" {
BeforeAll {
if($OpenSSHTestInfo -eq $null)
{
Throw "`$OpenSSHTestInfo is null. Please run Setup-OpenSSHTestEnvironment to setup test environment."
Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to setup test environment."
}
$testDir = "$($OpenSSHTestInfo["TestDataPath"])\$suite"
if( -not (Test-path $testDir -PathType Container))
@ -24,13 +25,13 @@ Describe "Tests for user Key file permission" -Tags "CI" {
$server = $OpenSSHTestInfo["Target"]
$userName = "$env:USERNAME@$env:USERDOMAIN"
$keypassphrase = "testpassword"
$systemAccount = New-Object System.Security.Principal.NTAccount("NT AUTHORITY", "SYSTEM")
$adminsAccount = New-Object System.Security.Principal.NTAccount("BUILTIN","Administrators")
$objUser = New-Object System.Security.Principal.NTAccount($ssouser)
$pubKeyUserAccount = New-Object System.Security.Principal.NTAccount($pubKeyUser)
$currentUser = New-Object System.Security.Principal.NTAccount($($env:USERDOMAIN), $($env:USERNAME))
$everyone = New-Object System.Security.Principal.NTAccount("EveryOne")
$systemSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::LocalSystemSid)
$adminsSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid)
$currentUserSid = Get-UserSID -User "$($env:USERDOMAIN)\$($env:USERNAME)"
$objUserSid = Get-UserSID -User $ssouser
$everyoneSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::WorldSid)
$pubKeyUserAccountSid = Get-UserSID -User $pubKeyUser
Add-PasswordSetting -Pass $keypassphrase
}
@ -48,7 +49,7 @@ Describe "Tests for user Key file permission" -Tags "CI" {
BeforeAll {
$keyFileName = "sshtest_userPermTestkey_ed25519"
$keyFilePath = Join-Path $testDir $keyFileName
Remove-Item -path "$keyFilePath*" -Force -ErrorAction Ignore
Remove-Item -path "$keyFilePath*" -Force -ErrorAction SilentlyContinue
ssh-keygen.exe -t ed25519 -f $keyFilePath -P $keypassphrase
$pubKeyUserProfilePath = Join-Path $pubKeyUserProfile .ssh
@ -58,22 +59,22 @@ Describe "Tests for user Key file permission" -Tags "CI" {
$testAuthorizedKeyPath = Join-Path $pubKeyUserProfilePath authorized_keys
Copy-Item "$keyFilePath.pub" $testAuthorizedKeyPath -Force -ErrorAction SilentlyContinue
Adjust-UserKeyFileACL -FilePath $testAuthorizedKeyPath -Owner $pubKeyUserAccount -OwnerPerms "Read, Write"
Add-PermissionToFileACL -FilePath $testAuthorizedKeyPath -User "NT Service\sshd" -Perm "Read"
Repair-AuthorizedKeyPermission -FilePath $testAuthorizedKeyPath -confirm:$false
$tI=1
}
AfterAll {
if(Test-Path $testAuthorizedKeyPath) {
Remove-Item $testAuthorizedKeyPath -Force -ErrorAction Ignore
Remove-Item $testAuthorizedKeyPath -Force -ErrorAction SilentlyContinue
}
if(Test-Path $pubKeyUserProfilePath) {
Remove-Item $pubKeyUserProfilePath -Recurse -Force -ErrorAction Ignore
Remove-Item $pubKeyUserProfilePath -Recurse -Force -ErrorAction SilentlyContinue
}
$tC++
}
It "$tC.$tI-ssh with private key file -- positive (Secured private key owned by current user)" {
Set-FileOwnerAndACL -FilePath $keyFilePath -Owner $currentUser -OwnerPerms "Read, Write"
Repair-FilePermission -FilePath $keyFilePath -Owners $currentUserSid -FullAccessNeeded $adminsSid,$systemSid,$currentUserSid -confirm:$false
#Run
$o = ssh -p $port -i $keyFilePath $pubKeyUser@$server echo 1234
$o | Should Be "1234"
@ -81,7 +82,7 @@ Describe "Tests for user Key file permission" -Tags "CI" {
It "$tC.$tI-ssh with private key file -- positive(Secured private key owned by Administrators group and current user has no explicit ACE)" {
#setup to have local admin group as owner and grant it full control
Set-FileOwnerAndACL -FilePath $keyFilePath -Owner $adminsAccount -OwnerPerms "FullControl"
Repair-FilePermission -FilePath $keyFilePath -Owners $adminsSid -FullAccessNeeded $adminsSid,$systemSid -confirm:$false
#Run
$o = ssh -p $port -i $keyFilePath $pubKeyUser@$server echo 1234
@ -90,8 +91,7 @@ Describe "Tests for user Key file permission" -Tags "CI" {
It "$tC.$tI-ssh with private key file -- positive(Secured private key owned by Administrators group and current user has explicit ACE)" {
#setup to have local admin group as owner and grant it full control
Set-FileOwnerAndACL -FilePath $keyFilePath -Owner $adminsAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath $keyFilePath -User $currentUser -Perm "Read"
Repair-FilePermission -FilePath $keyFilePath -Owners $adminsSid -FullAccessNeeded $adminsSid,$systemSid -ReadAccessNeeded $currentUserSid -confirm:$false
#Run
$o = ssh -p $port -i $keyFilePath $pubKeyUser@$server echo 1234
@ -100,8 +100,7 @@ Describe "Tests for user Key file permission" -Tags "CI" {
It "$tC.$tI-ssh with private key file -- positive (Secured private key owned by local system)" {
#setup to have local system as owner and grant it full control
Set-FileOwnerAndACL -FilePath $keyFilePath -Owner $systemAccount -OwnerPerms "FullControl"
Add-PermissionToFileACL -FilePath $keyFilePath -User $adminsAccount -Perm "Read"
Repair-FilePermission -FilePath $keyFilePath -Owners $systemSid -FullAccessNeeded $adminsSid,$systemSid -confirm:$false
#Run
$o = ssh -p $port -i $keyFilePath $pubKeyUser@$server echo 1234
@ -109,11 +108,8 @@ Describe "Tests for user Key file permission" -Tags "CI" {
}
It "$tC.$tI-ssh with private key file -- negative(other account can access private key file)" {
#setup to have current user as owner and grant it full control
Set-FileOwnerAndACL -FilePath $keyFilePath -Owner $currentUser -OwnerPerms "Read, Write"
#add ssouser to access the private key
Add-PermissionToFileACL -FilePath $keyFilePath -User $objUser -Perm "Read"
#setup to have current user as owner and grant it full control
Repair-FilePermission -FilePath $keyFilePath -Owners $currentUserSid -FullAccessNeeded $currentUser,$adminsSid,$systemSid -ReadAccessNeeded $objUserSid -confirm:$false
#Run
$o = ssh -p $port -i $keyFilePath -E $logPath $pubKeyUser@$server echo 1234
@ -123,9 +119,8 @@ Describe "Tests for user Key file permission" -Tags "CI" {
}
It "$tC.$tI-ssh with private key file -- negative(the private key has wrong owner)" {
#setup to have ssouser as owner and grant it full control
Set-FileOwnerAndACL -FilePath $keyFilePath -Owner $objUser -OwnerPerms "Read, Write"
Add-PermissionToFileACL -FilePath $keyFilePath -User $adminsAccount -Perm "FullControl"
#setup to have ssouser as owner and grant it full control
Repair-FilePermission -FilePath $keyFilePath -Owners $objUserSid -FullAccessNeeded $objUserSid,$adminsSid,$systemSid -ReadAccessNeeded $objUserSid -confirm:$false
$o = ssh -p $port -i $keyFilePath -E $logPath $pubKeyUser@$server echo 1234
$LASTEXITCODE | Should Not Be 0