184 lines
9.2 KiB
PowerShell
184 lines
9.2 KiB
PowerShell
function Import-PodFromSecretServer {
|
|
<#
|
|
.SYNOPSIS
|
|
Import Pod Certificates from Secret Server.
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $false)]
|
|
$PodName,
|
|
[Parameter(Mandatory = $false, ParameterSetName = "credentials")]
|
|
[string]$SecretServerUrl ="https://alkami.secretservercloud.com",
|
|
[Parameter(Mandatory = $false, ParameterSetName = "credentials")]
|
|
$SecretServerUserName,
|
|
[Parameter(Mandatory = $false, ParameterSetName = "credentials")]
|
|
$SecretServerPassword,
|
|
[Parameter(Mandatory = $false)]
|
|
[ValidateSet("Web", "App")]
|
|
$ServerType,
|
|
[Parameter(Mandatory = $false, HelpMessage = "ADGroups that need permission to these certificates")]
|
|
[string[]]$ADGroups,
|
|
[Parameter(Mandatory = $false)]
|
|
$TempDirectory = "c:\temp\importTempDir",
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$CertRoot = "Cert:\LocalMachine\",
|
|
[Parameter(Mandatory = $false)]
|
|
[switch]$UsePassword,
|
|
[Parameter(Mandatory = $false)]
|
|
[ValidateSet("Production", "Staging")]
|
|
[string]$EnvironmentType
|
|
)
|
|
begin {
|
|
Import-AWSModule # SSM
|
|
|
|
New-Item -Path $TempDirectory -ItemType Directory -Force -ErrorAction SilentlyContinue | Out-Null
|
|
|
|
switch ($EnvironmentType) {
|
|
"Production" {$RootFolderName = "Production-CertApi"}
|
|
"Staging" {$RootFolderName = "Staging-CertApi"}
|
|
}
|
|
|
|
# Get all parmeters which weren't supplied.
|
|
if(!$EnvironmentType)
|
|
{
|
|
$EnvironmentType = Get-AppSetting Environment.Type
|
|
}
|
|
|
|
if(!$PodName)
|
|
{
|
|
$PodName = Get-AppSetting Environment.Name
|
|
}
|
|
|
|
if(!$ServerType)
|
|
{
|
|
$ServerType = Get-AppSetting Environment.Server
|
|
}
|
|
|
|
if((!$SecretServerUserName -or !$SecretServerPassword))
|
|
{
|
|
if(Test-IsAws)
|
|
{
|
|
if(!$SecretServerUserName) {
|
|
$SecretServerUserName = (Get-SSMParameter -Name "secret_server_api_username" -WithDecryption $true).Value
|
|
}
|
|
|
|
if(!$SecretServerPassword) {
|
|
$SecretServerPassword = (Get-SSMParameter -Name "secret_server_api_password" -WithDecryption $true).Value
|
|
}
|
|
}
|
|
else {
|
|
Write-Error "Secret credentials must be manually provided if this is run on a non-AWS machine. They cannot be retrieved from SSM."
|
|
}
|
|
}
|
|
|
|
$secretServer = [SecretServerConnection]::new($SecretServerUrl, $SecretServerUserName, $SecretServerPassword)
|
|
$UseTwoFactor = $false
|
|
$secretServer.Authenticate($UseTwoFactor)
|
|
|
|
$NameOfCertificateField = "pfx-file"
|
|
$NameOfPasswordField = "Import Password"
|
|
Add-Type -Assembly System.IO.Compression.FileSystem
|
|
}
|
|
process {
|
|
$startTime = Get-Date
|
|
Write-Debug "Getting folder info"
|
|
$environmentFolderId = $secretServer.GetFolderIdByName($RootFolderName)
|
|
$podFolderId = $secretServer.GetFolderIdByName($PodName, $environmentFolderId)
|
|
$subFolderId = $secretServer.GetFolderIdByName($ServerType, $podFolderId) # Should be at an App/Mic/Web folder by this point. These folder names aren't unique, hence getting the environment folder id above.
|
|
|
|
$storeFolders = $secretServer.GetChildFolders($subFolderId)
|
|
|
|
$timeElapsed = New-TimeSpan -Start $startTime -End (Get-Date)
|
|
Write-Debug "Folder info retreived - $timeElapsed"
|
|
|
|
foreach ($storeFolder in $storeFolders) {
|
|
if ($storeFolder.FolderName -eq "CertificateAuthority") {$sanitizedStore = "CA"} else {$sanitizedStore = $storeFolder.FolderName} # Powershell's Paths don't match the X509 enum. So here we do a poor man's lookup. If we ever need more stores than just the CA, this needs to be expanded to something more robust and clean.
|
|
|
|
$TempStoreDirectory = Join-Path $TempDirectory $storeFolder.FolderName
|
|
|
|
$installedCerts = (Get-Cert -StoreName $sanitizedStore).thumbprint # Get certs in the current store.
|
|
|
|
Write-Debug "Getting Secrets and downloading certificate chain"
|
|
$secretInfoList = $secretServer.GetSecretByFolderId($storeFolder.id)
|
|
$secretInfoList | Where-Object {$installedCerts -notcontains $_.name.split("-")[-1]}
|
|
foreach ($secretInfo in $secretInfoList) {
|
|
$secret = $secretServer.GetSecretById($secretInfo.id)
|
|
|
|
# Don't import expired certs
|
|
$certExpirationDate = $secret.items | Where-Object {$_.fieldName -eq "ExperationDate"}
|
|
if ((Get-Date $certExpirationDate.itemValue) -gt (Get-Date)) {
|
|
if ($installedCerts) { #Don't die if there are no certs
|
|
$secretThumbprint = $secret.items | Where-Object {$_.fieldName -eq "Thumbprint"} | Select-Object -ExpandProperty itemValue
|
|
if ($installedCerts.Contains($secretThumbprint)) {
|
|
Write-Verbose "Certificate with thumbprint $secretThumbprint already installed"
|
|
continue
|
|
}
|
|
}
|
|
if ($UsePassword) {
|
|
$TempPassword = $secret.items | Where-Object {$_.fieldName -eq $NameOfPasswordField} | Select-Object -ExpandProperty itemValue
|
|
$Password = ConvertTo-SecureString $TempPassword -AsPlainText -Force
|
|
}
|
|
|
|
$folder = Join-Path $TempStoreDirectory $secret.Name
|
|
Remove-Item $folder -Force -ea SilentlyContinue -Recurse
|
|
New-Item $folder -ItemType Directory -Force -ea SilentlyContinue | Out-Null
|
|
|
|
$zipFolder = $folder, "$($secret.Name).zip" -join "\"
|
|
if ($secretServer.DownloadFile($secret.Id, $NameOfCertificateField, $zipFolder)) {
|
|
$timeElapsed = New-TimeSpan -Start $startTime -End (Get-Date)
|
|
Write-Debug "downloaded... - $timeElapsed"
|
|
|
|
[System.IO.Compression.ZipFile]::ExtractToDirectory($zipFolder, $folder)
|
|
Write-Debug "unzipping complete - $timeElapsed"
|
|
|
|
$certificateFiles = Get-ChildItem $folder -Include "*.cer", "*.pfx" -Recurse
|
|
$certList = [System.Collections.Arraylist]::new()
|
|
foreach ($file in $certificateFiles) {
|
|
$certStore = if ($file.Directory.Name -Match $file.BaseName) {$sanitizedStore}else {$file.Directory.Name}
|
|
|
|
[void]$certList.Add(([PSObject]@{
|
|
file = $file
|
|
certStore = Join-path $CertRoot $certStore
|
|
}))
|
|
}
|
|
|
|
foreach ($cert in $certList) {
|
|
if ($cert.file.extension -eq ".cer") {
|
|
try {
|
|
Import-Certificate -FilePath $cert.file.FullName -CertStoreLocation $cert.certStore | Out-null
|
|
}
|
|
catch {
|
|
Write-Warning "Failed to import Cert with filename $($cert.file.FullName)"
|
|
Write-Warning -Message "Error: $($_.Exception.ErrorRecord)"
|
|
Write-Warning -Message "Stack Trace: $($_.Exception.StackTrace)"
|
|
}
|
|
}
|
|
else {
|
|
try {
|
|
$installedCert = Import-PfxCertificate -FilePath $cert.file.FullName -CertStoreLocation $cert.certStore -Exportable -Password $Password
|
|
foreach ($ADGroup in $ADGroups.Split("{,}")) {
|
|
Write-Host "Setting Permissions"
|
|
Set-CertPermissions -certThumprint $installedCert.Thumbprint -user $ADGroup | Out-Null
|
|
}
|
|
}
|
|
catch [System.ComponentModel.Win32Exception] {
|
|
Write-Warning "Failed to import Cert with filename $($cert.file.FullName)"
|
|
Write-Warning -Message "Error: $($_.Exception.Message)"
|
|
Write-Warning -Message "Stack Trace: $($_.Exception.StackTrace)"
|
|
}
|
|
catch {
|
|
Write-Warning "Failed to import Cert with filename $($cert.file.FullName)"
|
|
Write-Warning -Message "Error: $($_.Exception.ErrorRecord)"
|
|
Write-Warning -Message "Stack Trace: $($_.Exception.StackTrace)"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
Write-Warning -Message "File could not be downloaded for certificate with thumbprint $($secretThumbprint)."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |