Repository navigation
Expand file tree
/
Copy pathTest-Repository.ps1
More file actions
80 lines (71 loc) · 3.07 KB
/
Copy pathTest-Repository.ps1
File metadata and controls
80 lines (71 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#Requires -Version 5.1
[CmdletBinding()]
param()
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$repositoryRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
$failures = [System.Collections.Generic.List[string]]::new()
$powerShellFiles = @(Get-ChildItem -LiteralPath $repositoryRoot -Filter '*.ps1' -File -Recurse)
foreach ($file in $powerShellFiles) {
$tokens = $null
$parseErrors = $null
[System.Management.Automation.Language.Parser]::ParseFile($file.FullName, [ref]$tokens, [ref]$parseErrors) | Out-Null
foreach ($parseError in $parseErrors) {
$relativePath = $file.FullName.Substring($repositoryRoot.Length).TrimStart('\', '/')
$failures.Add("${relativePath}:$($parseError.Extent.StartLineNumber): $($parseError.Message)")
}
}
$requiredFiles = @(
'README.md',
'LICENSE',
'SECURITY.md',
'CONTRIBUTING.md',
'New-DebianUnattendedUsb.ps1',
'docs\TROUBLESHOOTING.md'
)
foreach ($relativePath in $requiredFiles) {
if (-not (Test-Path -LiteralPath (Join-Path $repositoryRoot $relativePath) -PathType Leaf)) {
$failures.Add("Missing required file: $relativePath")
}
}
$textFiles = @(
Get-ChildItem -LiteralPath $repositoryRoot -File -Recurse |
Where-Object { $_.Extension -in @('.ps1', '.md', '.yml', '.yaml', '.txt') -or $_.Name -in @('LICENSE', '.gitignore') }
)
$forbiddenPatterns = @(
[pscustomobject]@{ Name = 'private key material'; Pattern = '-----BEGIN (?:OPENSSH|RSA|EC|DSA) PRIVATE KEY-----' },
[pscustomobject]@{ Name = 'machine-specific Windows user path'; Pattern = '(?i)C:\\Users\\[^\\\r\n]+\\' },
[pscustomobject]@{ Name = 'embedded Ed25519 public key'; Pattern = '(?m)^ssh-ed25519\s+AAA[A-Za-z0-9+/=]{30,}' },
[pscustomobject]@{ Name = 'generated plaintext credential'; Pattern = '(?m)^Console password:\s+(?!\$|<|__)[A-Za-z0-9]{16,}\s*$' }
)
foreach ($file in $textFiles) {
$content = Get-Content -LiteralPath $file.FullName -Raw
foreach ($forbidden in $forbiddenPatterns) {
if ($content -match $forbidden.Pattern) {
$relativePath = $file.FullName.Substring($repositoryRoot.Length).TrimStart('\', '/')
$failures.Add("$relativePath contains $($forbidden.Name).")
}
}
}
$builderPath = Join-Path $repositoryRoot 'New-DebianUnattendedUsb.ps1'
if (Test-Path -LiteralPath $builderPath -PathType Leaf) {
$builder = Get-Content -LiteralPath $builderPath -Raw
foreach ($requiredSafetyText in @(
'#Requires -RunAsAdministrator',
'THE SELECTED USB WILL BE ERASED COMPLETELY',
'expected exactly one matching non-USB target disk',
'AUTO_INSTALL_ARMED',
'set timeout=-1',
'PermitRootLogin no',
'PasswordAuthentication no'
)) {
if (-not $builder.Contains($requiredSafetyText)) {
$failures.Add("Builder is missing safety marker: $requiredSafetyText")
}
}
}
if ($failures.Count -gt 0) {
$failures | ForEach-Object { Write-Error $_ }
exit 1
}
Write-Host "Validated $($powerShellFiles.Count) PowerShell files and $($textFiles.Count) repository text files."