From 05cfc83902731c5fac242036eff51acacf2c7ce1 Mon Sep 17 00:00:00 2001 From: kfadmin Date: Wed, 10 May 2023 20:14:27 +0000 Subject: [PATCH 1/5] changes --- RemoteFile/RemoteCertificateStore.cs | 7 +- RemoteFile/RemoteHandlers/LocalWinHandler.cs | 258 +++++++++++++++++++ 2 files changed, 264 insertions(+), 1 deletion(-) create mode 100644 RemoteFile/RemoteHandlers/LocalWinHandler.cs diff --git a/RemoteFile/RemoteCertificateStore.cs b/RemoteFile/RemoteCertificateStore.cs index 8be5b53d..d8e6cca9 100644 --- a/RemoteFile/RemoteCertificateStore.cs +++ b/RemoteFile/RemoteCertificateStore.cs @@ -334,7 +334,12 @@ internal void Initialize() if (ServerType == ServerTypeEnum.Linux) RemoteHandler = new SSHHandler(Server, ServerId, ServerPassword); else - RemoteHandler = new WinRMHandler(Server, ServerId, ServerPassword); + { + if (Server.ToLower() == "localhost") + RemoteHandler = new LocalWinHandler(Server, ServerId, ServerPassword); + else + RemoteHandler = new WinRMHandler(Server, ServerId, ServerPassword); + } RemoteHandler.Initialize(); diff --git a/RemoteFile/RemoteHandlers/LocalWinHandler.cs b/RemoteFile/RemoteHandlers/LocalWinHandler.cs new file mode 100644 index 00000000..1c907ece --- /dev/null +++ b/RemoteFile/RemoteHandlers/LocalWinHandler.cs @@ -0,0 +1,258 @@ +// Copyright 2021 Keyfactor +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions +// and limitations under the License. + +using System; +using System.Collections.Generic; +using System.Management.Automation; +using System.Management.Automation.Runspaces; +using System.Net; +using System.Text; + +using Microsoft.Extensions.Logging; + +using Keyfactor.Logging; + +namespace Keyfactor.Extensions.Orchestrator.RemoteFile.RemoteHandlers +{ + class LocalWinHandler : BaseRemoteHandler + { + private const string IGNORED_ERROR1 = "setupcmdline.bat"; + private const string IGNORED_ERROR2 = "operable program or batch file"; + + private Runspace runspace { get; set; } + private WSManConnectionInfo connectionInfo { get; set; } + + internal WinRMHandler(string server, string serverLogin, string serverPassword) + { + _logger.MethodEntry(LogLevel.Debug); + + Server = server; + connectionInfo = new WSManConnectionInfo(new System.Uri($"{Server}/wsman")); + if (!string.IsNullOrEmpty(serverLogin)) + { + connectionInfo.Credential = new PSCredential(serverLogin, new NetworkCredential(serverLogin, serverPassword).SecurePassword); + } + + _logger.MethodExit(LogLevel.Debug); + } + + public override void Initialize() + { + _logger.MethodEntry(LogLevel.Debug); + + try + { + if (ApplicationSettings.UseNegotiate) + { + connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Negotiate; + } + runspace = RunspaceFactory.CreateRunspace(connectionInfo); + runspace.Open(); + } + + catch (Exception ex) + { + _logger.LogError($"Exception during Initialize...{RemoteFileException.FlattenExceptionMessages(ex, ex.Message)}"); + throw ex; + } + + _logger.MethodExit(LogLevel.Debug); + } + + public override void Terminate() + { + _logger.MethodEntry(LogLevel.Debug); + + runspace.Close(); + runspace.Dispose(); + + _logger.MethodExit(LogLevel.Debug); + } + + public override string RunCommand(string commandText, object[] parameters, bool withSudo, string[] passwordsToMaskInLog) + { + _logger.MethodEntry(LogLevel.Debug); + _logger.LogDebug($"RunCommand: {commandText}"); + + try + { + using (PowerShell ps = PowerShell.Create()) + { + ps.Runspace = runspace; + + if (commandText.ToLower().IndexOf("keytool ") > -1) + { + commandText = ($"& '{commandText}").Replace("keytool", "keytool'"); + commandText = "echo '' | " + commandText; + } + ps.AddScript(commandText); + + string displayCommand = commandText; + if (passwordsToMaskInLog != null) + { + foreach (string password in passwordsToMaskInLog) + displayCommand = displayCommand.Replace(password, PASSWORD_MASK_VALUE); + } + + if (parameters != null) + { + foreach(object parameter in parameters) + ps.AddArgument(parameter); + } + + _logger.LogDebug($"RunCommand: {displayCommand}"); + string result = FormatResult(ps.Invoke(parameters)); + + if (ps.HadErrors) + { + string errors = string.Empty; + System.Collections.ObjectModel.Collection errorRecords = ps.Streams.Error.ReadAll(); + foreach (ErrorRecord errorRecord in errorRecords) + { + string error = errorRecord.ToString(); + if (error.ToLower().Contains(IGNORED_ERROR1) + || error.ToLower().Contains(IGNORED_ERROR2)) + { + errors = null; + break; + } + + errors += (error + " "); + } + + if (!string.IsNullOrEmpty(errors)) + throw new ApplicationException(errors); + } + else + _logger.LogDebug($"WinRM Results: {displayCommand}::: {result}"); + + _logger.MethodExit(LogLevel.Debug); + + return result; + } + } + catch (Exception ex) + { + _logger.LogError($"Exception during RunCommand...{RemoteFileException.FlattenExceptionMessages(ex, ex.Message)}"); + throw ex; + } + } + + private byte[] RunCommandBinary(string commandText) + { + _logger.MethodEntry(LogLevel.Debug); + _logger.LogDebug($"RunCommandBinary: {commandText}"); + + byte[] rtnBytes = new byte[0]; + + try + { + using (PowerShell ps = PowerShell.Create()) + { + ps.Runspace = runspace; + ps.AddScript(commandText); + + System.Collections.ObjectModel.Collection psResult = ps.Invoke(); + + if (ps.HadErrors) + { + string errors = string.Empty; + System.Collections.ObjectModel.Collection errorRecords = ps.Streams.Error.ReadAll(); + foreach (ErrorRecord errorRecord in errorRecords) + errors += (errorRecord.ToString() + " "); + + throw new ApplicationException(errors); + } + else + { + if (psResult.Count > 0) + rtnBytes = (byte[])psResult[0].BaseObject; + _logger.LogDebug($"WinRM Results: {commandText}::: binary results."); + } + } + + _logger.MethodExit(LogLevel.Debug); + + return rtnBytes; + } + + catch (Exception ex) + { + _logger.LogError("Exception during RunCommandBinary...{RemoteFileException.FlattenExceptionMessages(ex, ex.Message)}"); + throw ex; + } + } + + public override void UploadCertificateFile(string path, string fileName, byte[] certBytes) + { + _logger.MethodEntry(LogLevel.Debug); + _logger.LogDebug($"UploadCertificateFile: {path} {fileName}"); + + string scriptBlock = $@" + param($contents) + + Set-Content {path + fileName} -Encoding Byte -Value $contents + "; + + object[] arguments = new object[] { certBytes }; + + RunCommand(scriptBlock, arguments, false, null); + + _logger.MethodEntry(LogLevel.Debug); + } + + public override byte[] DownloadCertificateFile(string path) + { + _logger.MethodEntry(LogLevel.Debug); + _logger.LogDebug($"DownloadCertificateFile: {path}"); + _logger.MethodExit(LogLevel.Debug); + + return RunCommandBinary($@"Get-Content -Path ""{path}"" -Encoding Byte -Raw"); + } + + public override void CreateEmptyStoreFile(string path, string linuxFilePermissions, string linuxFileOwner) + { + _logger.MethodEntry(LogLevel.Debug); + RunCommand($@"Out-File -FilePath ""{path}""", null, false, null); + _logger.MethodExit(LogLevel.Debug); + } + + public override bool DoesFileExist(string path) + { + _logger.MethodEntry(LogLevel.Debug); + _logger.LogDebug($"DoesFileExist: {path}"); + _logger.MethodExit(LogLevel.Debug); + + return Convert.ToBoolean(RunCommand($@"Test-Path -path ""{path}""", null, false, null)); + } + + public override void RemoveCertificateFile(string path, string fileName) + { + _logger.LogDebug($"RemoveCertificateFile: {path} {fileName}"); + + RunCommand($"rm {path}{fileName}", null, false, null); + } + + + private string FormatResult(ICollection results) + { + _logger.MethodEntry(LogLevel.Debug); + + StringBuilder rtn = new StringBuilder(); + + foreach (PSObject resultLine in results) + { + if (resultLine != null) + rtn.Append(resultLine.ToString() + System.Environment.NewLine); + } + + _logger.MethodExit(LogLevel.Debug); + + return rtn.ToString(); + } + } +} From 6da498d9e2560cc7f773a502c8c7fc8cdac8923e Mon Sep 17 00:00:00 2001 From: kfadmin Date: Wed, 17 May 2023 17:33:32 +0000 Subject: [PATCH 2/5] changes --- RemoteFile/RemoteCertificateStore.cs | 7 +- RemoteFile/RemoteHandlers/LocalWinHandler.cs | 258 ------------------- RemoteFile/RemoteHandlers/WinRMHandler.cs | 41 +-- 3 files changed, 26 insertions(+), 280 deletions(-) delete mode 100644 RemoteFile/RemoteHandlers/LocalWinHandler.cs diff --git a/RemoteFile/RemoteCertificateStore.cs b/RemoteFile/RemoteCertificateStore.cs index d8e6cca9..8be5b53d 100644 --- a/RemoteFile/RemoteCertificateStore.cs +++ b/RemoteFile/RemoteCertificateStore.cs @@ -334,12 +334,7 @@ internal void Initialize() if (ServerType == ServerTypeEnum.Linux) RemoteHandler = new SSHHandler(Server, ServerId, ServerPassword); else - { - if (Server.ToLower() == "localhost") - RemoteHandler = new LocalWinHandler(Server, ServerId, ServerPassword); - else - RemoteHandler = new WinRMHandler(Server, ServerId, ServerPassword); - } + RemoteHandler = new WinRMHandler(Server, ServerId, ServerPassword); RemoteHandler.Initialize(); diff --git a/RemoteFile/RemoteHandlers/LocalWinHandler.cs b/RemoteFile/RemoteHandlers/LocalWinHandler.cs deleted file mode 100644 index 1c907ece..00000000 --- a/RemoteFile/RemoteHandlers/LocalWinHandler.cs +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright 2021 Keyfactor -// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. -// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions -// and limitations under the License. - -using System; -using System.Collections.Generic; -using System.Management.Automation; -using System.Management.Automation.Runspaces; -using System.Net; -using System.Text; - -using Microsoft.Extensions.Logging; - -using Keyfactor.Logging; - -namespace Keyfactor.Extensions.Orchestrator.RemoteFile.RemoteHandlers -{ - class LocalWinHandler : BaseRemoteHandler - { - private const string IGNORED_ERROR1 = "setupcmdline.bat"; - private const string IGNORED_ERROR2 = "operable program or batch file"; - - private Runspace runspace { get; set; } - private WSManConnectionInfo connectionInfo { get; set; } - - internal WinRMHandler(string server, string serverLogin, string serverPassword) - { - _logger.MethodEntry(LogLevel.Debug); - - Server = server; - connectionInfo = new WSManConnectionInfo(new System.Uri($"{Server}/wsman")); - if (!string.IsNullOrEmpty(serverLogin)) - { - connectionInfo.Credential = new PSCredential(serverLogin, new NetworkCredential(serverLogin, serverPassword).SecurePassword); - } - - _logger.MethodExit(LogLevel.Debug); - } - - public override void Initialize() - { - _logger.MethodEntry(LogLevel.Debug); - - try - { - if (ApplicationSettings.UseNegotiate) - { - connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Negotiate; - } - runspace = RunspaceFactory.CreateRunspace(connectionInfo); - runspace.Open(); - } - - catch (Exception ex) - { - _logger.LogError($"Exception during Initialize...{RemoteFileException.FlattenExceptionMessages(ex, ex.Message)}"); - throw ex; - } - - _logger.MethodExit(LogLevel.Debug); - } - - public override void Terminate() - { - _logger.MethodEntry(LogLevel.Debug); - - runspace.Close(); - runspace.Dispose(); - - _logger.MethodExit(LogLevel.Debug); - } - - public override string RunCommand(string commandText, object[] parameters, bool withSudo, string[] passwordsToMaskInLog) - { - _logger.MethodEntry(LogLevel.Debug); - _logger.LogDebug($"RunCommand: {commandText}"); - - try - { - using (PowerShell ps = PowerShell.Create()) - { - ps.Runspace = runspace; - - if (commandText.ToLower().IndexOf("keytool ") > -1) - { - commandText = ($"& '{commandText}").Replace("keytool", "keytool'"); - commandText = "echo '' | " + commandText; - } - ps.AddScript(commandText); - - string displayCommand = commandText; - if (passwordsToMaskInLog != null) - { - foreach (string password in passwordsToMaskInLog) - displayCommand = displayCommand.Replace(password, PASSWORD_MASK_VALUE); - } - - if (parameters != null) - { - foreach(object parameter in parameters) - ps.AddArgument(parameter); - } - - _logger.LogDebug($"RunCommand: {displayCommand}"); - string result = FormatResult(ps.Invoke(parameters)); - - if (ps.HadErrors) - { - string errors = string.Empty; - System.Collections.ObjectModel.Collection errorRecords = ps.Streams.Error.ReadAll(); - foreach (ErrorRecord errorRecord in errorRecords) - { - string error = errorRecord.ToString(); - if (error.ToLower().Contains(IGNORED_ERROR1) - || error.ToLower().Contains(IGNORED_ERROR2)) - { - errors = null; - break; - } - - errors += (error + " "); - } - - if (!string.IsNullOrEmpty(errors)) - throw new ApplicationException(errors); - } - else - _logger.LogDebug($"WinRM Results: {displayCommand}::: {result}"); - - _logger.MethodExit(LogLevel.Debug); - - return result; - } - } - catch (Exception ex) - { - _logger.LogError($"Exception during RunCommand...{RemoteFileException.FlattenExceptionMessages(ex, ex.Message)}"); - throw ex; - } - } - - private byte[] RunCommandBinary(string commandText) - { - _logger.MethodEntry(LogLevel.Debug); - _logger.LogDebug($"RunCommandBinary: {commandText}"); - - byte[] rtnBytes = new byte[0]; - - try - { - using (PowerShell ps = PowerShell.Create()) - { - ps.Runspace = runspace; - ps.AddScript(commandText); - - System.Collections.ObjectModel.Collection psResult = ps.Invoke(); - - if (ps.HadErrors) - { - string errors = string.Empty; - System.Collections.ObjectModel.Collection errorRecords = ps.Streams.Error.ReadAll(); - foreach (ErrorRecord errorRecord in errorRecords) - errors += (errorRecord.ToString() + " "); - - throw new ApplicationException(errors); - } - else - { - if (psResult.Count > 0) - rtnBytes = (byte[])psResult[0].BaseObject; - _logger.LogDebug($"WinRM Results: {commandText}::: binary results."); - } - } - - _logger.MethodExit(LogLevel.Debug); - - return rtnBytes; - } - - catch (Exception ex) - { - _logger.LogError("Exception during RunCommandBinary...{RemoteFileException.FlattenExceptionMessages(ex, ex.Message)}"); - throw ex; - } - } - - public override void UploadCertificateFile(string path, string fileName, byte[] certBytes) - { - _logger.MethodEntry(LogLevel.Debug); - _logger.LogDebug($"UploadCertificateFile: {path} {fileName}"); - - string scriptBlock = $@" - param($contents) - - Set-Content {path + fileName} -Encoding Byte -Value $contents - "; - - object[] arguments = new object[] { certBytes }; - - RunCommand(scriptBlock, arguments, false, null); - - _logger.MethodEntry(LogLevel.Debug); - } - - public override byte[] DownloadCertificateFile(string path) - { - _logger.MethodEntry(LogLevel.Debug); - _logger.LogDebug($"DownloadCertificateFile: {path}"); - _logger.MethodExit(LogLevel.Debug); - - return RunCommandBinary($@"Get-Content -Path ""{path}"" -Encoding Byte -Raw"); - } - - public override void CreateEmptyStoreFile(string path, string linuxFilePermissions, string linuxFileOwner) - { - _logger.MethodEntry(LogLevel.Debug); - RunCommand($@"Out-File -FilePath ""{path}""", null, false, null); - _logger.MethodExit(LogLevel.Debug); - } - - public override bool DoesFileExist(string path) - { - _logger.MethodEntry(LogLevel.Debug); - _logger.LogDebug($"DoesFileExist: {path}"); - _logger.MethodExit(LogLevel.Debug); - - return Convert.ToBoolean(RunCommand($@"Test-Path -path ""{path}""", null, false, null)); - } - - public override void RemoveCertificateFile(string path, string fileName) - { - _logger.LogDebug($"RemoveCertificateFile: {path} {fileName}"); - - RunCommand($"rm {path}{fileName}", null, false, null); - } - - - private string FormatResult(ICollection results) - { - _logger.MethodEntry(LogLevel.Debug); - - StringBuilder rtn = new StringBuilder(); - - foreach (PSObject resultLine in results) - { - if (resultLine != null) - rtn.Append(resultLine.ToString() + System.Environment.NewLine); - } - - _logger.MethodExit(LogLevel.Debug); - - return rtn.ToString(); - } - } -} diff --git a/RemoteFile/RemoteHandlers/WinRMHandler.cs b/RemoteFile/RemoteHandlers/WinRMHandler.cs index 122fb579..354e23d9 100644 --- a/RemoteFile/RemoteHandlers/WinRMHandler.cs +++ b/RemoteFile/RemoteHandlers/WinRMHandler.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Management.Automation; +using System.Management.Automation.Remoting; using System.Management.Automation.Runspaces; using System.Net; using System.Text; @@ -31,10 +32,13 @@ internal WinRMHandler(string server, string serverLogin, string serverPassword) _logger.MethodEntry(LogLevel.Debug); Server = server; - connectionInfo = new WSManConnectionInfo(new System.Uri($"{Server}/wsman")); - if (!string.IsNullOrEmpty(serverLogin)) + if (Server.ToLower() != "localhost") { - connectionInfo.Credential = new PSCredential(serverLogin, new NetworkCredential(serverLogin, serverPassword).SecurePassword); + connectionInfo = new WSManConnectionInfo(new System.Uri($"{Server}/wsman")); + if (!string.IsNullOrEmpty(serverLogin)) + { + connectionInfo.Credential = new PSCredential(serverLogin, new NetworkCredential(serverLogin, serverPassword).SecurePassword); + } } _logger.MethodExit(LogLevel.Debug); @@ -46,11 +50,18 @@ public override void Initialize() try { - if (ApplicationSettings.UseNegotiate) + if (Server.ToLower() == "localhost") + { + runspace = RunspaceFactory.CreateRunspace(); + } + else { - connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Negotiate; + if (ApplicationSettings.UseNegotiate) + { + connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Negotiate; + } + runspace = RunspaceFactory.CreateRunspace(connectionInfo); } - runspace = RunspaceFactory.CreateRunspace(connectionInfo); runspace.Open(); } @@ -83,12 +94,6 @@ public override string RunCommand(string commandText, object[] parameters, bool using (PowerShell ps = PowerShell.Create()) { ps.Runspace = runspace; - - if (commandText.ToLower().IndexOf("keytool ") > -1) - { - commandText = ($"& '{commandText}").Replace("keytool", "keytool'"); - commandText = "echo '' | " + commandText; - } ps.AddScript(commandText); string displayCommand = commandText; @@ -100,7 +105,7 @@ public override string RunCommand(string commandText, object[] parameters, bool if (parameters != null) { - foreach(object parameter in parameters) + foreach (object parameter in parameters) ps.AddArgument(parameter); } @@ -120,7 +125,7 @@ public override string RunCommand(string commandText, object[] parameters, bool errors = null; break; } - + errors += (error + " "); } @@ -192,10 +197,12 @@ public override void UploadCertificateFile(string path, string fileName, byte[] _logger.MethodEntry(LogLevel.Debug); _logger.LogDebug($"UploadCertificateFile: {path} {fileName}"); + string cmdOption = RunCommand($@"$PSVersionTable.PSEdition", null, false, null).ToLower().Contains("core") ? "AsByteStream" : "Encoding Byte"; + string scriptBlock = $@" param($contents) - Set-Content {path + fileName} -Encoding Byte -Value $contents + Set-Content {path + fileName} -{cmdOption} -Value $contents "; object[] arguments = new object[] { certBytes }; @@ -211,7 +218,9 @@ public override byte[] DownloadCertificateFile(string path) _logger.LogDebug($"DownloadCertificateFile: {path}"); _logger.MethodExit(LogLevel.Debug); - return RunCommandBinary($@"Get-Content -Path ""{path}"" -Encoding Byte -Raw"); + string cmdOption = RunCommand($@"$PSVersionTable.PSEdition", null, false, null).ToLower().Contains("core") ? "AsByteStream" : "Encoding Byte"; + + return RunCommandBinary($@"Get-Content -Path ""{path}"" -{cmdOption} -Raw"); } public override void CreateEmptyStoreFile(string path, string linuxFilePermissions, string linuxFileOwner) From 7dbec226fdce598a68679d8c78c15d6341285a78 Mon Sep 17 00:00:00 2001 From: Keyfactor Date: Wed, 17 May 2023 17:34:15 +0000 Subject: [PATCH 3/5] Update generated README --- README.md | 61 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 5b01adee..5c0622e2 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,13 @@ The Remote File Orchestrator allows for the remote management of file-based cert #### Integration status: Production - Ready for use in production environments. -## About the Keyfactor Universal Orchestrator Capability +## About the Keyfactor Universal Orchestrator Extension -This repository contains a Universal Orchestrator Capability which is a plugin to the Keyfactor Universal Orchestrator. Within the Keyfactor Platform, Orchestrators are used to manage “certificate stores” — collections of certificates and roots of trust that are found within and used by various applications. +This repository contains a Universal Orchestrator Extension which is a plugin to the Keyfactor Universal Orchestrator. Within the Keyfactor Platform, Orchestrators are used to manage “certificate stores” — collections of certificates and roots of trust that are found within and used by various applications. -The Universal Orchestrator is part of the Keyfactor software distribution and is available via the Keyfactor customer portal. For general instructions on installing Capabilities, see the “Keyfactor Command Orchestrator Installation and Configuration Guide” section of the Keyfactor documentation. For configuration details of this specific Capability, see below in this readme. +The Universal Orchestrator is part of the Keyfactor software distribution and is available via the Keyfactor customer portal. For general instructions on installing Extensions, see the “Keyfactor Command Orchestrator Installation and Configuration Guide” section of the Keyfactor documentation. For configuration details of this specific Extension see below in this readme. -The Universal Orchestrator is the successor to the Windows Orchestrator. This Capability plugin only works with the Universal Orchestrator and does not work with the Windows Orchestrator. +The Universal Orchestrator is the successor to the Windows Orchestrator. This Orchestrator Extension plugin only works with the Universal Orchestrator and does not work with the Windows Orchestrator. @@ -50,34 +50,43 @@ The secrets that this orchestrator extension supports for use with a PAM Provide |StorePassword|The optional password used to secure the certificate store being managed| -It is not necessary to implement all of the secrets available to be managed by a PAM provider. For each value that you want managed by a PAM provider, simply enter the key value inside your specific PAM provider that will hold this value into the corresponding field when setting up the certificate store, discovery job, or API call. +It is not necessary to use a PAM Provider for all of the secrets available above. If a PAM Provider should not be used, simply enter in the actual value to be used, as normal. -Setting up a PAM provider for use involves adding an additional section to the manifest.json file for this extension as well as setting up the PAM provider you will be using. Each of these steps is specific to the PAM provider you will use and are documented in the specific GitHub repo for that provider. For a list of Keyfactor supported PAM providers, please reference the [Keyfactor Integration Catalog](https://keyfactor.github.io/integrations-catalog/content/pam). +If a PAM Provider will be used for one of the fields above, start by referencing the [Keyfactor Integration Catalog](https://keyfactor.github.io/integrations-catalog/content/pam). The GitHub repo for the PAM Provider to be used contains important information such as the format of the `json` needed. What follows is an example but does not reflect the `json` values for all PAM Providers as they have different "instance" and "initialization" parameter names and values. +
General PAM Provider Configuration +

