Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save infamousjoeg/4683452365e6c5449bfea8d706935727 to your computer and use it in GitHub Desktop.
Save infamousjoeg/4683452365e6c5449bfea8d706935727 to your computer and use it in GitHub Desktop.
Proxy-supported Vault-Conjur Synchronizer PowerShell Script
# Version = 13.6.0.4-release/13.6
#-----------------------------------------
# This script installs the Vault-Conjur Synchronizer
#------------------------------------------
#Requires -Version 4.0
param([switch] $silent, [switch] $forceNoPVWAApiUse, [switch] $trustPVWAAndConjurCert, [switch] $automationTests)
#region [Variables]
$script:ScriptDir = $null
$script:LogFilePath = $null
$script:LogFolderPath = $null
$script:doesPVWAAPIExist = $false
$script:ConjurDatabaseUsername = $null
$script:ConjurDatabasePassword = $null
$script:ConjurDatabasePort = $null
$script:ConjurDatabaseHost = $null
$script:Config=@{}
$script:InstallationTargetPathParameter="InstallationTargetPath"
$script:PVWAURLParameter="PVWAURL"
$script:ConjurServerDNSParameter="ConjurServerDNS"
$script:VaultNameParameter="VaultName"
$script:VaultAddressParameter="VaultAddress"
$script:VaultPortParameter="VaultPort"
$script:SyncSafeNameParameter="SyncSafeName"
$script:ConjurCredentialsFilePathParameter="ConjurCredentialsFilePath"
$script:ConjurAccountKeyParameter="ConjurAccount"
$script:ConjurAuthenApiKeyParameter="ConjurAuthnApi"
$script:ConjurAuthenUserKeyParameter="ConjurAuthnUser"
$script:ConjurTokenKeyParameter="ConjurTokenKey"
$script:LOBNameParameter="LOBName"
$script:LOBPlatformParameter="LOBPlatform"
$script:MultiNodeEnabledParameter="MultiNodeEnabled"
$script:ClusterKeyParameter="ClusterKey"
$script:ConjurCloudSelectedParameter="ConjurCloudSelected";
$script:ConjurCloudHostAndTokenParameter="ConjurCloudHostAndToken";
$script:HostPrefix = "host/"
#Constants
$SyncPrefix = 'Sync_'
$LobAccountPrefix = "LOBUser_"
$ConjurCloudDefaultLob = 'ConjurSync'
#endregion
#region [Functions]
function VerifyScriptsSignature {
param($ScriptDir)
$scriptPath = "$ScriptDir\V5SynchronizerInstallation.ps1"
$scriptsToVerify = @(
"$ScriptDir\Modules\PVWAapi.Gen1.URIS.psm1",
"$ScriptDir\Modules\PVWAapi.Gen2.URIS.psm1",
"$ScriptDir\Modules\PVWAapi.ps1",
"$ScriptDir\Modules\PVWAapi.RestService.psm1",
"$ScriptDir\Modules\PVWAapi.Utils.psm1",
"$ScriptDir\Modules\SynchronizerBase.ps1",
"$ScriptDir\Modules\Strategies\PVWAapi.gen2.psm1",
"$ScriptDir\Modules\Strategies\PVWAapi.mixed.psm1"
)
foreach ($scriptToVerify in $scriptsToVerify) {
VerifyScriptModuleCertificate $scriptPath $scriptToVerify
}
}
function VerifyScriptModuleCertificate{
param($scriptPath, $modulePath)
$signatureScript = Get-AuthenticodeSignature -FilePath $scriptPath
$signatureScriptModule = Get-AuthenticodeSignature -FilePath $modulePath
if($signatureScript.Status -eq "Valid"){
if($signatureScriptModule.Status -eq "Valid"){
$scriptSubject = ($signatureScript | select -ExpandProperty SignerCertificate).thumbprint
$scriptModuleSubject = ($signatureScriptModule | select -ExpandProperty SignerCertificate).thumbprint
if($scriptSubject -ne $scriptModuleSubject){
Write-Error "The $modulePath certificate is not trusted to work with this script. Make sure its source is trusted."
Exit 1
}
}
else{
Write-Error "The $modulePath certificate is not trusted. Make sure its source is trusted."
Exit 1
}
}
elseif($signatureScript.Status -ne "NotSigned"){
Write-Error 'Error: The script you are using is unsafe. Make sure its source is trusted.'
Exit 1
}
}
# Sets the value in the config
function SetValueInConfig($key, $value){
if($silent -and $Config.ContainsKey($key)){
return
}
$Config.Add($key, $value)
}
# Replace the value in the config
function ReplaceValueInConfig($key, $value){
$Config[$key] = $value
}
# Returns the value from the config
function GetValueFromConfig($key){
return $Config.Get_Item($key)
}
# ----------------- Get Conjur Database configuration from Conjur -----------------
function GetDatabaseConfigurationFromConjur() {
LogMsg -Msg $UserMessages.SynchronizerDatabasePolicy -newLine
$conjurAccountEncoded = [System.Web.HttpUtility]::UrlEncode($conjurAccount)
$variablePath = "$conjurAccountEncoded`:variable`:AutomationVault/db"
$conjurDatabaseConfiguration = GetConjurDatabaseConfiguration -variablePath $variablePath
MapConfigurationToVariables -databaseConfigurationFromConjur $conjurDatabaseConfiguration -variablePath $variablePath
}
function MapConfigurationToVariables($databaseConfigurationFromConjur, $variablePath) {
$variablesArray = $databaseConfigurationFromConjur -replace '@\{|}', '' -split '; '
foreach ($variable in $variablesArray) {
$name, $value = $variable -split '='
switch ($name)
{
"$variablePath/password" {$script:ConjurDatabasePassword = $value; Break}
"$variablePath/username" {$script:ConjurDatabaseUsername = $value; Break}
"$variablePath/url" {$script:ConjurDatabaseHost = $value -split ':' |Select-Object -First 1; $script:ConjurDatabasePort = $value -split ':' |Select-Object -Last 1; Break}
}
}
}
# Map configuration to variables:
# Get data from conjur
function GetConjurDatabaseConfiguration($variablePath) {
$baseUri = GetBaseUriForConjurApi -parameterName $ConjurServerDNSParameter
$conjurToken = (GetValueFromConfig -key $ConjurTokenKeyParameter)
$variables = "$variablePath/password,$variablePath/url,$variablePath/username"
$hostUri = "$baseUri/secrets?variable_ids=$variables"
try{
return Invoke-RestMethod @proxyConfig -Uri $hostUri -Headers @{"Authorization"="Token token=`"$conjurToken`""; "UserAgent"="Powershell"}
}
catch{
$statusCode = $_.Exception.Response.StatusCode.Value__
if($statusCode -eq 404){
throw $UserMessages.ConjurDatabaseConfigurationNotFound
}
else{
$CouldntRetretrieveDatabaseConfigurationFromConjur = [string]::Format($UserMessages.CouldNotRetrieveDatabaseConfigurationFromConjur, $statusCode)
throw $CouldntRetretrieveDatabaseConfigurationFromConjur
}
}
}
# ----------------- Create Conjur Host and Policy -----------------
# Creates a policy file with a host for the Synchronizer and vault policy loads it to Conjur
function CreateConjurHostAndPolicy($conjurHostId, $conjurHostCredFileOutputPath, $vaultName){
LogMsg -Msg $UserMessages.SynchronizerPolicy -newLine
# Check if host already exists in Conjur
$baseUri = GetBaseUriForConjurApi -parameterName $ConjurServerDNSParameter
$conjurToken = (GetValueFromConfig -key $ConjurTokenKeyParameter)
$conjurHostIdEncoded = [System.Web.HttpUtility]::UrlEncode($conjurHostId)
$conjurAccountEncoded = [System.Web.HttpUtility]::UrlEncode($conjurAccount)
$isHostExists = $false
$hostUri = "$baseUri/resources/$conjurAccountEncoded/$script:HostPrefix$conjurHostIdEncoded"
try{
$searchHostResponse = Invoke-RestMethod @proxyConfig -Uri $hostUri -Headers @{"Authorization"="Token token=`"$conjurToken`""; "UserAgent"="Powershell"}
$ConjurHostAlreadyExistsMessage = [string]::Format($UserMessages.ConjurHostAlreadyExists, $conjurHostId)
LogMsg -Type Debug -Msg $ConjurHostAlreadyExistsMessage
$isHostExists = $true
}
catch{
$statusCode = $_.Exception.Response.StatusCode.Value__
if($statusCode -ne 404){
$CouldntCreateHostFailedExistenceSearchMessage = [string]::Format($UserMessages.CouldntCreateHostFailedExistenceSearch, $conjurHostId, $searchHostResponse, $_.ErrorDetails)
throw $CouldntCreateHostFailedExistenceSearchMessage
}
}
# Create host and policy
$policyFileContent = createHostPolicyFileContent
$groupUri = "$baseUri/resources/$conjurAccountEncoded/group/synchronizer"
$doesSynchronizerGroupExist = ConjurGroupExists $groupUri $conjurToken
if($doesSynchronizerGroupExist){
$grantSyncGroupPolicyFileContent = CreateSynchronizerGroupPolicyFileContent
$policyFileContent = "$policyFileContent`n$grantSyncGroupPolicyFileContent"
}
$loadPolicyUri = "$baseUri/policies/$conjurAccountEncoded/policy/root"
try{
$createHostResponse = Invoke-RestMethod @proxyConfig -Method Post -Uri $loadPolicyUri -Headers @{"Authorization"="Token token=`"$conjurToken`""; "UserAgent"="Powershell"} -Body $policyFileContent
}
catch{
$statusCode = $_.Exception.Response.StatusCode.Value__
$CouldntCreateHostFailedToLoadPolicyMessage = [string]::Format($UserMessages.CouldntCreateHostFailedToLoadPolicy, $conjurHostId, $createHostResponse, $statusCode, $_.ErrorDetails)
throw $CouldntCreateHostFailedToLoadPolicyMessage
}
if(-not $isHostExists){
try{
$hostParamKey = "$conjurAccount`:host`:$conjurHostId"
$Script:objectApiKey = $createHostResponse.created_roles.$hostParamKey.api_key
if(-not $Script:objectApiKey){
throw
}
if($forceNoPVWAApiUse -or -not $doesPVWAAPIExist){
createConjurHostCredFile $conjurHostId $objectApiKey $conjurHostCredFileOutputPath
}
}
catch{
throw $UserMessages.FailedToParseResponseFromLoadPolicy
}
if($automationTests){
createConjurHostCredFile $conjurHostId $Script:objectApiKey $conjurHostCredFileOutputPath
}
}
elseif(-not $forceNoPVWAApiUse -and $doesPVWAAPIExist){
$rotateHostAPIKeyUri = "$baseUri/authn/$conjurAccountEncoded/api_key?role=host:$conjurHostIdEncoded"
try{
$Script:objectApiKey = Invoke-RestMethod @proxyConfig -Method PUT -Uri $rotateHostAPIKeyUri -Headers @{"Authorization"="Token token=`"$conjurToken`""; "UserAgent"="Powershell"}
}
catch{
$statusCode = $_.Exception.Response.StatusCode.Value__
$FailedToRotateAPIKeyMessage = [string]::Format($UserMessages.FailedToRotateAPIKey, $hostParamKey, $rotateHostAPIKeyUri, $_.ErrorDetails)
throw $FailedToRotateAPIKeyMessage
}
if($automationTests){
createConjurHostCredFile $conjurHostId $Script:objectApiKey $conjurHostCredFileOutputPath
}
}
}
# ----------------- Create Conjur Host and Policy -----------------
# Creates a policy file with a host for the Synchronizer and vault policy loads it to Conjur
# conjurHostFileOutputPath is the path to the file that will contain the host credentials
function RotateConjurCloudApiKey($conjurHostId, $conjurHostFileOutputPath){
LogMsg -Msg $UserMessages.ConjurCloudApiKeyRotation -newLine
$conjurToken = (GetValueFromConfig -key $ConjurTokenKeyParameter)
$hostWithoutHostPrefix = $conjurHostId -replace "^host/", ""
$conjurHostIdEncoded = [System.Web.HttpUtility]::UrlEncode($hostWithoutHostPrefix)
$conjurAccountEncoded = [System.Web.HttpUtility]::UrlEncode($conjurAccount)
$baseUri = GetBaseUriForConjurApi -parameterName $ConjurServerDNSParameter
$rotateHostAPIKeyUri = "$baseUri/authn/$conjurAccountEncoded/api_key?role=host:$conjurHostIdEncoded"
try{
$Script:objectApiKey = Invoke-RestMethod @proxyConfig -Method PUT -Uri $rotateHostAPIKeyUri -Headers @{"Authorization"="Token token=`"$conjurToken`""; "UserAgent"="Powershell"}
}
catch{
$statusCode = $_.Exception.Response.StatusCode.Value__
$FailedToRotateAPIKeyMessage = [string]::Format($UserMessages.FailedToRotateAPIKey, $conjurHostId, $rotateHostAPIKeyUri, $_.ErrorDetails)
throw $FailedToRotateAPIKeyMessage
}
if($automationTests){
createConjurHostCredFile -conjurHostId $conjurHostId -objectApiKey $Script:objectApiKey -conjurHostCredFileOutputPath $conjurHostFileOutputPath
}
}
function createHostPolicyFileContent()
{
if ((GetValueFromConfig -key $ConjurCloudSelectedParameter) -eq $true) {
# This should not happen because this method is not invoked for Conjur Cloud.
# It is here to prevent the method from being called in case of a bug.
LogMsg -Type Error -Msg $UserMessages.ConjurCloudNoHostCreation
exit 1
}
$synchronizerVersion = getSynchronizerVersion
return @"
- !group
id: $vaultName-admins
- !host
id: $conjurHostId
annotations:
authn/api-key: true
synchronzer-user: true
synchronizer-version: $synchronizerVersion
- !grant
role: !group $vaultName-admins
members:
- !host $conjurHostId
- !policy
id: $vaultName
owner: !group $vaultName-admins
"@
}
function CreateSynchronizerGroupPolicyFileContent() {
$policyFileContent = @"
- !grant
role: !group synchronizer
members:
- !host $conjurHostId
"@
return $policyFileContent
}
function getSynchronizerVersion() {
$version = (Get-Command "$ScriptDir\..\VaultConjurSynchronizer\VaultConjurSynchronizer.exe").FileVersionInfo
$versionString = [string]::Format("{0}.{1}.{2}", $version.FileMajorPart, $version.FileMinorPart, $version.FileBuildPart)
return $versionString
}
function createConjurHostCredFile($conjurHostId, $objectApiKey, $conjurHostCredFileOutputPath){
$psHostname = "$script:HostPrefix$conjurHostId"
$psApiKey = ConvertTo-SecureString -String $objectApiKey -AsPlainText -Force
$psCredentials = New-Object System.Management.Automation.PSCredential ($psHostname, $psApiKey)
CreatePSCredentials -PSCredentials $psCredentials -outputPath $conjurHostCredFileOutputPath
$ConjurHostCredentialsWrittenMessage = [string]::Format($UserMessages.ConjurHostCredentialsWritten, $conjurHostCredFileOutputPath)
LogMsg -Msg $ConjurHostCredentialsWrittenMessage
}
# ----------------- Init Conjur -----------------
# Initialize Conjur by sending authentication REST requests to the prompted hostname
function InitConjur(){
LogMsg -Msg $UserMessages.ConjurAuthentication -newLine
if($silent){
if($forceNoPVWAApiUse -or -not $doesPVWAAPIExist){
VerifyMandatoryParam -key $ConjurCredentialsFilePathParameter
$conjurCredentials = Import-Clixml -Path (GetValueFromConfig -key $ConjurCredentialsFilePathParameter)
}
#$conjurCredentials is an environment variable in new mode
if($null -eq $conjurCredentials){
Write-Error $UserMessages.ConjurLogonNoCredentials
exit 1
}
$conjurUser = $conjurCredentials.UserName
$conjurApiKey = ConvertSecurePasswordToPlainText -securePassword $conjurCredentials.Password
$ConjurServerDNS = (GetValueFromConfig -key $ConjurServerDNSParameter)
$conjurAccount = (GetValueFromConfig -key $ConjurAccountKeyParameter)
}
else{
$ConjurServerDNS = ReadHost $UserMessages.ConjurServerHostNameSpecify
$script:conjurAccount = ReadHost $UserMessages.ConjurAccountNameSpecify
$conjurUser = ReadHostWithDefaultValue -Message $UserMessages.ConjurUserNameSpecify -defaultValue $UserMessages.VaultDefaultAdminUser
$conjurUserPassword = GetPassword -userPromptMsg $UserMessages.ConjurAPIKeySpecify
$conjurApiKey = ConvertSecurePasswordToPlainText -securePassword $conjurUserPassword
SetValueInConfig -key $ConjurAccountKeyParameter -value $conjurAccount
}
ReplaceValueInConfig -key $ConjurServerDNSParameter -value "$ConjurServerDNS"
$script:ConjurServerDNS = (GetValueFromConfig -key $ConjurServerDNSParameter)
SetValueInConfig -key $ConjurAuthenUserKeyParameter -value $conjurUser
SetValueInConfig -key $ConjurAuthenApiKeyParameter -value $conjurApiKey
$encodedConjurAccount = [System.Web.HttpUtility]::UrlEncode($conjurAccount)
$InstallationTargetPath = (GetValueFromConfig -key $InstallationTargetPathParameter)
HandleCertificate -componentName 'Conjur' -serverUri "$script:ConjurServerDNS/info" -pemTargetDir $InstallationTargetPath -action 'Installation' -trustCert $trustPVWAAndConjurCert -CertificateAbortedMsg $UserMessages.SynchronizerInstallationCertificateAborted
LogMsg -Type Debug -Msg $UserMessages.ConjurLogin
$loginResponse = ConjurLogin -baseUri $script:ConjurServerDNS -conjurAccount $encodedConjurAccount
LogMsg -Type Debug -Msg $UserMessages.ConjurAuth
$authenticationResponse = ConjurAuthenticate -baseUri $script:ConjurServerDNS -conjurAccount $encodedConjurAccount -conjurApiKey $loginResponse
$conjurToken = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$authenticationResponse"))
SetValueInConfig -key $ConjurTokenKeyParameter -value $conjurToken
}
# ----------------- Conjur login REST -----------------
# Invoke REST login API to Conjur host
# Argument conjurAccount needs to be encoded
function ConjurLogin($baseUri, $conjurAccount){
$conjurUser = (GetValueFromConfig -key $ConjurAuthenUserKeyParameter)
$conjurSecret = (GetValueFromConfig -key $ConjurAuthenApiKeyParameter)
$basicCreds = Get-BasicAuthCreds -user $conjurUser -secret $conjurSecret
$conjurLoginUri = "$baseUri/authn/$conjurAccount/login"
try{
return Invoke-RestMethod @proxyConfig -Uri $conjurLoginUri -Headers @{"Authorization"="Basic $basicCreds"; "UserAgent"="Powershell"}
}
catch{
$CouldNotLoginToConjurMessage = [string]::Format($UserMessages.CouldNotLoginToConjur, $_.Exception)
throw $CouldNotLoginToConjurMessage
}
}
# ----------------- Conjur authenticate REST -----------------
# Invoke REST authenticate API to Conjur host
# Argument conjurAccount needs to be encoded
function ConjurAuthenticate($baseUri, $conjurAccount, $conjurApiKey){
$encodedconjurUser = [System.Web.HttpUtility]::UrlEncode((GetValueFromConfig -key $ConjurAuthenUserKeyParameter))
$conjurAuthenticateUri = "$baseUri/authn/$conjurAccount/$encodedconjurUser/authenticate"
try{
$authenticateResponse = Invoke-RestMethod @proxyConfig -Method Post -Uri $conjurAuthenticateUri -Body $conjurApiKey -UserAgent "Powershell"
}
catch{
$CouldNotAuthenticateToConjurMessage = [string]::Format($UserMessages.CouldNotAuthenticateToConjur, $_.ErrorDetails)
throw $CouldNotAuthenticateToConjurMessage
}
return ($authenticateResponse | ConvertTo-Json -Compress)
}
# ----------------- Conjur Cloud start authentication REST -----------------
# Invoke REST start authentication API request to Conjur Cloud
function ConjurCloudStartAuthentication($identityTenantBaseUrl, $identityUsername){
$startAuthenticationUrl = "$identityTenantBaseUrl/Security/StartAuthentication"
$startAuthenticationBody = ConvertTo-Json @{
Version = "1.0"
User = "$identityUsername"
}
try{
return Invoke-RestMethod @proxyConfig -Uri $startAuthenticationUrl -Headers @{"UserAgent"="Powershell"; "Accept"="*/*"} -Body $startAuthenticationBody -Method Post
}
catch{
$FailedToAuthenticateToConjurMessage = [string]::Format($UserMessages.FailedToAuthenticateToConjur, $_.Exception)
throw $CouldNotAuthenticateToConjurMessage
}
}
# ----------------- Conjur Cloud advance authentication REST -----------------
# Invoke REST advance authentication API request to Conjur Cloud
function ConjurCloudAdvanceAuthentication($identityTenantBaseUrl, $sessionId, $mechanismId, [Security.SecureString]$identityPassword){
$identityPasswordPlainText = ConvertSecurePasswordToPlainText -securePassword $identityPassword
$advanceAuthenticationUrl = "$identityTenantBaseUrl/Security/AdvanceAuthentication"
$advanceAuthenticationBody = ConvertTo-Json @{
Action = "Answer"
SessionId = "$sessionId"
MechanismId = "$mechanismId"
Answer = "$identityPasswordPlainText"
}
try{
return Invoke-RestMethod @proxyConfig -Uri $advanceAuthenticationUrl -Headers @{"UserAgent"="Powershell"; "Accept"="*/*"} -Body $advanceAuthenticationBody -Method Post
}
catch{
$FailedToAuthenticateToConjurMessage = [string]::Format($UserMessages.FailedToAuthenticateToConjur, $_.Exception)
throw $FailedToAuthenticateToConjurMessage
}
}
# ----------------- Conjur cloud start authentication REST -----------------
# Invoke REST start authentication API request to Conjur cloud
function ConjurCloudAuthenticateUser($conjurCloudBaseUrl, $identityToken){
$conjurCloudAuthUrl = "$conjurCloudBaseUrl/api/authn-oidc/cyberark/conjur/authenticate"
$conjurCloudAuthBody = @{
id_token = "$identityToken"
}
try{
return Invoke-RestMethod @proxyConfig -Uri $conjurCloudAuthUrl -Headers @{"UserAgent"="Powershell"; "Accept-Encoding"="base64"} -Body $conjurCloudAuthBody -Method Post
}
catch{
$CouldNotAuthenticateToConjurMessage = [string]::Format($UserMessages.CouldNotAuthenticateToConjur, $_.Exception)
throw $CouldNotAuthenticateToConjurMessage
}
}
# ----------------- Init Conjur Cloud -----------------
# Initialize Conjur by sending authentication REST requests to the prompted hostnamecoaxil
function InitConjurCloud(){
LogMsg -Msg $UserMessages.ConjurAuthentication -newLine
$script:conjurAccount = "conjur"
LogMsg -Msg $UserMessages.ConjurCloudDefaultAccountName -newLine
if($silent -eq $false){
$conjurCloudUrl = (ReadHost $UserMessages.ConjurCloudUrlSpecify).TrimEnd('/')
SetValueInConfig -key $ConjurServerDNSParameter -value $conjurCloudUrl
SetValueInConfig -key $ConjurAccountKeyParameter -value $conjurAccount
$script:ConjurServerDNS = $conjurCloudUrl;
}
}
# ----------------- Update Vault.ini -----------------
# notice address should contain no quotes to support DR
function UpdateVaultIni($filePath, $vaultName, $VaultAddress, $vaultPort){
$fileContent = (Get-Content -path $filePath)
$fileContent = $fileContent -replace "VAULT\s?=\s?`"?[\s\S]*`"?", "VAULT=`"$vaultName`""
$fileContent = $fileContent -replace "ADDRESS\s?=\s?`"?[\s\S]*`"?", "ADDRESS=$VaultAddress"
$fileContent = $fileContent -replace "PORT\s?=\s?`"?[\s\S]*`"?", "PORT=`"$vaultPort`""
$fileContent | Set-Content $filePath
}
# ----------------- Update Config file -----------------
function UpdateConfigFile($filePath, $Items){
$UpdatingFileMessage = [string]::Format($UserMessages.UpdatingFile, $filePath)
LogMsg -Type Debug -Msg $UpdatingFileMessage
$parsedValues = @{}
$Items = $Items -split ", "
$Items | foreach{
$item = $_.split("=")
$parsedValues.Add($item[0], $item[1])
}
$xml = [xml](Get-Content $filePath)
foreach ($elem in $xml.configuration.appSettings.ChildNodes){
if($elem.key){
if($parsedValues.ContainsKey($elem.key)){
$UpdatingFileValueOfToMessage = [string]::Format($UserMessages.UpdatingFileValueOfTo, $($elem.key), $($parsedValues[$elem.key]))
LogMsg -Type Debug -Msg $UpdatingFileValueOfToMessage
$elem.value = $parsedValues[$elem.key]
}
}
}
$xml.Save($filePath)
}
function UpdateTargetInstallationFolderPermissions(){
$InstallationTargetPath = (GetValueFromConfig -key $InstallationTargetPathParameter)
$SettingAccessPermissionToFolderMessage = [string]::Format($UserMessages.SettingAccessPermissionToFolder, $InstallationTargetPath)
LogMsg -Type Debug -Msg $SettingAccessPermissionToFolderMessage
### set Synchronizer Installation folder ACL ###
# retrieve ACL (Access Control List) of Installation target folder
$Acl = Get-Acl $InstallationTargetPath
# protect the access rules associated with this ObjectSecurity object from inheritance (=True) & Don't preserve inherited access rules (=False)
$Acl.SetAccessRuleProtection($True , $False)
# Grant �Full Control� permissions to Administrators
$administratorsSID = New-Object System.Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid, $null)
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule($administratorsSID, "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
$Acl.SetAccessRule($Ar)
# Grant "Read" permissions to Users
$usersSID = New-Object System.Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType]::BuiltinUsersSid, $null)
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule($usersSID, "Read", "None", "None", "Allow")
$Acl.SetAccessRule($Ar)
Set-Acl $InstallationTargetPath $Acl
}
################################################################################################
# Utils
################################################################################################
# ----------------- Get Basic authentication credentials -----------------
# Convert given user and secret to compile with basic authorization format
function Get-BasicAuthCreds($user, $secret){
$authString = "{0}:{1}" -f $user,$secret
$authBytes = [System.Text.Encoding]::Ascii.GetBytes($authString)
return [Convert]::ToBase64String($authBytes)
}
# ----------------- Unzip -----------------
# Unzip a specifed zip file to a specified location, if not exists in the output path
function Unzip($zipfile, $outpath){
$UnzippingFileMessage = [string]::Format($UserMessages.UnzippingFile, $zipfile, $outpath)
LogMsg -Msg $UnzippingFileMessage
if(-not (Test-Path $outpath)){
[System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath)
}
else{
$DirectoryExistsMessage = [string]::Format($UserMessages.DirectoryExists, $outpath)
LogMsg -Msg $DirectoryExistsMessage
}
}
# ----------------- Read config file -----------------
function VerifyMandatoryParam($key){
$value = GetValueFromConfig -key $key
if(DoesParameterEmpty($value)){
$MissingMandatoryParamMessage = [string]::Format($UserMessages.MissingMandatoryParam, $key)
throw $MissingMandatoryParamMessage
}
}
# ----------------- Read Silent Installation Config File -----------------
function ReadSilentInstallationConfigFile($path){
$SingleQuoteRegex = '^"(.*)"$'
$DoubleQuoteRegex = "^'(.*)'$"
$fileContent = Get-Content $path
foreach ($line in $fileContent){
$values = [regex]::split($line,'=')
$keyName = $values[0]
$keyValue = $values[1..($values.Length - 1)] -join "="
if(($keyName.CompareTo("") -ne 0) -and (-not $keyName.StartsWith("[")) -and (-not $keyName.StartsWith("#"))){
# Skip empty lines, comments and other non-usable stuff from the silent.ini
SetValueInConfig -key $keyName -value ($keyValue -replace $DoubleQuoteRegex,'$1' -replace $SingleQuoteRegex,'$1')
}
}
# Verify all mandatory params
VerifyMandatoryParam -key $InstallationTargetPathParameter
VerifyMandatoryParam -key $ConjurServerDNSParameter
VerifyMandatoryParam -key $VaultNameParameter
VerifyMandatoryParam -key $VaultAddressParameter
VerifyMandatoryParam -key $VaultPortParameter
VerifyMandatoryParam -key $SyncSafeNameParameter
if ($false -eq (GetValueFromConfig -key $ConjurCloudSelectedParameter)) {
VerifyMandatoryParam -key $ConjurAccountKeyParameter
}
}
function CreateCredFile($credFilePath, $createcredfilePath, $runningExePath, $SynchronizerVaultCredentials){
LogMsg -Msg $UserMessages.VaultCredentails -newLine
$createCredFileResponse = & "$createcredfilePath\CreateCredFile.exe" @("`"$credFilePath`"", "Password", "/Username",
$SynchronizerVaultCredentials.UserName, "/Password", $SynchronizerVaultCredentials.GetNetworkCredential().Password, "/ExePath", $runningExePath, "/AppType", "AppPrv",
"/DPAPIMachineProtection", "/Hostname", "/IPAddress", "/EntropyFile") 2>&1
#"/DPAPIMachineProtection", "/Hostname", "/IPAddress", "/DiskSignature", "/EntropyFile", "/InstallTime", "/MACAddress", "/MachineGUID") 2>&1
if($LASTEXITCODE -ne 0){
throw $createCredFileResponse
}
}
# ----------------- Create PS Credentials -----------------
function CreatePSCredentials([PSCredential] $PSCredentials, $outputPath){
$CreatingCredentialsFileMessage = [string]::Format($UserMessages.CreatingCredentialsFile, $PSCredentials.UserName)
LogMsg -Msg $CreatingCredentialsFileMessage -newLine
try{
$conjurCredentials = $PSCredentials
$conjurCredentials | Export-Clixml -Path $outputPath
}
finally{
if($conjurCredentials){
$conjurCredentials.Password.Dispose()
}
}
}
# ----------------- Copy logs to target installation folder -----------------
function CopyLogs(){
try{
LogMsg -Type Debug -Msg $UserMessages.LogCopy
$LogFolderPath = (GetValueFromConfig -key $InstallationTargetPathParameter) + "\Logs"
if(-not (Test-Path -Path $LogFolderPath)){
New-Item -ItemType directory -Path $LogFolderPath | Out-Null
}
# Copy installation log file to target installation folder
Copy-Item -Path $LogFilePath -Destination $LogFolderPath -Force -ErrorAction Stop
}
catch{
$errMsg = $_.Exception.Message
$FailedToCopyLogFileMessage = [string]::Format($UserMessages.FailedToCopyLogFile, $errMsg)
Write-Error $FailedToCopyLogFileMessage
Exit 1
}
}
# ----------------- Create event log ---------------------
function CreateEventLog(){
LogMsg -Msg $UserMessages.EventLog -newLine
$SourceExists = [System.Diagnostics.EventLog]::SourceExists("CyberArk Vault-Conjur Synchronizer")
if(!$SourceExists){
New-EventLog -LogName "CyberArk Vault-Conjur Synchronizer" -Source "CyberArk Vault-Conjur Synchronizer"
Limit-EventLog -LogName "CyberArk Vault-Conjur Synchronizer" -MaximumSize 50MB
}
else{
LogMsg -Type Debug -Msg $UserMessages.EventLogExist
}
}
# ----------------- Install Service ---------------------
function InstallService(){
LogMsg -Msg $UserMessages.SynchronizerInstalling -newLine
$serviceName = "CyberArkVaultConjurSynchronizer"
$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
if(!$service){
$exePath = '"' + [System.IO.Path]::Combine((GetValueFromConfig -key $InstallationTargetPathParameter), "VaultConjurSynchronizer.exe") + '"'
$params = @{
Name = $serviceName
BinaryPathName = $exePath
DisplayName = "CyberArk Vault-Conjur Synchronizer"
StartupType = "Automatic"
Description = "Synchronizes secrets, stored and managed in the CyberArk Vault, with Conjur."
}
New-Service @params
& sc.exe @("failure",$serviceName,"reset=86400","actions=restart/60000/restart/60000//")
if($LASTEXITCODE -ne 0){
throw $UserMessages.VaultConjurSynchronizerServiceInstallationFailed
}
}
else{
LogMsg -Msg $UserMessages.SynchronizerExist -newLine
}
}
function MainPVWAAPIFlow{
param($PVWAURL,[PSCredential] $VaultAdminCredentials, $SyncSafeName,[PSCredential] $SynchronizerVaultCredentials, $credFilePath, $createCredFilePath, $SynchronizerExePath, $ConjurCloudSelected)
$script:pvwaModulePath = "$ScriptDir\Modules\PVWAapi.ps1"
if(-not $forceNoPVWAApiUse){
$InstallationTargetPath = (GetValueFromConfig -key $InstallationTargetPathParameter)
HandleCertificate -componentName 'PVWA' -serverUri "$PVWAURL/passwordvault" -pemTargetDir $InstallationTargetPath -action 'Installation' -trustCert $trustPVWAAndConjurCert
Import-Module $pvwaModulePath -Force
$pvwaVersion = Init $LogFilePath $silent $PVWAURL $VaultAdminCredentials $SyncSafeName $ScriptDir
$script:doesPVWAAPIExist = DoesPVWAAPIExist $pvwaVersion
if(-not $silent -and -not $doesPVWAAPIExist){
$SynchronizerVaultUserName = ReadHostWithDefaultValue -Message $UserMessages.SynchronizerVaultUserNameSpecify -defaultValue "$SyncPrefix$env:computername"
$SynchronizerVaultUserPassword = GetPassword -userPromptMsg $UserMessages.SynchronizerVaultUserPasswordSpecify
$SynchronizerVaultCredentials = New-Object System.Management.Automation.PSCredential ($SynchronizerVaultUserName, $SynchronizerVaultUserPassword)
CreateCredFile -credfilePath $credFilePath -createcredfilePath $createCredFilePath -runningExePath $SynchronizerExePath -SynchronizerVaultCredentials $SynchronizerVaultCredentials
}
if($silent){
VerifyMandatoryParam -key $PVWAURLParameter
}
if($doesPVWAAPIExist){
if ($ConjurCloudSelected -eq $true) {
$numberOfAccountsInConjurSyncSafe = GetNumberOfLobAccountsInConjurSyncSafe $SyncSafeName
if ($numberOfAccountsInConjurSyncSafe -gt 1) {
LogMsg -Type Error -Msg $UserMessages.TooManyLobAccountsForConjurCloud -newLine
exit 1
}
}
AddUser $SynchronizerVaultCredentials $credFilePath $createCredFilePath $SynchronizerExePath
AddSynchronizerVaultUserToPVWAConfigSafe $SynchronizerVaultCredentials.UserName
CreateConjurSyncSafe
AddSynchronizerVaultUserToSyncSafe $SynchronizerVaultCredentials.UserName
AddVaultAdminsGroupToSyncSafe
HandleConjurHostPlatform $SynchronizerVaultCredentials.UserName
if((GetValueFromConfig -key $MultiNodeEnabledParameter) -eq $true){
HandleConjurDatabasePlatform
}
}
}
elseif(-not $silent){
$script:doesPVWAAPIExist = $false
$SynchronizerVaultUserName = ReadHostWithDefaultValue -Message $UserMessages.SynchronizerVaultUserNameSpecify -defaultValue "$SyncPrefix$env:computername"
$SynchronizerVaultUserPassword = GetPassword -userPromptMsg $UserMessages.SynchronizerVaultUserPasswordSpecify
$SynchronizerVaultCredentials = New-Object System.Management.Automation.PSCredential ($SynchronizerVaultUserName, $SynchronizerVaultUserPassword)
CreateCredFile -credfilePath $credFilePath -createcredfilePath $createCredFilePath -runningExePath $SynchronizerExePath -SynchronizerVaultCredentials $SynchronizerVaultCredentials
}
}
function DoesPVWAAPIExist {
param($versionNumber)
if($versionNumber -ge 11.4){
return $true
}
else{
return $false
}
}
function PVWACreateConjurAccount{
param($ConjurServerDNS, $ConjurAccount, $SynchronizerVaultUserName)
if(-not $forceNoPVWAApiUse){
Import-Module $pvwaModulePath -Force
if($doesPVWAAPIExist){
HandleConjurHostAccount $Script:objectApiKey $ConjurServerDNS $ConjurAccount $SynchronizerVaultUserName
}
}
}
function PVWACreateConjurDatabaseAccount{
if(-not $forceNoPVWAApiUse){
Import-Module $pvwaModulePath -Force
if($doesPVWAAPIExist){
HandleConjurDatabaseAccount -databaseUsername $Script:ConjurDatabaseUsername -databaseKey $script:ConjurDatabasePassword -databaseHost $script:ConjurDatabaseHost -databasePort $script:ConjurDatabasePort
}
}
}
function PVWACreateLOB{
param($VaultAddress, $ConjurCloudSelected, $ConjurSyncSafeName)
if(-not $forceNoPVWAApiUse){
Import-Module $pvwaModulePath -Force
if($doesPVWAAPIExist){
if ($ConjurCloudSelected -eq $true){
$lobAccountsCountInConjurSyncSafe = GetNumberOfLobAccountsInConjurSyncSafe $ConjurSyncSafeName
if ($lobAccountsCountInConjurSyncSafe -gt 0) {
LogMsg -Msg $UserMessages.LOBAccountExistsForConjurCloud -newLine
return
}
}
if($silent){
try {
VerifyMandatoryParam -key $LOBNameParameter
} catch {
LogMsg -Msg $UserMessages.LOBNameEmpty -newLine
return
}
$LobName = (GetValueFromConfig -key $LOBNameParameter)
$script:LOBPlatformName = (GetValueFromConfig -key $LOBPlatformParameter)
if ([string]::IsNullOrEmpty($script:LOBPlatformName)) {
$script:LOBPlatformName = $LOBDefaultPlatform
$UsingDefaultLobPlatformMessage = [string]::Format($UserMessages.DefaultLOBPlatform, $script:LOBPlatformName)
LogMsg -Msg $UsingDefaultLobPlatformMessage -newLine
}
}
else{
$createLob = ReadHost -Message $UserMessages.DefineLOBSpecify
if ('yes' -ne $createLob) {
return
}
$LOBName = ''
if ($ConjurCloudSelected -eq $true){
#We can read only one LOB and doesn't have to verify if it already exist, since we already did that.
$LOBName = ReadHostWithDefaultValue -Message $UserMessages.LOBNameSpecify -defaultValue $ConjurCloudDefaultLob
} else {
$LOBName = ReadLobNameFromConsole -defaultValue $defaultLob
}
$script:LOBPlatformName = ReadHostWithDefaultValue -Message $UserMessages.LOBPlatformSpecify -defaultValue $LOBDefaultPlatform
}
AddLOB $VaultAddress $LOBPlatformName $LobName
}
}
}
function GetNumberOfLobAccountsInConjurSyncSafe {
param($ConjurSyncSafeName)
$FilterOnConjurSyncSafe = "filter=safeName eq $ConjurSyncSafeName"
$content = $(Invoke-AccountGetAllBySafeFailoverRequest $FilterOnConjurSyncSafe)
$jsonContent = ConvertFrom-Json -InputObject $content
$lobAccountsInSafe = $jsonContent.value | Where-Object { $_.name -like $LobAccountPrefix + "*" }
$accountsCount = 0
$lobAccountsInSafe | ForEach-Object {$accountsCount++};
return $accountsCount
}
function PVWACreateLOBs{
param($PVWAURL, $VaultAddress,[PSCredential] $VaultAdminCredentials, $SyncSafeName, $LOBPlatformName, $LobNames)
if(-not $forceNoPVWAApiUse){
if($doesPVWAAPIExist -and -not $silent){
$answer = ReadHost -Message $UserMessages.DefineLOBsSpecify -defaultValue "no"
if('yes' -eq $answer){
$generateLOBsPath = "$ScriptDir\GenerateLOBs.ps1"
VerifyScriptModuleCertificate $scriptPath $generateLOBsPath
Import-Module $generateLOBsPath -ArgumentList $PVWAURL,$VaultAddress,$VaultAdminCredentials.UserName,$VaultAdminCredentials.GetNetworkCredential().Password,$SyncSafeName,$LOBPlatformName,$LobNames,$true,$trustPVWAAndConjurCert -Force
}
}
}
}
function PVWALogouot{
if(-not $forceNoPVWAApiUse){
Import-Module $pvwaModulePath -Force
Logout
}
}
function DeleteConjurHostInVault {
param($newHostName)
if(-not $forceNoPVWAApiUse){
Import-Module $pvwaModulePath -Force
if($doesPVWAAPIExist){
RemoveConjurHostAccount $newHostName
}
}
}
function ConjurGroupExists {
param($groupUri, $conjurToken)
try{
Invoke-RestMethod @proxyConfig -Uri $groupUri -Headers @{"Authorization"="Token token=`"$conjurToken`""; "UserAgent"="Powershell"}
return $true;
}
catch{
return $false
}
}
function GetBaseUriForConjurApi {
param($parameterName)
$baseUri = (GetValueFromConfig -key $parameterName)
if ($true -eq (GetValueFromConfig -key $ConjurCloudSelectedParameter)){
$baseUri = "$baseUri/api"
}
return $baseUri
}
function MultiNodeSetupConfiguration {
# Multi-Node
if(-not $silent){
$multinodeEnabled = ReadHost -Message $UserMessages.DefineSynchronizerModeSpecify
if ('yes' -eq $multinodeEnabled)
{
SetValueInConfig -key $MultiNodeEnabledParameter -value true
DO {
$clusterKey = ReadHost -Message $UserMessages.ClusterKeySpecify
} while (-not $clusterKey)
} else {
SetValueInConfig -key $MultiNodeEnabledParameter -value false
$clusterKey = ReadHostWithDefaultValue -Message $UserMessages.InstanceNameSpecify -defaultValue "${env:computername}"
}
SetValueInConfig -key $ClusterKeyParameter -value $clusterKey
}
else {
VerifyMandatoryParam -key $MultiNodeEnabledParameter
$multiNodeEnabled = GetValueFromConfig -key $MultiNodeEnabledParameter
if ($multiNodeEnabled -eq $true) {
VerifyMandatoryParam -key $ClusterKeyParameter
} else {
$clusterKey = GetValueFromConfig -key $ClusterKeyParameter
if ([string]::IsNullOrEmpty($clusterKey)) {
$computerName = "${env:computername}"
ReplaceValueInConfig -key $ClusterKeyParameter -value "${computerName}"
}
}
}
}
#endregion
################################################################################################
# Main script
################################################################################################
#region [Main]
try{
foreach ($spType in [System.Enum]::GetValues([System.Net.SecurityProtocolType])){
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor $spType
}
# Get location of script
$ScriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
# Initialize log location
$LogFilePath = "$ScriptDir\Installation.log"
VerifyScriptsSignature -ScriptDir $ScriptDir
$script:scriptPath = "$ScriptDir\V5SynchronizerInstallation.ps1"
$SynchronizerBaseModulePath = "$ScriptDir\Modules\SynchronizerBase.ps1"
Import-Module $SynchronizerBaseModulePath -Force
$userMessagesFilePath = "$ScriptDir\UserMessages.psd1"
$UserMessages = Import-PowerShellDataFile -Path $userMessagesFilePath
WriteWelcome
LogMsg -Msg $UserMessages.StartingInstallation -newLine
# Enable unzipping and encoding
Add-Type -AssemblyName System.IO.Compression.FileSystem
Add-Type -AssemblyName System.Web
# Ask user if they use a proxy
$useProxy = Read-Host "Do you need to use a proxy? (yes/no)"
if ($useProxy -match '^(y|yes)$') {
# Ask for proxy address
$proxyURL = Read-Host "Enter the proxy URL (e.g., http://proxy.company.com:8080)"
# Ask if proxy requires authentication
$needsAuth = Read-Host "Does the proxy require authentication? (yes/no)"
if ($needsAuth -match '^(y|yes)$') {
$proxyCred = Get-Credential -Message "Enter proxy credentials"
$proxyConfig = @{
Proxy = $proxyURL
ProxyCredential = $proxyCred
}
} else {
$proxyConfig = @{
Proxy = $proxyURL
}
}
} else {
$proxyConfig = @{}
}
if($silent){
LogMsg -Msg $UserMessages.SynchronizerSilentInstallation
ReadSilentInstallationConfigFile "$ScriptDir\silent.ini"
}
# Conjur Cloud
$conjurCloudSelected = ReadHost -Message $UserMessages.ConjurCloudSelected
if('cloud' -eq $conjurCloudSelected){
SetValueInConfig -key $ConjurCloudSelectedParameter -value true
# Multi-Node -> false, not supported in Conjur Cloud
SetValueInConfig -key $ClusterKeyParameter -value ""
SetValueInConfig -key $MultiNodeEnabledParameter -value false
}
else{
SetValueInConfig -key $ConjurCloudSelectedParameter -value false
MultiNodeSetupConfiguration
}
SetValueInConfig -key $InstallationTargetPathParameter -value (ReadHostWithDefaultValue -Message $UserMessages.InstallationPathSpecify -defaultValue "${env:ProgramFiles}\CyberArk\Synchronizer")
$InstallationTargetPath = (GetValueFromConfig -key $InstallationTargetPathParameter)
if(-not (Test-Path -Path $InstallationTargetPath)){
Copy-Item -Path "$ScriptDir\..\VaultConjurSynchronizer" -Destination $InstallationTargetPath -Recurse -Force -ErrorAction Stop
}
else{
$DirectoryExistsMessage = [string]::Format($UserMessages.DirectoryExists, $InstallationTargetPath)
LogMsg -Type Debug -Msg $DirectoryExistsMessage
}
# Update VaultConjurSynchronizer.exe.config
$multinodeEnabled=GetValueFromConfig($MultiNodeEnabledParameter)
$clusterKey=GetValueFromConfig($ClusterKeyParameter)
$itemsToUpdate = "SYNCHRONIZER_MULTI_NODE_ENABLED=$multinodeEnabled", "SYNCHRONIZER_CLUSTER_KEY=$clusterKey"
UpdateConfigFile -filePath ((GetValueFromConfig($InstallationTargetPathParameter)) + "\VaultConjurSynchronizer.exe.config") -Items $itemsToUpdate
SetValueInConfig -key $VaultNameParameter -value (ReadHost $UserMessages.VaultNameSpecify)
$VaultName = (GetValueFromConfig -key $VaultNameParameter)
SetValueInConfig -key $PVWAURLParameter -value (ReadHost $UserMessages.PVWAURLSpecify)
$PVWAURL = (GetValueFromConfig -key $PVWAURLParameter)
SetValueInConfig -key $VaultAddressParameter -value (ReadHost $UserMessages.VaultAddressSpecify)
SetValueInConfig -key $VaultPortParameter -value (ReadHostWithDefaultValue -Message $UserMessages.VaultPortSpecify -defaultValue $UserMessages.VaultDefaultPort)
# Edit Vault.ini
$vaultFilePath = "$InstallationTargetPath\Vault\Vault.ini"
$UpdatingFileMessage = [string]::Format($UserMessages.UpdatingFile, $vaultFilePath)
LogMsg -Type Debug -Msg $UpdatingFileMessage
$VaultAddress = GetValueFromConfig -key $VaultAddressParameter
UpdateVaultIni -filePath $vaultFilePath -vaultName $VaultName -VaultAddress $VaultAddress -vaultPort (GetValueFromConfig -key $VaultPortParameter)
$SynchronizerVaultUsername = "$SyncPrefix$env:computername"
$SynchronizerVaultUserPassword = GetRandomPassword
$SynchronizerVaultCredentials = New-Object System.Management.Automation.PSCredential -ArgumentList $SynchronizerVaultUsername,$SynchronizerVaultUserPassword
$credFilePath = "$InstallationTargetPath\Vault\VaultConjurSynchronizerUser.cred"
$createCredFilePath = "$ScriptDir\CreateCredFile"
$SynchronizerExePath = (GetValueFromConfig -key $InstallationTargetPathParameter) + "\VaultConjurSynchronizer.exe"
if($silent){
$script:ConjurServerDNS = (GetValueFromConfig -key $ConjurServerDNSParameter)
$script:conjurAccount = (GetValueFromConfig -key $ConjurAccountKeyParameter)
}
else{
$vaultAdminUserName = ReadHost -Message $UserMessages.LogonUserNameSpecify
$vaultAdminPassword = GetPassword -userPromptMsg $UserMessages.LogonPasswordSpecify
$VaultAdminCredentials = New-Object System.Management.Automation.PSCredential ($vaultAdminUserName, $vaultAdminPassword)
}
$conjurCloudSelectedParameterValue = GetValueFromConfig -key $ConjurCloudSelectedParameter
if ($conjurCloudSelectedParameterValue -eq $true) {
# Conjur Cloud host input is already supposed to have host prefix
$script:HostPrefix = ""
}
SetValueInConfig -key $SyncSafeNameParameter -value (ReadHost $UserMessages.AdminSafeSpecify)
$SyncSafeName = (GetValueFromConfig -key $SyncSafeNameParameter)
MainPVWAAPIFlow -PVWAURL $PVWAURL -VaultAdminCredentials $VaultAdminCredentials -SyncSafeName $SyncSafeName -SynchronizerVaultCredentials $SynchronizerVaultCredentials -credFilePath $credFilePath -createCredFilePath $createCredFilePath -SynchronizerExePath $SynchronizerExePath -ConjurCloudSelected $conjurCloudSelectedParameterValue
UpdateTargetInstallationFolderPermissions
if($conjurCloudSelectedParameterValue -eq $true)
{
InitConjurCloud
}
else {
InitConjur
}
# Edit VaultConjurSynchronizer.exe.config (If CONJUR_CLOUD_SELECTED is true, SYNC_ALL_PROPERTIES and CONJUR_API_KEY_ROTATION_ENABLED have to be true, otherwise they can stay false)
$itemsToUpdate = "INTEGRATION_VAULT_NAME=$VaultName", "SYNC_SAFE_NAME=$SyncSafeName", "SYNC_ALL_PROPERTIES=$conjurCloudSelectedParameterValue", "CONJUR_CLOUD_SELECTED=$conjurCloudSelectedParameterValue", "CONJUR_API_KEY_ROTATION_ENABLED=$conjurCloudSelectedParameterValue"
UpdateConfigFile -filePath ((GetValueFromConfig($InstallationTargetPathParameter)) + "\VaultConjurSynchronizer.exe.config") -Items $itemsToUpdate
$clusterName = (GetValueFromConfig -key $ClusterKeyParameter)
if($conjurCloudSelectedParameterValue -eq $true)
{
if($silent){
$ConjurCloudHostnameAndTokenEncodedBase64 = GetValueFromConfig -key $ConjurCloudHostAndTokenParameter
} else {
$ConjurCloudHostnameAndTokenAsSecuret = ReadHost -Message $UserMessages.ConjurCloudHostnameAndToken -AsSecureString
$ConjurCloudHostnameAndTokenEncodedBase64 = ConvertSecurePasswordToPlainText -securePassword $ConjurCloudHostnameAndTokenAsSecuret
}
$ConjurCloudHostnameAndToken = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($ConjurCloudHostnameAndTokenEncodedBase64))
$ConjurCloudHostnameAndTokenSplit = $ConjurCloudHostnameAndToken.Split(":")
$ConjurCloudHostname = $ConjurCloudHostnameAndTokenSplit[0]
$ConjurHostName = $ConjurCloudHostname
$ConjurCloudToken = $ConjurCloudHostnameAndTokenSplit[1]
ReplaceValueInConfig -key $ConjurTokenKeyParameter -value $ConjurCloudToken
# Remove old conjur host account from vault
DeleteConjurHostInVault $ConjurCloudHostname
# In Conjur Cloud Host is built-in so we don't have to do anything with it besides rotating the API key
RotateConjurCloudApiKey -conjurHostId $ConjurCloudHostname -conjurHostFileOutputPath "$ScriptDir\synchronizerConjurHost.xml"
}
else
{
$ConjurHostName = "$SyncPrefix$clusterName"
# Remove old conjur host account from vault
DeleteConjurHostInVault $ConjurHostName
# Create the Synchronizer Conjur host and policy
CreateConjurHostAndPolicy -conjurHostId $ConjurHostName -conjurHostCredFileOutputPath "$ScriptDir\synchronizerConjurHost.xml" -vaultName $VaultName
}
PVWACreateConjurAccount -ConjurServerDNS $script:ConjurServerDNS -ConjurAccount $script:conjurAccount -SynchronizerVaultUserName "$script:HostPrefix$ConjurHostName"
# Create Conjur Database configuration in vault
if((GetValueFromConfig -key $MultiNodeEnabledParameter) -eq $true){
if($conjurCloudSelectedParameterValue -eq $true)
{
# This should never happen because multi node is set to false if conjur cloud is selected
LogMsg -Type Error -Msg $UserMessages.ConjurCloudMultiNodeNotSupported -newLine
exit 1
}
else {
GetDatabaseConfigurationFromConjur
PVWACreateConjurDatabaseAccount
}
}
CreateEventLog
InstallService
PVWACreateLOB -VaultAddress $VaultAddress -ConjurCloudSelected $conjurCloudSelectedParameterValue -ConjurSyncSafeName $SyncSafeName
LogMsg -Msg $UserMessages.SynchronizerInstallationSucceeded -newLine
}
catch{
$errMsg = $_.Exception.Message
# Redirect the Exception to log file
$FailedToInstallMessage = [string]::Format($UserMessages.FailedToInstall, $errMsg)
LogMsg -Type Error -Msg $FailedToInstallMessage
Exit 1
}
finally{
try{
PVWALogouot
CopyLogs
}
catch{ }
}
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment