@@ -0,0 +1,114 @@
|
||||
# Detect or generate ED25519 SSH key. Print public key only. Never print the private key.
|
||||
|
||||
param(
|
||||
[string]$Email,
|
||||
[string]$KeyPath,
|
||||
[switch]$ForceGenerate,
|
||||
[switch]$NoGenerate,
|
||||
[switch]$Quiet
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
. (Join-Path $PSScriptRoot 'common.ps1')
|
||||
|
||||
$gitProfile = Get-GitSkillsProfile
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($Email)) {
|
||||
if ($gitProfile) { $Email = [string]$gitProfile.userEmail }
|
||||
}
|
||||
if ([string]::IsNullOrWhiteSpace($Email)) {
|
||||
$Email = [string](Get-GitSkillsDefaults).userEmail
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($KeyPath)) {
|
||||
if ($gitProfile -and $gitProfile.sshKeyPath) {
|
||||
$KeyPath = [string]$gitProfile.sshKeyPath
|
||||
} else {
|
||||
$KeyPath = Join-Path $env:USERPROFILE '.ssh\id_ed25519'
|
||||
}
|
||||
}
|
||||
|
||||
if (Test-Path -LiteralPath $KeyPath -PathType Container) {
|
||||
$KeyPath = Join-Path $KeyPath 'id_ed25519'
|
||||
}
|
||||
|
||||
$pubPath = $KeyPath + '.pub'
|
||||
$sshDir = Split-Path -Parent $KeyPath
|
||||
if (-not (Test-Path -LiteralPath $sshDir)) {
|
||||
New-Item -ItemType Directory -Path $sshDir -Force | Out-Null
|
||||
}
|
||||
|
||||
$status = 'exists'
|
||||
if ($NoGenerate -and -not (Test-Path -LiteralPath $KeyPath)) {
|
||||
Write-StatusLine -Key 'status' -Value 'failed'
|
||||
Write-StatusLine -Key 'reason' -Value 'ssh_key_missing'
|
||||
Write-StatusLine -Key 'key_path' -Value $KeyPath
|
||||
exit 1
|
||||
}
|
||||
|
||||
if ($ForceGenerate -or -not (Test-Path -LiteralPath $KeyPath)) {
|
||||
if ((Test-Path -LiteralPath $KeyPath) -and $ForceGenerate) {
|
||||
Write-StatusLine -Key 'status' -Value 'failed'
|
||||
Write-StatusLine -Key 'reason' -Value 'refusing_to_overwrite_ssh_key'
|
||||
Write-StatusLine -Key 'key_path' -Value $KeyPath
|
||||
exit 1
|
||||
}
|
||||
|
||||
$sshKeygen = Get-Command ssh-keygen -ErrorAction SilentlyContinue
|
||||
if ($null -eq $sshKeygen) {
|
||||
Write-StatusLine -Key 'status' -Value 'failed'
|
||||
Write-StatusLine -Key 'reason' -Value 'ssh_keygen_missing'
|
||||
exit 1
|
||||
}
|
||||
|
||||
Invoke-GitSkillsNative -FilePath ssh-keygen -ArgumentList @('-t', 'ed25519', '-C', $Email, '-f', $KeyPath, '-N', '""') | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-StatusLine -Key 'status' -Value 'failed'
|
||||
Write-StatusLine -Key 'reason' -Value 'ssh_keygen_failed'
|
||||
exit 1
|
||||
}
|
||||
$status = 'created'
|
||||
}
|
||||
|
||||
if (-not (Test-Path -LiteralPath $pubPath)) {
|
||||
Write-StatusLine -Key 'status' -Value 'failed'
|
||||
Write-StatusLine -Key 'reason' -Value 'public_key_missing'
|
||||
Write-StatusLine -Key 'key_path' -Value $KeyPath
|
||||
exit 1
|
||||
}
|
||||
|
||||
$agent = 'unavailable'
|
||||
$added = 'skipped'
|
||||
$svc = Get-Service -Name ssh-agent -ErrorAction SilentlyContinue
|
||||
if ($null -ne $svc) {
|
||||
try {
|
||||
if ($svc.StartType -eq 'Disabled') {
|
||||
Set-Service -Name ssh-agent -StartupType Manual
|
||||
}
|
||||
if ((Get-Service -Name ssh-agent).Status -ne 'Running') {
|
||||
Start-Service -Name ssh-agent
|
||||
}
|
||||
$agent = 'running'
|
||||
Invoke-GitSkillsNative -FilePath ssh-add -ArgumentList @($KeyPath) | Out-Null
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
$added = 'yes'
|
||||
} else {
|
||||
$added = 'failed'
|
||||
}
|
||||
}
|
||||
catch {
|
||||
$agent = 'error'
|
||||
$added = 'failed'
|
||||
}
|
||||
}
|
||||
|
||||
$publicKey = (Get-Content -LiteralPath $pubPath -Raw -Encoding UTF8).Trim()
|
||||
|
||||
Write-StatusLine -Key 'status' -Value $status
|
||||
Write-StatusLine -Key 'key_path' -Value $KeyPath
|
||||
Write-StatusLine -Key 'public_key_path' -Value $pubPath
|
||||
Write-StatusLine -Key 'ssh_agent' -Value $agent
|
||||
Write-StatusLine -Key 'ssh_add' -Value $added
|
||||
if (-not $Quiet) {
|
||||
Write-Output ('public_key=' + $publicKey)
|
||||
}
|
||||
Reference in New Issue
Block a user