-### Register the PAM Provider -A PAM Provider needs to be registered on the Universal Orchestrator in the same way other extensions are. Create a folder for the specific PAM Provider to be added, and place the contents of the PAM Provider into the folder. There needs to be a manifest.json with the PAM Provider. -After a manifest.json is added, the final step for configuration is setting the "provider-level" parameters for the PAM Provider. These are also known as the "initialization-level" parameters. These need to be placed in a json file that gets loaded by the Orchestrator by default. +### Example PAM Provider Setup -example manifest.json for MY-PROVIDER-NAME -``` -{ - "extensions": { - "Keyfactor.Platform.Extensions.IPAMProvider": { - "PAMProviders.MY-PROVIDER-NAME.PAMProvider": { - "assemblyPath": "my-pam-provider.dll", - "TypeFullName": "Keyfactor.Extensions.Pam.MyPamProviderClass" - } - } - }, - "Keyfactor:PAMProviders:MY-PROVIDER-NAME:InitializationInfo": { - "InitParam1": "InitValue1", - "InitParam2": "InitValue2" - } -} -``` +To use a PAM Provider to resolve a field, in this example the __Server Password__ will be resolved by the `Hashicorp-Vault` provider, first install the PAM Provider extension from the [Keyfactor Integration Catalog](https://keyfactor.github.io/integrations-catalog/content/pam) on the Universal Orchestrator. + +Next, complete configuration of the PAM Provider on the UO by editing the `manifest.json` of the __PAM Provider__ (e.g. located at extensions/Hashicorp-Vault/manifest.json). The "initialization" parameters need to be entered here: + +~~~ json + "Keyfactor:PAMProviders:Hashicorp-Vault:InitializationInfo": { + "Host": "http://127.0.0.1:8200", + "Path": "v1/secret/data", + "Token": "xxxxxx" + } +~~~ + +After these values are entered, the Orchestrator needs to be restarted to pick up the configuration. Now the PAM Provider can be used on other Orchestrator Extensions. + +### Use the PAM Provider +With the PAM Provider configured as an extenion on the UO, a `json` object can be passed instead of an actual value to resolve the field with a PAM Provider. Consult the [Keyfactor Integration Catalog](https://keyfactor.github.io/integrations-catalog/content/pam) for the specific format of the `json` object. + +To have the __Server Password__ field resolved by the `Hashicorp-Vault` provider, the corresponding `json` object from the `Hashicorp-Vault` extension needs to be copied and filed in with the correct information: + +~~~ json +{"Secret":"my-kv-secret","Key":"myServerPassword"} +~~~ + +This text would be entered in as the value for the __Server Password__, instead of entering in the actual password. The Orchestrator will attempt to use the PAM Provider to retrieve the __Server Password__. If PAM should not be used, just directly enter in the value for the field. +

