Skip to content

Commit 5726a77

Browse files
authored
Merge pull request #75 from Keyfactor/ab#69330
Ab#69330
2 parents 546cdc5 + fea5dda commit 5726a77

31 files changed

+817
-697
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
v2.11.0
2+
- Added ability to set SSH port when managing Linux servers
3+
- Bug Fix - Issue adding new certificate with private key to RFPEM store on Windows
4+
15
v2.10.0
26
- Added support for Eliptical Curve (EC) private keys for RFPEM.
37
- 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.

README.md

+114-74
Large diffs are not rendered by default.

RemoteFile/ApplicationSettings.cs

+19
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public enum FileTransferProtocolEnum
2828
private const string DEFAULT_LINUX_PERMISSION_SETTING = "";
2929
private const string DEFAULT_OWNER_SETTING = "";
3030
private const string DEFAULT_SUDO_IMPERSONATION_SETTING = "";
31+
private const int DEFAULT_SSH_PORT = 22;
3132

3233
private static Dictionary<string,string> configuration;
3334

@@ -40,6 +41,24 @@ public enum FileTransferProtocolEnum
4041
public static string DefaultSudoImpersonatedUser { get { return configuration.ContainsKey("DefaultSudoImpersonatedUser") ? configuration["DefaultSudoImpersonatedUser"] : DEFAULT_SUDO_IMPERSONATION_SETTING; } }
4142
public static bool CreateCSROnDevice { get { return configuration.ContainsKey("CreateCSROnDevice") ? configuration["CreateCSROnDevice"]?.ToUpper() == "Y" : false; } }
4243
public static string TempFilePathForODKG { get { return configuration.ContainsKey("TempFilePathForODKG") ? configuration["TempFilePathForODKG"] : string.Empty; } }
44+
public static int SSHPort
45+
{
46+
get
47+
{
48+
if (configuration.ContainsKey("SSHPort") && !string.IsNullOrEmpty(configuration["SSHPort"]))
49+
{
50+
int sshPort;
51+
if (int.TryParse(configuration["SSHPort"], out sshPort))
52+
return sshPort;
53+
else
54+
throw new RemoteFileException($"Invalid optional config.json SSHPort value of {configuration["SSHPort"]}. If present, this must be an integer value.");
55+
}
56+
else
57+
{
58+
return DEFAULT_SSH_PORT;
59+
}
60+
}
61+
}
4362
public static FileTransferProtocolEnum FileTransferProtocol
4463
{
4564
get

RemoteFile/ImplementedStoreTypes/PEM/PEMCertificateStoreSerializer.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ private PrivateKeyTypeEnum GetPrivateKeyType(string storeContents, out string pr
294294
{
295295
foreach (string begDelim in PrivateKeyDelimetersPkcs8)
296296
{
297-
if (string.IsNullOrEmpty(storeContents) || storeContents.Contains(begDelim))
297+
if (string.IsNullOrEmpty(storeContents) || storeContents.Length < 10 || storeContents.Contains(begDelim))
298298
{
299299
privateKeyBegDelim = begDelim;
300300
return PrivateKeyTypeEnum.PKCS8;

RemoteFile/InventoryBase.cs

+4-27
Original file line numberDiff line numberDiff line change
@@ -28,41 +28,18 @@ public abstract class InventoryBase : RemoteFileJobTypeBase, IInventoryJobExtens
2828
public JobResult ProcessJob(InventoryJobConfiguration config, SubmitInventoryUpdate submitInventory)
2929
{
3030
ILogger logger = LogHandler.GetClassLogger(this.GetType());
31-
logger.LogDebug($"Begin {config.Capability} for job id {config.JobId}...");
32-
logger.LogDebug($"Server: { config.CertificateStoreDetails.ClientMachine }");
33-
logger.LogDebug($"Store Path: { config.CertificateStoreDetails.StorePath }");
34-
logger.LogDebug($"Job Properties:");
35-
foreach (KeyValuePair<string, object> keyValue in config.JobProperties ?? new Dictionary<string,object>())
36-
{
37-
logger.LogDebug($" {keyValue.Key}: {keyValue.Value}");
38-
}
3931

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

4335
try
4436
{
45-
string userName = PAMUtilities.ResolvePAMField(_resolver, logger, "Server User Name", config.ServerUsername);
46-
string userPassword = PAMUtilities.ResolvePAMField(_resolver, logger, "Server Password", config.ServerPassword);
47-
string storePassword = PAMUtilities.ResolvePAMField(_resolver, logger, "Store Password", config.CertificateStoreDetails.StorePassword);
48-
4937
ApplicationSettings.Initialize(this.GetType().Assembly.Location);
50-
dynamic properties = JsonConvert.DeserializeObject(config.CertificateStoreDetails.Properties.ToString());
51-
string sudoImpersonatedUser = properties.SudoImpersonatedUser == null || string.IsNullOrEmpty(properties.SudoImpersonatedUser.Value) ?
52-
ApplicationSettings.DefaultSudoImpersonatedUser :
53-
properties.SudoImpersonatedUser.Value;
54-
bool includePortInSPN = properties.IncludePortInSPN == null || string.IsNullOrEmpty(properties.IncludePortInSPN.Value) ?
55-
false :
56-
Convert.ToBoolean(properties.IncludePortInSPN.Value);
57-
58-
ApplicationSettings.FileTransferProtocolEnum fileTransferProtocol = ApplicationSettings.FileTransferProtocol;
59-
if (properties.FileTransferProtocol != null && !string.IsNullOrEmpty(properties.FileTransferProtocol.Value))
60-
{
61-
Enum.TryParse(properties.FileTransferProtocol.Value, out fileTransferProtocol);
62-
}
6338

64-
certificateStore = new RemoteCertificateStore(config.CertificateStoreDetails.ClientMachine, userName, userPassword, config.CertificateStoreDetails.StorePath, storePassword, fileTransferProtocol, includePortInSPN);
65-
certificateStore.Initialize(sudoImpersonatedUser);
39+
SetJobProperties(config, config.CertificateStoreDetails, logger);
40+
41+
certificateStore = new RemoteCertificateStore(config.CertificateStoreDetails.ClientMachine, UserName, UserPassword, config.CertificateStoreDetails.StorePath, StorePassword, FileTransferProtocol, SSHPort, IncludePortInSPN);
42+
certificateStore.Initialize(SudoImpersonatedUser);
6643
certificateStore.LoadCertificateStore(certificateStoreSerializer, true);
6744

6845
List<X509Certificate2Collection> collections = certificateStore.GetCertificateChains();

RemoteFile/ManagementBase.cs

+7-33
Original file line numberDiff line numberDiff line change
@@ -28,43 +28,17 @@ public abstract class ManagementBase : RemoteFileJobTypeBase, IManagementJobExte
2828
public JobResult ProcessJob(ManagementJobConfiguration config)
2929
{
3030
ILogger logger = LogHandler.GetClassLogger(this.GetType());
31-
logger.LogDebug($"Begin {config.Capability} for job id {config.JobId}...");
32-
logger.LogDebug($"Server: {config.CertificateStoreDetails.ClientMachine}");
33-
logger.LogDebug($"Store Path: {config.CertificateStoreDetails.StorePath}");
34-
logger.LogDebug($"Job Properties:");
35-
foreach (KeyValuePair<string, object> keyValue in config.JobProperties == null ? new Dictionary<string, object>() : config.JobProperties)
36-
{
37-
logger.LogDebug($" {keyValue.Key}: {keyValue.Value}");
38-
}
3931

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

4234
try
4335
{
44-
string userName = PAMUtilities.ResolvePAMField(_resolver, logger, "Server User Name", config.ServerUsername);
45-
string userPassword = PAMUtilities.ResolvePAMField(_resolver, logger, "Server Password", config.ServerPassword);
46-
string storePassword = PAMUtilities.ResolvePAMField(_resolver, logger, "Store Password", config.CertificateStoreDetails.StorePassword);
47-
4836
ApplicationSettings.Initialize(this.GetType().Assembly.Location);
49-
dynamic properties = JsonConvert.DeserializeObject(config.CertificateStoreDetails.Properties.ToString());
50-
string sudoImpersonatedUser = properties.SudoImpersonatedUser == null || string.IsNullOrEmpty(properties.SudoImpersonatedUser.Value) ?
51-
ApplicationSettings.DefaultSudoImpersonatedUser :
52-
properties.SudoImpersonatedUser.Value;
53-
bool removeRootCertificate = properties.RemoveRootCertificate == null || string.IsNullOrEmpty(properties.RemoveRootCertificate.Value) ?
54-
false :
55-
Convert.ToBoolean(properties.RemoveRootCertificate.Value);
56-
bool includePortInSPN = properties.IncludePortInSPN == null || string.IsNullOrEmpty(properties.IncludePortInSPN.Value) ?
57-
false :
58-
Convert.ToBoolean(properties.IncludePortInSPN.Value);
59-
60-
ApplicationSettings.FileTransferProtocolEnum fileTransferProtocol = ApplicationSettings.FileTransferProtocol;
61-
if (properties.FileTransferProtocol != null && !string.IsNullOrEmpty(properties.FileTransferProtocol.Value))
62-
{
63-
Enum.TryParse(properties.FileTransferProtocol.Value, out fileTransferProtocol);
64-
}
6537

66-
certificateStore = new RemoteCertificateStore(config.CertificateStoreDetails.ClientMachine, userName, userPassword, config.CertificateStoreDetails.StorePath, storePassword, fileTransferProtocol, includePortInSPN);
67-
certificateStore.Initialize(sudoImpersonatedUser);
38+
SetJobProperties(config, config.CertificateStoreDetails, logger);
39+
40+
certificateStore = new RemoteCertificateStore(config.CertificateStoreDetails.ClientMachine, UserName, UserPassword, config.CertificateStoreDetails.StorePath, StorePassword, FileTransferProtocol, SSHPort, IncludePortInSPN);
41+
certificateStore.Initialize(SudoImpersonatedUser);
6842

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

@@ -80,8 +54,8 @@ public JobResult ProcessJob(ManagementJobConfiguration config)
8054
throw new RemoteFileException($"Certificate store {config.CertificateStoreDetails.StorePath} does not exist on server {config.CertificateStoreDetails.ClientMachine}.");
8155
}
8256
certificateStore.LoadCertificateStore(certificateStoreSerializer, false);
83-
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);
84-
certificateStore.SaveCertificateStore(certificateStoreSerializer.SerializeRemoteCertificateStore(certificateStore.GetCertificateStore(), storePathFile.Path, storePathFile.File, storePassword, certificateStore.RemoteHandler));
57+
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);
58+
certificateStore.SaveCertificateStore(certificateStoreSerializer.SerializeRemoteCertificateStore(certificateStore.GetCertificateStore(), storePathFile.Path, storePathFile.File, StorePassword, certificateStore.RemoteHandler));
8559

8660
logger.LogDebug($"END add Operation for {config.CertificateStoreDetails.StorePath} on {config.CertificateStoreDetails.ClientMachine}.");
8761
break;
@@ -96,7 +70,7 @@ public JobResult ProcessJob(ManagementJobConfiguration config)
9670
{
9771
certificateStore.LoadCertificateStore(certificateStoreSerializer, false);
9872
certificateStore.DeleteCertificateByAlias(config.JobCertificate.Alias);
99-
certificateStore.SaveCertificateStore(certificateStoreSerializer.SerializeRemoteCertificateStore(certificateStore.GetCertificateStore(), storePathFile.Path, storePathFile.File, storePassword, certificateStore.RemoteHandler));
73+
certificateStore.SaveCertificateStore(certificateStoreSerializer.SerializeRemoteCertificateStore(certificateStore.GetCertificateStore(), storePathFile.Path, storePathFile.File, StorePassword, certificateStore.RemoteHandler));
10074
}
10175
logger.LogDebug($"END Delete Operation for {config.CertificateStoreDetails.StorePath} on {config.CertificateStoreDetails.ClientMachine}.");
10276
break;

0 commit comments

Comments
 (0)