Skip to content

Commit 6753d85

Browse files
authored
59831 error getting iisu bound certs (#106)
* Added additional trace logging information * Minor Exception Handling Update * ab#59831 Added additional error trapping, fixed typo, fixed missing parameter when adding IIS certificate
1 parent 7c35815 commit 6753d85

File tree

12 files changed

+75
-41
lines changed

12 files changed

+75
-41
lines changed

CHANGELOG.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
2.4.2
2+
* Correct false positive error when completing an IIS inventory job.
3+
* Revert to specifying the version of PowerShell to use when establishing a local PowerShell Runspace.
4+
* Fixed typo in error message.
5+
16
2.4.1
27
* Modified the CertUtil logic to use the -addstore argument when no password is sent with the certificate information.
38
* Added additional error trapping and trace logs
49

510
2.4.0
611
* Changed the way certificates are added to cert stores. CertUtil is now used to import the PFX certificate into the associated store. The CSP is now considered when maintaining certificates, empty CSP values will result in using the machines default CSP.
712
* Added the Crypto Service Provider and SAN Entry Parameters to be used on Inventory queries, Adding and ReEnrollments for the WinCert, WinSQL and IISU extensions.
8-
* Changed how Client Machine Names are handled when a 'localhost' connection is desiered. The new naming convention is: {machineName}|localmachine. This will eliminate the issue of unqiue naming conflicts.
13+
* Changed how Client Machine Names are handled when a 'localhost' connection is desired. The new naming convention is: {machineName}|localmachine. This will eliminate the issue of unique naming conflicts.
914
* Updated the manifest.json to now include WinSQL ReEnrollment.
1015
* Updated the integration-manifest.json file for new fields in cert store types.
1116

@@ -49,7 +54,7 @@
4954
2.0.0
5055
* Add support for reenrollment jobs (On Device Key Generation) with the ability to specify a cryptographic provider. Specification of cryptographic provider allows HSM (Hardware Security Module) use.
5156
* Local PAM Support added (requires Universal Orchestrator Framework version 10.1)
52-
* Certificate store type changed from IISBin to IISU. See readme for migration notes.
57+
* Certificate store type changed from IISBin to IISU. See README for migration notes.
5358

5459

5560
1.1.3

IISU/ClientPSCertStoreInventory.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ public List<Certificate> GetCertificatesFromStore(Runspace runSpace, string stor
6464

6565
ps.AddScript(certStoreScript);
6666

67+
_logger.LogTrace($"Executing the following script:\n{certStoreScript}");
68+
6769
var certs = ps.Invoke();
6870

6971
foreach (var c in certs)
@@ -77,11 +79,13 @@ public List<Certificate> GetCertificatesFromStore(Runspace runSpace, string stor
7779
SAN = Certificate.Utilities.FormatSAN($"{c.Properties["san"]?.Value}")
7880
});
7981
}
80-
82+
_logger.LogTrace($"found: {myCertificates.Count} certificate(s), exiting GetCertificatesFromStore()");
8183
return myCertificates;
8284
}
8385
catch (Exception ex)
8486
{
87+
_logger.LogTrace($"An error occurred in the WinCert GetCertificatesFromStore method:\n{ex.Message}");
88+
8589
throw new CertificateStoreException(
8690
$"Error listing certificate in {storePath} store on {runSpace.ConnectionInfo.ComputerName}: {ex.Message}");
8791
}