+
From e0172473d54333c9d3e926d29d9fc229b1dd66ce Mon Sep 17 00:00:00 2001 From: kfadmin Date: Wed, 17 May 2023 17:38:37 +0000 Subject: [PATCH 4/5] changes --- CHANGELOG.md | 4 ++++ readme_source.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f6c4fcc..82d7089a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +v2.2.0 +- Add ability to manage same windows server as installed without using WinRM +- Check for "core" version of PowerShell for command tweaks + v2.1.2 - Bug fix: Discovery not working against Windows servers - Bug fix: Issue running Discovery on Windows servers with one or more spaces in the path diff --git a/readme_source.md b/readme_source.md index 7cefb029..3e8629ee 100644 --- a/readme_source.md +++ b/readme_source.md @@ -268,7 +268,7 @@ CURL script to automate certificate store type creation can be found [here](Cert   ## Creating Certificate Stores and Scheduling Discovery Jobs -Please refer to the Keyfactor Command Reference Guide for information on creating certificate stores and scheduling Discovery jobs in Keyfactor Command. However, there are a few fields that are important to highlight here - Client Machine, Store Path (Creating Certificate Stores), and Directories to search (Discovery jobs) and Extensions (Discovery jobs). For Linux orchestrated servers, "Client Machine" should be the DNS or IP address of the remote orchestrated server while "Store Path" is the full path and file name of the file based store, beginning with a forward slash (/). For Windows orchestrated servers, "Client Machine" should be of the format {protocol}://{dns-or-ip}:{port} where {protocol} is either http or https, {dns-or-ip} is the DNS or IP address of the remote orchestrated server, and {port} is the port where WinRM is listening, by convention usually 5985 for http and 5986 for https. "Store Path" is the full path and file name of the file based store, beginning with a drive letter (i.e. c:\). For example valid values for Client Machine and Store Path for Linux and Windows managed servers may look something like: +Please refer to the Keyfactor Command Reference Guide for information on creating certificate stores and scheduling Discovery jobs in Keyfactor Command. However, there are a few fields that are important to highlight here - Client Machine, Store Path (Creating Certificate Stores), and Directories to search (Discovery jobs) and Extensions (Discovery jobs). For Linux orchestrated servers, "Client Machine" should be the DNS or IP address of the remote orchestrated server while "Store Path" is the full path and file name of the file based store, beginning with a forward slash (/). For Windows orchestrated servers, "Client Machine" should be of the format {protocol}://{dns-or-ip}:{port} where {protocol} is either http or https, {dns-or-ip} is the DNS or IP address of the remote orchestrated server, and {port} is the port where WinRM is listening, by convention usually 5985 for http and 5986 for https. Alternately, entering the keyword "localhost" for "Client Machine" will point to the server where the orchestrator service is installed and WinRM WILL NOT be required. "Store Path" is the full path and file name of the file based store, beginning with a drive letter (i.e. c:\). For example valid values for Client Machine and Store Path for Linux and Windows managed servers may look something like: Linux: Client Machine - 127.0.0.1 or MyLinuxServerName; Store Path - /home/folder/path/storename.ext Windows: Client Machine - https://My.Server.Domain:5986; Store Path - c:\folder\path\storename.ext From 69d6c697d01ee4e82dcd575eba10044ac13ba03e Mon Sep 17 00:00:00 2001 From: Keyfactor Date: Wed, 17 May 2023 17:39:25 +0000 Subject: [PATCH 5/5] Update generated README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c0622e2..002395ad 100644 --- a/README.md +++ b/README.md @@ -364,7 +364,7 @@ CURL script to automate certificate store type creation can be found [here](Cert   ## Creating Certificate Stores and Scheduling Discovery Jobs -Please refer to the Keyfactor Command Reference Guide for information on creating certificate stores and scheduling Discovery jobs in Keyfactor Command. However, there are a few fields that are important to highlight here - Client Machine, Store Path (Creating Certificate Stores), and Directories to search (Discovery jobs) and Extensions (Discovery jobs). For Linux orchestrated servers, "Client Machine" should be the DNS or IP address of the remote orchestrated server while "Store Path" is the full path and file name of the file based store, beginning with a forward slash (/). For Windows orchestrated servers, "Client Machine" should be of the format {protocol}://{dns-or-ip}:{port} where {protocol} is either http or https, {dns-or-ip} is the DNS or IP address of the remote orchestrated server, and {port} is the port where WinRM is listening, by convention usually 5985 for http and 5986 for https. "Store Path" is the full path and file name of the file based store, beginning with a drive letter (i.e. c:\). For example valid values for Client Machine and Store Path for Linux and Windows managed servers may look something like: +Please refer to the Keyfactor Command Reference Guide for information on creating certificate stores and scheduling Discovery jobs in Keyfactor Command. However, there are a few fields that are important to highlight here - Client Machine, Store Path (Creating Certificate Stores), and Directories to search (Discovery jobs) and Extensions (Discovery jobs). For Linux orchestrated servers, "Client Machine" should be the DNS or IP address of the remote orchestrated server while "Store Path" is the full path and file name of the file based store, beginning with a forward slash (/). For Windows orchestrated servers, "Client Machine" should be of the format {protocol}://{dns-or-ip}:{port} where {protocol} is either http or https, {dns-or-ip} is the DNS or IP address of the remote orchestrated server, and {port} is the port where WinRM is listening, by convention usually 5985 for http and 5986 for https. Alternately, entering the keyword "localhost" for "Client Machine" will point to the server where the orchestrator service is installed and WinRM WILL NOT be required. "Store Path" is the full path and file name of the file based store, beginning with a drive letter (i.e. c:\). For example valid values for Client Machine and Store Path for Linux and Windows managed servers may look something like: Linux: Client Machine - 127.0.0.1 or MyLinuxServerName; Store Path - /home/folder/path/storename.ext Windows: Client Machine - https://My.Server.Domain:5986; Store Path - c:\folder\path\storename.ext