2cddf06b6c
Co-authored-by: 旅行呀~ <travelxiao@qq.com>
110 lines
3.5 KiB
PowerShell
110 lines
3.5 KiB
PowerShell
# Orchestrate Gitea SSH + GPG key verification challenges.
|
|
# Challenge tokens come from /user/settings/keys Verify page (short-lived).
|
|
# Never store them. Never confuse with the HTTPS access token in token.dpapi.
|
|
|
|
param(
|
|
[string]$GpgToken,
|
|
[string]$SshToken,
|
|
[string]$KeyId,
|
|
[string]$KeyPath,
|
|
[switch]$GpgOnly,
|
|
[switch]$SshOnly
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
. (Join-Path $PSScriptRoot 'common.ps1')
|
|
|
|
function Resolve-DefaultGpgKeyId {
|
|
$ensure = Join-Path $PSScriptRoot 'ensure-gpg.ps1'
|
|
$gitProfile = Get-GitSkillsProfile
|
|
$name = if ($gitProfile) { [string]$gitProfile.userName } else { '' }
|
|
$email = if ($gitProfile) { [string]$gitProfile.userEmail } else { '' }
|
|
$prev = $ErrorActionPreference
|
|
$ErrorActionPreference = 'Continue'
|
|
try {
|
|
$out = & powershell -NoProfile -ExecutionPolicy Bypass -File $ensure -Name $name -Email $email 2>&1 | Out-String
|
|
}
|
|
finally {
|
|
$ErrorActionPreference = $prev
|
|
}
|
|
if ($out -match 'key_id=([0-9A-Fa-f]+)') {
|
|
return $Matches[1]
|
|
}
|
|
return $null
|
|
}
|
|
|
|
$doGpg = -not $SshOnly
|
|
$doSsh = -not $GpgOnly
|
|
if (-not $doGpg -and -not $doSsh) {
|
|
Write-StatusLine -Key 'status' -Value 'failed'
|
|
Write-StatusLine -Key 'reason' -Value 'nothing_to_verify'
|
|
exit 1
|
|
}
|
|
|
|
$failed = $false
|
|
|
|
if ($doGpg) {
|
|
if ([string]::IsNullOrWhiteSpace($GpgToken)) {
|
|
Write-StatusLine -Key 'gpg' -Value 'need_token'
|
|
Write-Output 'ask=Open Gitea Settings > SSH/GPG keys > GPG Verify, paste the page challenge token here (NOT the HTTPS access token)'
|
|
}
|
|
else {
|
|
if ([string]::IsNullOrWhiteSpace($KeyId)) {
|
|
$KeyId = Resolve-DefaultGpgKeyId
|
|
}
|
|
if ([string]::IsNullOrWhiteSpace($KeyId)) {
|
|
Write-StatusLine -Key 'gpg' -Value 'failed'
|
|
Write-StatusLine -Key 'reason' -Value 'gpg_key_id_missing'
|
|
$failed = $true
|
|
}
|
|
else {
|
|
Write-StatusLine -Key 'gpg_key_id' -Value $KeyId
|
|
& (Join-Path $PSScriptRoot 'verify-gpg-challenge.ps1') -Token $GpgToken -KeyId $KeyId
|
|
if ($LASTEXITCODE -ne 0) {
|
|
$failed = $true
|
|
}
|
|
else {
|
|
Write-Output 'gpg_next=Paste the BEGIN/END PGP SIGNATURE block back into Gitea GPG Verify, then click Verify'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($doSsh) {
|
|
if ([string]::IsNullOrWhiteSpace($SshToken)) {
|
|
Write-StatusLine -Key 'ssh' -Value 'need_token'
|
|
Write-Output 'ask=Open Gitea Settings > SSH/GPG keys > SSH Verify, paste that page challenge token here (different from GPG token)'
|
|
}
|
|
else {
|
|
$sshInvoke = @{
|
|
Token = $SshToken
|
|
}
|
|
if (-not [string]::IsNullOrWhiteSpace($KeyPath)) {
|
|
$sshInvoke['KeyPath'] = $KeyPath
|
|
}
|
|
& (Join-Path $PSScriptRoot 'verify-ssh-challenge.ps1') @sshInvoke
|
|
if ($LASTEXITCODE -ne 0) {
|
|
$failed = $true
|
|
}
|
|
else {
|
|
Write-Output 'ssh_next=Paste the BEGIN/END SSH SIGNATURE block back into Gitea SSH Verify, then click Verify'
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($failed) {
|
|
Write-StatusLine -Key 'status' -Value 'failed'
|
|
exit 1
|
|
}
|
|
|
|
$gpgPending = $doGpg -and [string]::IsNullOrWhiteSpace($GpgToken)
|
|
$sshPending = $doSsh -and [string]::IsNullOrWhiteSpace($SshToken)
|
|
if ($gpgPending -or $sshPending) {
|
|
Write-StatusLine -Key 'status' -Value 'waiting_for_tokens'
|
|
exit 0
|
|
}
|
|
|
|
Write-StatusLine -Key 'status' -Value 'signatures_ready'
|
|
Write-Output 'done=Signatures generated. After user pastes them on Gitea and clicks Verify, check new commits for verified status.'
|
|
exit 0
|