You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
4.6 KiB
67 lines
4.6 KiB
|
6 days ago
|
param([string]$BuildFolder = 'NetworkTools')
|
||
|
|
|
||
|
|
if ($PSVersionTable.PSEdition -ne 'Desktop') {
|
||
|
|
& "$env:SystemRoot/System32/WindowsPowerShell/v1.0/powershell.exe" -NoProfile -STA -ExecutionPolicy Bypass -File $PSCommandPath -BuildFolder $BuildFolder
|
||
|
|
exit $LASTEXITCODE
|
||
|
|
}
|
||
|
|
$ErrorActionPreference = 'Stop'
|
||
|
|
Add-Type -AssemblyName PresentationFramework
|
||
|
|
$networkAssembly = [Reflection.Assembly]::LoadFrom((Join-Path $PSScriptRoot "DCT_test/bin/$BuildFolder/DCT_test.exe"))
|
||
|
|
function Assert-Network($condition, $message) { if (-not $condition) { throw $message } }
|
||
|
|
Add-Type @'
|
||
|
|
public class FirewallRuleProbe {
|
||
|
|
public string Name {get;set;}
|
||
|
|
public string Description {get;set;}
|
||
|
|
public string Grouping {get;set;}
|
||
|
|
public string ApplicationName {get;set;}
|
||
|
|
public int Protocol {get;set;}
|
||
|
|
public string LocalPorts {get;set;}
|
||
|
|
public string LocalAddresses {get;set;}
|
||
|
|
public string RemoteAddresses {get;set;}
|
||
|
|
public int Direction {get;set;}
|
||
|
|
public int Action {get;set;}
|
||
|
|
public int Profiles {get;set;}
|
||
|
|
public bool EdgeTraversal {get;set;}
|
||
|
|
public bool Enabled {get;set;}
|
||
|
|
}
|
||
|
|
'@
|
||
|
|
$exe = $networkAssembly.Location
|
||
|
|
$settings = [DCT_test.NetworkFirewallSettings]::new($exe, 5000, 'ap', '192.168.200.5,192.168.200.5')
|
||
|
|
$rule = New-Object FirewallRuleProbe
|
||
|
|
[DCT_test.NetworkSupport]::ConfigureRule($rule, $settings)
|
||
|
|
Assert-Network ($rule.ApplicationName -eq $exe -and $rule.Protocol -eq 6 -and $rule.LocalPorts -eq '5000') 'Rule must restrict executable and TCP port'
|
||
|
|
Assert-Network ($rule.LocalAddresses -eq '192.168.200.5' -and $rule.RemoteAddresses -eq 'LocalSubnet') 'Rule must restrict local IPv4 and remote subnet'
|
||
|
|
Assert-Network ($rule.Direction -eq 1 -and $rule.Action -eq 1 -and $rule.Enabled -and $rule.Profiles -eq 7 -and -not $rule.EdgeTraversal) 'Inbound allow policy contract'
|
||
|
|
Assert-Network ($settings.HelperArguments -eq '--allow-network 5000 ap 192.168.200.5') 'Validated UAC helper arguments'
|
||
|
|
$changedIp = [DCT_test.NetworkFirewallSettings]::new($exe,5000,'ap','192.168.200.6')
|
||
|
|
$direct = [DCT_test.NetworkFirewallSettings]::new($exe,5000,'direct','192.168.137.1')
|
||
|
|
Assert-Network ($changedIp.RuleName -eq $settings.RuleName -and $direct.RuleName -ne $settings.RuleName) 'DHCP updates same rule; Direct/AP remain separate'
|
||
|
|
foreach ($badAddress in @('*','0.0.0.0','127.0.0.1','224.0.0.1','::1','192.168.200.0/24','192.168.200.5;whoami','192.168.1','')) {
|
||
|
|
$rejected = $false
|
||
|
|
try { [void][DCT_test.NetworkFirewallSettings]::new($exe,5000,'ap',$badAddress) } catch { $rejected = $true }
|
||
|
|
Assert-Network $rejected ('Unsafe address accepted: ' + $badAddress)
|
||
|
|
}
|
||
|
|
foreach ($badPort in @(0,65536)) {
|
||
|
|
$rejected = $false
|
||
|
|
try { [void][DCT_test.NetworkFirewallSettings]::new($exe,$badPort,'ap','192.168.200.5') } catch { $rejected = $true }
|
||
|
|
Assert-Network $rejected 'Invalid port accepted'
|
||
|
|
}
|
||
|
|
$report = [DCT_test.NetworkSupport]::BuildReport('ap',5000,'203.0.113.111',$false,[string[]]@(),[string[]]@())
|
||
|
|
Assert-Network ($report.Contains('203.0.113.111:5000') -and $report.Contains('ARP') -and $report.Contains('netsh') -eq $false) 'Report must identify selected endpoint and ARP limitation without requiring terminal commands'
|
||
|
|
Assert-Network ($report.Contains('Windows TCP') -and $report.Contains('Wi-Fi AP')) 'Report must include listener and AP inventory'
|
||
|
|
Assert-Network ($report.Contains([DCT_test.NetworkSupport]::ExecutablePath)) 'Report must use actual executable path'
|
||
|
|
$korean = [string][char]0xC5F0 + [string][char]0xACB0
|
||
|
|
Assert-Network ([DCT_test.NetworkSupport]::DecodeConsoleOutput([Text.Encoding]::UTF8.GetBytes($korean)) -eq $korean) 'Korean UTF-8 console text must remain readable'
|
||
|
|
$oem = [Text.Encoding]::GetEncoding([Globalization.CultureInfo]::CurrentCulture.TextInfo.OEMCodePage)
|
||
|
|
if ($oem.CodePage -eq 949) {
|
||
|
|
Assert-Network ([DCT_test.NetworkSupport]::DecodeConsoleOutput($oem.GetBytes($korean)) -eq $korean) 'Legacy Korean console output must remain readable'
|
||
|
|
}
|
||
|
|
Write-Output $report
|
||
|
|
$window = New-Object DCT_test.MainWindow
|
||
|
|
try {
|
||
|
|
Assert-Network ($null -ne $window.FindName('BtnNetworkDiagnostics') -and $null -ne $window.FindName('BtnAllowNetwork')) 'Network action buttons missing'
|
||
|
|
$window.GetType().GetMethod('BtnAllowNetwork_Click',[Reflection.BindingFlags]'Instance,NonPublic').Invoke($window,@($null,$null)) | Out-Null
|
||
|
|
Assert-Network ($window.FindName('BtnAllowNetwork').IsEnabled -and $window.FindName('BtnToggleServer').IsEnabled) 'Stopped server must not launch or lock the admin helper'
|
||
|
|
} finally { $window.Close() }
|
||
|
|
Write-Output 'PASS: firewall plan scope, validation, helper arguments, DHCP/mode rule identity, real read-only network/firewall/AP report, stopped-server guard (no firewall changes or UAC)'
|