Providers/FreeIPA/Private/Import-FreeIPACredential.ps1
|
function Import-FreeIPACredential { <# .SYNOPSIS Reads the service account credential record and recovers its password .DESCRIPTION The inverse of Export-FreeIPACredential. The record says where the password is, and this reads it from there: the SecretStore vault it names, or the DPAPI-protected value in the record itself. A record with no protection at all - written on a platform that could not encrypt - is read with a warning, so nobody mistakes it for a safe file. A byte order mark is stripped before parsing, because a record edited by hand in an editor that adds one would otherwise fail as malformed JSON. .PARAMETER Path The record to read. .PARAMETER VaultPassword The vault's password, when the password is in a vault whose password is not a default. .OUTPUTS PSCustomObject with BaseUrl, Username, Password, CaCertificate, Protection, VaultName, SecretName, CreatedUtc and Path. .EXAMPLE PS> $credential = Import-FreeIPACredential -Path $path DESCRIPTION: Reads the record and recovers the password OUTPUT: The credential with its plaintext password USE CASE: Connect-FreeIPAEnvironment -ServiceAccount .NOTES Author: Jeffrey Stuhr Blog: https://www.techbyjeff.net LinkedIn: https://www.linkedin.com/in/jeffrey-stuhr-034214aa/ #> [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$Path, [Parameter()] [System.Security.SecureString]$VaultPassword ) if (-not (Test-Path -LiteralPath $Path)) { throw "No service account credential record at $Path. Run New-TestServiceApp after connecting with a credential." } $bytes = [System.IO.File]::ReadAllBytes($Path) $text = [System.Text.Encoding]::UTF8.GetString($bytes).TrimStart([char]0xFEFF) $record = $text | ConvertFrom-Json foreach ($required in 'baseUrl', 'username') { if (-not $record.PSObject.Properties[$required] -or [string]::IsNullOrWhiteSpace([string]$record.$required)) { throw "The credential record at $Path has no '$required'. Re-run New-TestServiceApp -Force." } } $protection = if ($record.PSObject.Properties['protection'] -and $record.protection) { [string]$record.protection } else { 'None' } $password = switch ($protection) { 'SecretStore' { Get-TestVaultSecret -VaultName $record.vaultName -SecretName $record.secretName -VaultPassword $VaultPassword } 'DPAPI' { Unprotect-TestSecret -Method DPAPI -Value $record.passwordProtected } default { Write-Warning "The password in $Path is stored unprotected. Re-run New-TestServiceApp -Force -UseSecretStore to encrypt it." [string]$record.passwordProtected } } if ([string]::IsNullOrWhiteSpace($password)) { throw "The credential record at $Path yielded no password. Re-run New-TestServiceApp -Force." } return [PSCustomObject]@{ BaseUrl = [string]$record.baseUrl Username = [string]$record.username Password = $password CaCertificate = $(if ($record.PSObject.Properties['caCertificate']) { [string]$record.caCertificate } else { $null }) Protection = $protection VaultName = $(if ($record.PSObject.Properties['vaultName']) { $record.vaultName } else { $null }) SecretName = $(if ($record.PSObject.Properties['secretName']) { $record.secretName } else { $null }) CreatedUtc = $(if ($record.PSObject.Properties['createdUtc']) { $record.createdUtc } else { $null }) Path = $Path } } |