103 lines
3.9 KiB
PowerShell
103 lines
3.9 KiB
PowerShell
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $true, Position = 0)]
|
|
[ValidateSet(
|
|
"runtime-check",
|
|
"initialize",
|
|
"status",
|
|
"build-recovery-keyrings",
|
|
"pin-source",
|
|
"sign-rc06-keyring",
|
|
"sign-apply-payloads",
|
|
"provision-apply-private-key"
|
|
)]
|
|
[string]$Command,
|
|
|
|
[Parameter(ValueFromRemainingArguments = $true)]
|
|
[string[]]$CommandArguments
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
$env:PSModulePath = @(
|
|
(Join-Path $env:SystemRoot "System32\WindowsPowerShell\v1.0\Modules")
|
|
(Join-Path $env:ProgramFiles "WindowsPowerShell\Modules")
|
|
) -join ";"
|
|
|
|
function Get-TrustedPythonCandidates {
|
|
$candidatePaths = [System.Collections.Generic.List[string]]::new()
|
|
foreach ($pattern in @(
|
|
(Join-Path $env:LOCALAPPDATA "Python\pythoncore-*\python.exe")
|
|
(Join-Path $env:LOCALAPPDATA "Programs\Python\Python*\python.exe")
|
|
(Join-Path $env:ProgramFiles "Python*\python.exe")
|
|
)) {
|
|
Get-ChildItem -Path $pattern -File -ErrorAction SilentlyContinue |
|
|
ForEach-Object { $candidatePaths.Add($_.FullName) }
|
|
}
|
|
foreach ($registryRoot in @(
|
|
"Registry::HKEY_CURRENT_USER\Software\Python\PythonCore"
|
|
"Registry::HKEY_LOCAL_MACHINE\Software\Python\PythonCore"
|
|
)) {
|
|
Get-ChildItem -LiteralPath $registryRoot -ErrorAction SilentlyContinue |
|
|
ForEach-Object {
|
|
$properties = Get-ItemProperty -LiteralPath (Join-Path $_.PSPath "InstallPath") -ErrorAction SilentlyContinue
|
|
if ($properties.ExecutablePath) {
|
|
$candidatePaths.Add([string]$properties.ExecutablePath)
|
|
} elseif ($properties.'(default)') {
|
|
$candidatePaths.Add((Join-Path ([string]$properties.'(default)') "python.exe"))
|
|
}
|
|
}
|
|
}
|
|
|
|
$trusted = foreach ($candidatePath in $candidatePaths | Sort-Object -Unique) {
|
|
if (-not (Test-Path -LiteralPath $candidatePath -PathType Leaf)) { continue }
|
|
$item = Get-Item -LiteralPath $candidatePath -Force
|
|
if (($item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) -ne 0) { continue }
|
|
if ($item.FullName -like "*\Microsoft\WindowsApps\*") { continue }
|
|
$version = [version]::new(
|
|
[Math]::Max(0, $item.VersionInfo.FileMajorPart),
|
|
[Math]::Max(0, $item.VersionInfo.FileMinorPart),
|
|
[Math]::Max(0, $item.VersionInfo.FileBuildPart),
|
|
[Math]::Max(0, $item.VersionInfo.FilePrivatePart)
|
|
)
|
|
if ($version -lt [version]"3.11") { continue }
|
|
$signature = Get-AuthenticodeSignature -LiteralPath $item.FullName
|
|
if (
|
|
$signature.Status -ne [System.Management.Automation.SignatureStatus]::Valid -or
|
|
$null -eq $signature.SignerCertificate -or
|
|
$signature.SignerCertificate.Subject -notlike "*CN=Python Software Foundation*"
|
|
) { continue }
|
|
[pscustomobject]@{ Path = $item.FullName; Version = $version }
|
|
}
|
|
return $trusted | Sort-Object Version -Descending
|
|
}
|
|
|
|
try {
|
|
$authorityScript = Join-Path $PSScriptRoot "rc06-release-trust-bootstrap.py"
|
|
if (-not (Test-Path -LiteralPath $authorityScript -PathType Leaf)) {
|
|
throw "The release authority program is missing"
|
|
}
|
|
Remove-Item Env:PYTHONPATH -ErrorAction SilentlyContinue
|
|
Remove-Item Env:PYTHONHOME -ErrorAction SilentlyContinue
|
|
Remove-Item Env:PYTHONSTARTUP -ErrorAction SilentlyContinue
|
|
Remove-Item Env:PYTHONUSERBASE -ErrorAction SilentlyContinue
|
|
$runtime = $null
|
|
$ErrorActionPreference = "Continue"
|
|
foreach ($candidate in @(Get-TrustedPythonCandidates)) {
|
|
$preflightOutput = @(& $candidate.Path -I -S -B $authorityScript runtime-check 2>&1)
|
|
if ($LASTEXITCODE -eq 0) {
|
|
$runtime = $candidate
|
|
break
|
|
}
|
|
}
|
|
$ErrorActionPreference = "Stop"
|
|
if ($null -eq $runtime) {
|
|
throw "No trusted offline Python runtime has DPAPI and the required cryptography dependency"
|
|
}
|
|
& $runtime.Path -I -S -B $authorityScript $Command @CommandArguments
|
|
exit $LASTEXITCODE
|
|
} catch {
|
|
Write-Host ("Authority startup failed: " + $_.Exception.Message) -ForegroundColor Red
|
|
Write-Host "No authority key, source pin, keyring, signature, or private-key export was created."
|
|
exit 2
|
|
}
|