Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
v2.11.0
- Added ability to set SSH port when managing Linux servers
- Bug Fix - Issue adding new certificate with private key to RFPEM store on Windows

v2.10.0
- Added support for Eliptical Curve (EC) private keys for RFPEM.
- For Linux hosted certificate stores, added ability to inherit file permissions and ownership when creating new stores by modifying default behavior when config.json and certificate store permissions/ownership settings are left empty.
Expand Down
188 changes: 114 additions & 74 deletions README.md

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions RemoteFile/ApplicationSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public enum FileTransferProtocolEnum
private const string DEFAULT_LINUX_PERMISSION_SETTING = "";
private const string DEFAULT_OWNER_SETTING = "";
private const string DEFAULT_SUDO_IMPERSONATION_SETTING = "";
private const int DEFAULT_SSH_PORT = 22;

private static Dictionary<string,string> configuration;

Expand All @@ -40,6 +41,24 @@ public enum FileTransferProtocolEnum
public static string DefaultSudoImpersonatedUser { get { return configuration.ContainsKey("DefaultSudoImpersonatedUser") ? configuration["DefaultSudoImpersonatedUser"] : DEFAULT_SUDO_IMPERSONATION_SETTING; } }
public static bool CreateCSROnDevice { get { return configuration.ContainsKey("CreateCSROnDevice") ? configuration["CreateCSROnDevice"]?.ToUpper() == "Y" : false; } }
public static string TempFilePathForODKG { get { return configuration.ContainsKey("TempFilePathForODKG") ? configuration["TempFilePathForODKG"] : string.Empty; } }
public static int SSHPort
{
get
{
if (configuration.ContainsKey("SSHPort") && !string.IsNullOrEmpty(configuration["SSHPort"]))
{
int sshPort;
if (int.TryParse(configuration["SSHPort"], out sshPort))
return sshPort;
else
throw new RemoteFileException($"Invalid optional config.json SSHPort value of {configuration["SSHPort"]}. If present, this must be an integer value.");
}
else
{
return DEFAULT_SSH_PORT;
}
}
}
public static FileTransferProtocolEnum FileTransferProtocol
{
get
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ private PrivateKeyTypeEnum GetPrivateKeyType(string storeContents, out string pr
{
foreach (string begDelim in PrivateKeyDelimetersPkcs8)
{
if (string.IsNullOrEmpty(storeContents) || storeContents.Contains(begDelim))
if (string.IsNullOrEmpty(storeContents) || storeContents.Length < 10 || storeContents.Contains(begDelim))
{
privateKeyBegDelim = begDelim;
return PrivateKeyTypeEnum.PKCS8;
Expand Down
31 changes: 4 additions & 27 deletions RemoteFile/InventoryBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,41 +28,18 @@ public abstract class InventoryBase : RemoteFileJobTypeBase, IInventoryJobExtens
public JobResult ProcessJob(InventoryJobConfiguration config, SubmitInventoryUpdate submitInventory)
{
ILogger logger = LogHandler.GetClassLogger(this.GetType());
logger.LogDebug($"Begin {config.Capability} for job id {config.JobId}...");
logger.LogDebug($"Server: { config.CertificateStoreDetails.ClientMachine }");
logger.LogDebug($"Store Path: { config.CertificateStoreDetails.StorePath }");
logger.LogDebug($"Job Properties:");
foreach (KeyValuePair<string, object> keyValue in config.JobProperties ?? new Dictionary<string,object>())
{
logger.LogDebug($" {keyValue.Key}: {keyValue.Value}");
}

ICertificateStoreSerializer certificateStoreSerializer = GetCertificateStoreSerializer(config.CertificateStoreDetails.Properties);
List<CurrentInventoryItem> inventoryItems = new List<CurrentInventoryItem>();

try
{
string userName = PAMUtilities.ResolvePAMField(_resolver, logger, "Server User Name", config.ServerUsername);
string userPassword = PAMUtilities.ResolvePAMField(_resolver, logger, "Server Password", config.ServerPassword);
string storePassword = PAMUtilities.ResolvePAMField(_resolver, logger, "Store Password", config.CertificateStoreDetails.StorePassword);

ApplicationSettings.Initialize(this.GetType().Assembly.Location);
dynamic properties = JsonConvert.DeserializeObject(config.CertificateStoreDetails.Properties.ToString());
string sudoImpersonatedUser = properties.SudoImpersonatedUser == null || string.IsNullOrEmpty(properties.SudoImpersonatedUser.Value) ?
ApplicationSettings.DefaultSudoImpersonatedUser :
properties.SudoImpersonatedUser.Value;
bool includePortInSPN = properties.IncludePortInSPN == null || string.IsNullOrEmpty(properties.IncludePortInSPN.Value) ?
false :
Convert.ToBoolean(properties.IncludePortInSPN.Value);

ApplicationSettings.FileTransferProtocolEnum fileTransferProtocol = ApplicationSettings.FileTransferProtocol;
if (properties.FileTransferProtocol != null && !string.IsNullOrEmpty(properties.FileTransferProtocol.Value))
{
Enum.TryParse(properties.FileTransferProtocol.Value, out fileTransferProtocol);
}

certificateStore = new RemoteCertificateStore(config.CertificateStoreDetails.ClientMachine, userName, userPassword, config.CertificateStoreDetails.StorePath, storePassword, fileTransferProtocol, includePortInSPN);
certificateStore.Initialize(sudoImpersonatedUser);
SetJobProperties(config, config.CertificateStoreDetails, logger);

certificateStore = new RemoteCertificateStore(config.CertificateStoreDetails.ClientMachine, UserName, UserPassword, config.CertificateStoreDetails.StorePath, StorePassword, FileTransferProtocol, SSHPort, IncludePortInSPN);
certificateStore.Initialize(SudoImpersonatedUser);
certificateStore.LoadCertificateStore(certificateStoreSerializer, true);

List<X509Certificate2Collection> collections = certificateStore.GetCertificateChains();
Expand Down
40 changes: 7 additions & 33 deletions RemoteFile/ManagementBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,43 +28,17 @@ public abstract class ManagementBase : RemoteFileJobTypeBase, IManagementJobExte
public JobResult ProcessJob(ManagementJobConfiguration config)
{
ILogger logger = LogHandler.GetClassLogger(this.GetType());
logger.LogDebug($"Begin {config.Capability} for job id {config.JobId}...");
logger.LogDebug($"Server: {config.CertificateStoreDetails.ClientMachine}");
logger.LogDebug($"Store Path: {config.CertificateStoreDetails.StorePath}");
logger.LogDebug($"Job Properties:");
foreach (KeyValuePair<string, object> keyValue in config.JobProperties == null ? new Dictionary<string, object>() : config.JobProperties)
{
logger.LogDebug($" {keyValue.Key}: {keyValue.Value}");
}

ICertificateStoreSerializer certificateStoreSerializer = GetCertificateStoreSerializer(config.CertificateStoreDetails.Properties);

try
{
string userName = PAMUtilities.ResolvePAMField(_resolver, logger, "Server User Name", config.ServerUsername);
string userPassword = PAMUtilities.ResolvePAMField(_resolver, logger, "Server Password", config.ServerPassword);
string storePassword = PAMUtilities.ResolvePAMField(_resolver, logger, "Store Password", config.CertificateStoreDetails.StorePassword);

ApplicationSettings.Initialize(this.GetType().Assembly.Location);
dynamic properties = JsonConvert.DeserializeObject(config.CertificateStoreDetails.Properties.ToString());
string sudoImpersonatedUser = properties.SudoImpersonatedUser == null || string.IsNullOrEmpty(properties.SudoImpersonatedUser.Value) ?
ApplicationSettings.DefaultSudoImpersonatedUser :
properties.SudoImpersonatedUser.Value;
bool removeRootCertificate = properties.RemoveRootCertificate == null || string.IsNullOrEmpty(properties.RemoveRootCertificate.Value) ?
false :
Convert.ToBoolean(properties.RemoveRootCertificate.Value);
bool includePortInSPN = properties.IncludePortInSPN == null || string.IsNullOrEmpty(properties.IncludePortInSPN.Value) ?
false :
Convert.ToBoolean(properties.IncludePortInSPN.Value);

ApplicationSettings.FileTransferProtocolEnum fileTransferProtocol = ApplicationSettings.FileTransferProtocol;
if (properties.FileTransferProtocol != null && !string.IsNullOrEmpty(properties.FileTransferProtocol.Value))
{
Enum.TryParse(properties.FileTransferProtocol.Value, out fileTransferProtocol);
}

certificateStore = new RemoteCertificateStore(config.CertificateStoreDetails.ClientMachine, userName, userPassword, config.CertificateStoreDetails.StorePath, storePassword, fileTransferProtocol, includePortInSPN);
certificateStore.Initialize(sudoImpersonatedUser);
SetJobProperties(config, config.CertificateStoreDetails, logger);

certificateStore = new RemoteCertificateStore(config.CertificateStoreDetails.ClientMachine, UserName, UserPassword, config.CertificateStoreDetails.StorePath, StorePassword, FileTransferProtocol, SSHPort, IncludePortInSPN);
certificateStore.Initialize(SudoImpersonatedUser);

PathFile storePathFile = RemoteCertificateStore.SplitStorePathFile(config.CertificateStoreDetails.StorePath);

Expand All @@ -80,8 +54,8 @@ public JobResult ProcessJob(ManagementJobConfiguration config)
throw new RemoteFileException($"Certificate store {config.CertificateStoreDetails.StorePath} does not exist on server {config.CertificateStoreDetails.ClientMachine}.");
}
certificateStore.LoadCertificateStore(certificateStoreSerializer, false);
certificateStore.AddCertificate((config.JobCertificate.Alias ?? new X509Certificate2(Convert.FromBase64String(config.JobCertificate.Contents), config.JobCertificate.PrivateKeyPassword, X509KeyStorageFlags.EphemeralKeySet).Thumbprint), config.JobCertificate.Contents, config.Overwrite, config.JobCertificate.PrivateKeyPassword, removeRootCertificate);
certificateStore.SaveCertificateStore(certificateStoreSerializer.SerializeRemoteCertificateStore(certificateStore.GetCertificateStore(), storePathFile.Path, storePathFile.File, storePassword, certificateStore.RemoteHandler));
certificateStore.AddCertificate((config.JobCertificate.Alias ?? new X509Certificate2(Convert.FromBase64String(config.JobCertificate.Contents), config.JobCertificate.PrivateKeyPassword, X509KeyStorageFlags.EphemeralKeySet).Thumbprint), config.JobCertificate.Contents, config.Overwrite, config.JobCertificate.PrivateKeyPassword, RemoveRootCertificate);
certificateStore.SaveCertificateStore(certificateStoreSerializer.SerializeRemoteCertificateStore(certificateStore.GetCertificateStore(), storePathFile.Path, storePathFile.File, StorePassword, certificateStore.RemoteHandler));

logger.LogDebug($"END add Operation for {config.CertificateStoreDetails.StorePath} on {config.CertificateStoreDetails.ClientMachine}.");
break;
Expand All @@ -96,7 +70,7 @@ public JobResult ProcessJob(ManagementJobConfiguration config)
{
certificateStore.LoadCertificateStore(certificateStoreSerializer, false);
certificateStore.DeleteCertificateByAlias(config.JobCertificate.Alias);
certificateStore.SaveCertificateStore(certificateStoreSerializer.SerializeRemoteCertificateStore(certificateStore.GetCertificateStore(), storePathFile.Path, storePathFile.File, storePassword, certificateStore.RemoteHandler));
certificateStore.SaveCertificateStore(certificateStoreSerializer.SerializeRemoteCertificateStore(certificateStore.GetCertificateStore(), storePathFile.Path, storePathFile.File, StorePassword, certificateStore.RemoteHandler));
}
logger.LogDebug($"END Delete Operation for {config.CertificateStoreDetails.StorePath} on {config.CertificateStoreDetails.ClientMachine}.");
break;
Expand Down
Loading
Loading