IISU/ClientPSCertStoreManager.cs

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public JobResult ImportPFXFile(string filePath, string privateKeyPassword, strin
133133
// If no private key password is provided, import the pfx file directory to the store using addstore argument
134134
string script = @"
135135
param($pfxFilePath, $storePath)
136-
$output = certutil -addstore $storePath $pfxFilePath 2>&1
136+
$output = certutil -f -addstore $storePath $pfxFilePath 2>&1
137137
$exit_message = ""LASTEXITCODE:$($LASTEXITCODE)""
138138
139139
if ($output.GetType().Name -eq ""String"")
@@ -156,20 +156,19 @@ public JobResult ImportPFXFile(string filePath, string privateKeyPassword, strin
156156
// Use ImportPFX to import the pfx file with private key password to the appropriate cert store
157157

158158
string script = @"
159-
param($pfxFilePath, $privateKeyPassword)
160-
$output = certutil -importpfx -p $privateKeyPassword $storePath $pfxFilePath 2>&1
159+
param($pfxFilePath, $privateKeyPassword, $storePath)
160+
$output = certutil -f -importpfx -p $privateKeyPassword $storePath $pfxFilePath 2>&1
161161
$exit_message = ""LASTEXITCODE:$($LASTEXITCODE)""
162-
$stuff = certutil -dump
163-
if ($stuff.GetType().Name -eq ""String"")
162+
163+
if ($output.GetType().Name -eq ""String"")
164164
{
165-
$stuff = @($stuff, $exit_message)
165+
$output = @($output, $exit_message)
166166
}
167167
else
168168
{
169-
$stuff += $exit_message
169+
$output += $exit_message
170170
}
171171
$output
172-
$stuff
173172
";
174173

175174
ps.AddScript(script);
@@ -184,20 +183,18 @@ public JobResult ImportPFXFile(string filePath, string privateKeyPassword, strin
184183
{
185184
string script = @"
186185
param($pfxFilePath, $cspName, $storePath)
187-
$output = certutil -csp $cspName -addstore $storePath $pfxFilePath 2>&1
186+
$output = certutil -f -csp $cspName -addstore $storePath $pfxFilePath 2>&1
188187
$exit_message = ""LASTEXITCODE:$($LASTEXITCODE)""
189188
190-
$stuff = certutil -dump
191-
if ($stuff.GetType().Name -eq ""String"")
189+
if ($output.GetType().Name -eq ""String"")
192190
{
193-
$stuff = @($stuff, $exit_message)
191+
$output = @($output, $exit_message)
194192
}
195193
else
196194
{
197-
$stuff += $exit_message
195+
$output += $exit_message
198196
}
199197
$output
200-
$stuff
201198
";
202199

203200
ps.AddScript(script);
@@ -208,21 +205,19 @@ public JobResult ImportPFXFile(string filePath, string privateKeyPassword, strin
208205
else
209206
{
210207
string script = @"
211-
param($pfxFilePath, $privateKeyPassword, $cspName)
212-
$output = certutil -importpfx -csp $cspName -p $privateKeyPassword $storePath $pfxFilePath 2>&1
208+
param($pfxFilePath, $privateKeyPassword, $cspName, $storePath)
209+
$output = certutil -f -importpfx -csp $cspName -p $privateKeyPassword $storePath $pfxFilePath 2>&1
213210
$exit_message = ""LASTEXITCODE:$($LASTEXITCODE)""
214211
215-
$stuff = certutil -dump
216-
if ($stuff.GetType().Name -eq ""String"")
212+
if ($output.GetType().Name -eq ""String"")
217213
{
218-
$stuff = @($stuff, $exit_message)
214+
$output = @($output, $exit_message)
219215
}
220216
else
221217
{
222-
$stuff += $exit_message
218+
$output += $exit_message
223219
}
224220
$output
225-
$stuff
226221
";
227222

228223
ps.AddScript(script);
@@ -244,9 +239,9 @@ public JobResult ImportPFXFile(string filePath, string privateKeyPassword, strin
244239
lastExitCode = GetLastExitCode(results[^1].ToString());
245240
_logger.LogTrace($"Last exit code: {lastExitCode}");
246241
}
247-
catch (Exception)
242+
catch (Exception ex)
248243
{
249-
_logger.LogTrace("Unable to get the last exit code.");
244+
_logger.LogTrace(ex.Message);
250245
}
251246

252247

IISU/ImplementedStoreTypes/Win/WinInventory.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,15 @@ namespace Keyfactor.Extensions.Orchestrator.WindowsCertStore.WinCert
2323
{
2424
internal class WinInventory : ClientPSCertStoreInventory
2525
{
26+
private ILogger _logger;
2627
public WinInventory(ILogger logger) : base(logger)
2728
{
29+
_logger = logger;
2830
}
2931

3032
public List<CurrentInventoryItem> GetInventoryItems(Runspace runSpace, string storePath)
3133
{
34+
_logger.LogTrace("Entering WinCert GetInventoryItems.");
3235
List<CurrentInventoryItem> inventoryItems = new List<CurrentInventoryItem>();
3336

3437
foreach (Certificate cert in base.GetCertificatesFromStore(runSpace, storePath))
@@ -50,6 +53,7 @@ public List<CurrentInventoryItem> GetInventoryItems(Runspace runSpace, string st
5053
});
5154
}
5255

56+
_logger.LogTrace($"Found {inventoryItems.Count} certificates. Exiting WinCert GetInventoryItems.");
5357
return inventoryItems;
5458
}
5559
}

IISU/ImplementedStoreTypes/WinIIS/Inventory.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,13 @@ private JobResult PerformInventory(InventoryJobConfiguration config, SubmitInven
7575
WinIISInventory IISInventory = new WinIISInventory(_logger);
7676
inventoryItems = IISInventory.GetInventoryItems(myRunspace, storePath);
7777

78-
_logger.LogTrace($"A total of {inventoryItems.Count} were found");
78+
_logger.LogTrace($"A total of {inventoryItems.Count} bound certificate(s) were found");
7979
_logger.LogTrace("Closing runspace...");
8080
myRunspace.Close();
8181

82-
_logger.LogTrace("Invoking Inventory..");
82+
_logger.LogTrace("Invoking submitInventory..");
8383
submitInventory.Invoke(inventoryItems);
84-
_logger.LogTrace($"Inventory Invoked... {inventoryItems.Count} Items");
84+
_logger.LogTrace($"submitInventory Invoked... {inventoryItems.Count} Items");
8585

8686
return new JobResult
8787
{

IISU/ImplementedStoreTypes/WinIIS/Management.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public JobResult ProcessJob(ManagementJobConfiguration config)
101101
{
102102
_logger.LogTrace(LogHandler.FlattenException(ex));
103103

104-
var failureMessage = $"Managemenmt job {config.OperationType} failed for Site '{config.CertificateStoreDetails.StorePath}' on server '{config.CertificateStoreDetails.ClientMachine}' with error: '{LogHandler.FlattenException(ex)}'";
104+
var failureMessage = $"Management job {config.OperationType} failed for Site '{config.CertificateStoreDetails.StorePath}' on server '{config.CertificateStoreDetails.ClientMachine}' with error: '{LogHandler.FlattenException(ex)}'";
105105
_logger.LogWarning(failureMessage);
106106

107107
return new JobResult

IISU/ImplementedStoreTypes/WinIIS/WinIISInventory.cs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,15 @@ namespace Keyfactor.Extensions.Orchestrator.WindowsCertStore.IISU
2727
{
2828
internal class WinIISInventory : ClientPSCertStoreInventory
2929
{
30+
private ILogger _logger;
3031
public WinIISInventory(ILogger logger) : base(logger)
3132
{
33+
_logger = logger;
3234
}
3335

3436
public List<CurrentInventoryItem> GetInventoryItems(Runspace runSpace, string storePath)
3537
{
38+
_logger.LogTrace("Entering IISU GetInventoryItems");
3639
// Get the raw certificate inventory from cert store
3740
List<Certificate> certificates = base.GetCertificatesFromStore(runSpace, storePath);
3841

@@ -51,22 +54,36 @@ public List<CurrentInventoryItem> GetInventoryItems(Runspace runSpace, string st
5154
}
5255
else
5356
{
54-
ps2.AddScript("Set-ExecutionPolicy RemoteSigned");
57+
ps2.AddScript("Set-ExecutionPolicy RemoteSigned -Scope Process -Force");
5558
ps2.AddScript("Import-Module WebAdministration");
56-
//var result = ps.Invoke();
5759
}
5860

5961
var searchScript = "Foreach($Site in get-website) { Foreach ($Bind in $Site.bindings.collection) {[pscustomobject]@{name=$Site.name;Protocol=$Bind.Protocol;Bindings=$Bind.BindingInformation;thumbprint=$Bind.certificateHash;sniFlg=$Bind.sslFlags}}}";
6062
ps2.AddScript(searchScript);
61-
var iisBindings = ps2.Invoke(); // Responsible for getting all bound certificates for each website
63+
64+
_logger.LogTrace($"Attempting to initiate the following script:\n{searchScript}");
65+
66+
var iisBindings = ps2.Invoke();
6267

6368
if (ps2.HadErrors)
6469
{
65-
var psError = ps2.Streams.Error.ReadAll().Aggregate(String.Empty, (current, error) => current + error.ErrorDetails.Message);
70+
_logger.LogTrace("The previous script encountered errors. See below for more info.");
71+
string psError = string.Empty;
72+
try
73+
{
74+
psError = ps2.Streams.Error.ReadAll().Aggregate(String.Empty, (current, error) => current + (error.ErrorDetails?.Message ?? error.Exception.ToString()));
75+
}
76+
catch
77+
{
78+
}
79+
80+
if (psError != null) { throw new Exception(psError); }
81+
6682
}
6783

6884
if (iisBindings.Count == 0)
6985
{
86+
_logger.LogTrace("No binding certificates were found. Exiting IISU GetInventoryItems.");
7087
return myBoundCerts;
7188
}
7289

@@ -123,6 +140,7 @@ public List<CurrentInventoryItem> GetInventoryItems(Runspace runSpace, string st
123140
}
124141
}
125142

143+
_logger.LogTrace($"Found {myBoundCerts.Count} bound certificates. Exiting IISU GetInventoryItems.");
126144
return myBoundCerts;
127145
}
128146
}

IISU/ImplementedStoreTypes/WinSQL/Management.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public JobResult ProcessJob(ManagementJobConfiguration config)
9696
{
9797
_logger.LogTrace(LogHandler.FlattenException(ex));
9898

99-
var failureMessage = $"Managemenmt job {config.OperationType} failed for Site '{config.CertificateStoreDetails.StorePath}' on server '{config.CertificateStoreDetails.ClientMachine}' with error: '{LogHandler.FlattenException(ex)}'";
99+
var failureMessage = $"Management job {config.OperationType} failed for Site '{config.CertificateStoreDetails.StorePath}' on server '{config.CertificateStoreDetails.ClientMachine}' with error: '{LogHandler.FlattenException(ex)}'";
100100
_logger.LogWarning(failureMessage);
101101

102102
return new JobResult

IISU/PSHelper.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public static Runspace GetClientPsRunspace(string winRmProtocol, string clientMa
3333
_logger.MethodEntry();
3434

3535
// 2.4 - Client Machine Name now follows the naming conventions of {clientMachineName}|{localMachine}
36-
// If the clientMachineName is just 'localhost', it will maintain that as locally only (as previosuly)
36+
// If the clientMachineName is just 'localhost', it will maintain that as locally only (as previously)
3737
// If there is no 2nd part to the clientMachineName, a remote PowerShell session will be created
3838

3939
// Break the clientMachineName into parts
@@ -43,14 +43,18 @@ public static Runspace GetClientPsRunspace(string winRmProtocol, string clientMa
4343
string machineName = parts.Length > 1 ? parts[0] : clientMachineName;
4444
string argument = parts.Length > 1 ? parts[1] : null;
4545

46-
// Determine if this is truely a local connection
46+
// Determine if this is truly a local connection
4747
bool isLocal = (machineName.ToLower() == "localhost") || (argument != null && argument.ToLower() == "localmachine");
4848

4949
_logger.LogInformation($"Full clientMachineName={clientMachineName} | machineName={machineName} | argument={argument} | isLocal={isLocal}");
5050

5151
if (isLocal)
5252
{
53-
return RunspaceFactory.CreateRunspace();
53+
//return RunspaceFactory.CreateRunspace();
54+
PowerShellProcessInstance instance = new PowerShellProcessInstance(new Version(5, 1), null, null, false);
55+
Runspace rs = RunspaceFactory.CreateOutOfProcessRunspace(new TypeTable(Array.Empty<string>()), instance);
56+
57+
return rs;
5458
}
5559
else
5660
{

IISU/WindowsCertStore.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
<ItemGroup>
3232
<PackageReference Include="Keyfactor.Logging" Version="1.1.1" />
3333
<PackageReference Include="Keyfactor.Orchestrators.IOrchestratorJobExtensions" Version="0.7.0" />
34-
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.2.12" />
34+
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.2.19" />
3535

3636
</ItemGroup>
3737

0 commit comments

Comments
 (0)