Skip to content

Commit 9322519

Browse files
committed
Remove Inventory & Mgmt Dependence on Web.Admin
1 parent b9b8275 commit 9322519

File tree

13 files changed

+306
-132
lines changed

13 files changed

+306
-132
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
1.0.2
2+
* Remove dependnce on Windows.Web.Administration on the orchestrator server. The agent will now use the local version on the managed server via remote powershell
3+
* add support for the IncludePortInSPN flag
4+
* add support to use credentials from Keyfactor for Add/Remove/Inventory jobs.

IISWithBindings/Constants.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Keyfactor.Extensions.Orchestrator.IISWithBinding
88
{
99
static class IISWithBinding2Constants
1010
{
11-
public const string STORE_TYPE_NAME = "IISBind2";
11+
public const string STORE_TYPE_NAME = "IISBinding";
1212
}
1313

1414
static class JobTypes

IISWithBindings/IISWithBindings.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
77
<ProjectGuid>{F57D07DB-613D-4837-B709-6E943CD4BA10}</ProjectGuid>
88
<OutputType>Library</OutputType>
9-
<RootNamespace>IISDemo</RootNamespace>
9+
<RootNamespace>Keyfactor.Extensions.Orchestrator.IISWithBinding</RootNamespace>
1010
<AssemblyName>IISWithBindings</AssemblyName>
1111
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
1212
<FileAlignment>512</FileAlignment>
@@ -48,9 +48,6 @@
4848
<Reference Include="Keyfactor.Platform.Extensions.Agents, Version=1.0.1.0, Culture=neutral, PublicKeyToken=0ed89d330114ab09, processorArchitecture=MSIL">
4949
<HintPath>..\packages\Keyfactor.Platform.Extensions.Agents.1.0.1\lib\net462\Keyfactor.Platform.Extensions.Agents.dll</HintPath>
5050
</Reference>
51-
<Reference Include="Microsoft.Web.Administration, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
52-
<HintPath>..\packages\Microsoft.Web.Administration.11.1.0\lib\netstandard1.5\Microsoft.Web.Administration.dll</HintPath>
53-
</Reference>
5451
<Reference Include="Microsoft.Win32.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
5552
<HintPath>..\packages\Microsoft.Win32.Primitives.4.0.1\lib\net46\Microsoft.Win32.Primitives.dll</HintPath>
5653
<Private>True</Private>
@@ -220,7 +217,10 @@
220217
<Compile Include="Jobs\AgentJob.cs" />
221218
<Compile Include="Jobs\Inventory.cs" />
222219
<Compile Include="Jobs\Management.cs" />
220+
<Compile Include="PowerShellCertStore.cs" />
223221
<Compile Include="Properties\AssemblyInfo.cs" />
222+
<Compile Include="PSCertificate.cs" />
223+
<Compile Include="PSCertStoreException.cs" />
224224
<Compile Include="StorePath.cs" />
225225
</ItemGroup>
226226
<ItemGroup>

IISWithBindings/Jobs/Inventory.cs

Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
using Keyfactor.Platform.Extensions.Agents;
1+

2+
using Keyfactor.Platform.Extensions.Agents;
23
using Keyfactor.Platform.Extensions.Agents.Delegates;
34
using Keyfactor.Platform.Extensions.Agents.Enums;
45
using Keyfactor.Platform.Extensions.Agents.Interfaces;
5-
using Microsoft.Web.Administration;
66
using Newtonsoft.Json;
77
using System;
88
using System.Collections.Generic;
9-
using System.Linq;
10-
using System.Security.Cryptography.X509Certificates;
11-
using System.Text;
12-
using System.Threading.Tasks;
9+
using System.Management.Automation;
10+
using System.Management.Automation.Runspaces;
11+
using System.Net;
12+
using System.Security;
1313

1414
namespace Keyfactor.Extensions.Orchestrator.IISWithBinding
1515
{
@@ -23,76 +23,87 @@ public override AnyJobCompleteInfo processJob(AnyJobConfigInfo config, SubmitInv
2323

2424
private AnyJobCompleteInfo PerformInventory(AnyJobConfigInfo config,SubmitInventoryUpdate submitInventory)
2525
{
26-
dynamic properties = JsonConvert.DeserializeObject(config.Store.Properties.ToString());
27-
StorePath storePath = new StorePath(properties.siteName.Value, properties.ipAddress.Value, properties.port.Value, properties.hostName.Value);
28-
29-
List<AgentCertStoreInventoryItem> inventoryItems = new List<AgentCertStoreInventoryItem>();
26+
try
27+
{
28+
StorePath storePath = JsonConvert.DeserializeObject<StorePath>(config.Store.Properties.ToString(), new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Populate });
29+
List<AgentCertStoreInventoryItem> inventoryItems = new List<AgentCertStoreInventoryItem>();
3030

31-
Logger.Trace($"Begin Inventory for Cert Store {$@"\\{config.Store.ClientMachine}\{config.Store.StorePath}"}");
31+
Logger.Trace($"Begin Inventory for Cert Store {$@"\\{config.Store.ClientMachine}\{config.Store.StorePath}"}");
3232

33-
using (X509Store certStore = new X509Store($@"\\{config.Store.ClientMachine}\{config.Store.StorePath}", StoreLocation.LocalMachine))
34-
{
35-
try
36-
{
37-
certStore.Open(OpenFlags.MaxAllowed);
38-
}
39-
catch (System.Security.Cryptography.CryptographicException ex)
40-
{
41-
Logger.Trace(ex);
42-
return new AnyJobCompleteInfo() { Status = 4, Message = $"Site {config.Store.StorePath} on server {config.Store.ClientMachine}: {ex.Message}" };
43-
}
33+
WSManConnectionInfo connInfo = new WSManConnectionInfo(new Uri($"http://{config.Store.ClientMachine}:5985/wsman"));
34+
connInfo.IncludePortInSPN = storePath.SPNPortFlag;
35+
SecureString pw = new NetworkCredential(config.Server.Username, config.Server.Password).SecurePassword;
36+
connInfo.Credential = new PSCredential(config.Server.Username, pw);
4437

45-
using (ServerManager serverManager = ServerManager.OpenRemote(config.Store.ClientMachine))
38+
using (Runspace runspace = RunspaceFactory.CreateRunspace(connInfo))
4639
{
47-
try
40+
runspace.Open();
41+
PowerShellCertStore psCertStore = new PowerShellCertStore(config.Store.ClientMachine, config.Store.StorePath, runspace);
42+
using (PowerShell ps = PowerShell.Create())
4843
{
49-
Site site = serverManager.Sites[storePath.SiteName];
50-
if (site == null)
51-
{
52-
return new AnyJobCompleteInfo() { Status = 4, Message = $"Site {config.Store.StorePath} on server {config.Store.ClientMachine} not found." };
44+
ps.Runspace = runspace;
45+
46+
ps.AddCommand("Import-Module")
47+
.AddParameter("Name", "WebAdministration")
48+
.AddStatement();
49+
ps.AddCommand("Get-WebBinding")
50+
.AddParameter("Name", storePath.SiteName)
51+
.AddParameter("Protocol", storePath.Protocol)
52+
.AddParameter("Port", storePath.Port)
53+
.AddParameter("HostHeader", storePath.HostName)
54+
.AddStatement();
55+
56+
var iisBindings = ps.Invoke();
57+
58+
if (ps.HadErrors) {
59+
return new AnyJobCompleteInfo() { Status = 4, Message = $"Inventory for Site {storePath.SiteName} on server {config.Store.ClientMachine} failed." };
5360
}
5461

55-
foreach (Binding binding in site.Bindings.Where(p => p.Protocol.Equals("https", StringComparison.CurrentCultureIgnoreCase) &&
56-
p.BindingInformation.Equals(storePath.FormatForIIS(), StringComparison.CurrentCultureIgnoreCase)).ToList())
57-
{
58-
string thumbPrint = binding.GetAttributeValue("CertificateHash").ToString();
62+
if (iisBindings.Count == 0){
63+
submitInventory.Invoke(inventoryItems);
64+
return new AnyJobCompleteInfo() { Status = 3, Message = $"{storePath.Protocol} binding for Site {storePath.SiteName} on server {config.Store.ClientMachine} not found." };
65+
}
5966

67+
//in theory should only be one, but keeping for future update to chance inventory
68+
foreach (var binding in iisBindings)
69+
{
70+
var thumbPrint = $"{(binding.Properties["certificateHash"]?.Value)}";
6071
if (string.IsNullOrEmpty(thumbPrint))
6172
continue;
6273

63-
X509Certificate2Collection x509Certs = certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbPrint, true);
64-
if (x509Certs.Count == 0)
74+
var foundCert = psCertStore.Certificates.Find(m => m.Thumbprint.Equals(thumbPrint));
75+
76+
if (foundCert == null)
6577
continue;
6678

6779
inventoryItems.Add(
6880
new AgentCertStoreInventoryItem()
6981
{
70-
Certificates = new string[] { Convert.ToBase64String(x509Certs[0].RawData) },
82+
Certificates = new string[] { foundCert.CertificateData },
7183
Alias = thumbPrint,
72-
PrivateKeyEntry = x509Certs[0].HasPrivateKey,
84+
PrivateKeyEntry = foundCert.HasPrivateKey,
7385
UseChainLevel = false,
7486
ItemStatus = AgentInventoryItemStatus.Unknown
7587
}
7688
);
7789
}
7890
}
79-
catch (Exception ex)
80-
{
81-
Logger.Trace(ex);
82-
return new AnyJobCompleteInfo() { Status = 4, Message = $"Site {config.Store.StorePath} on server {config.Store.ClientMachine}: {ex.Message}" };
83-
}
91+
runspace.Close();
8492
}
85-
}
8693

87-
try
88-
{
8994
submitInventory.Invoke(inventoryItems);
9095
return new AnyJobCompleteInfo() { Status = 2, Message = "Successful" };
9196
}
97+
catch (PSCertStoreException psEx)
98+
{
99+
Logger.Trace(psEx);
100+
return new AnyJobCompleteInfo() { Status = 4, Message = $"Unable to open remote certificate store: {psEx.Message}" };
101+
}
92102
catch (Exception ex)
93103
{
94104
Logger.Trace(ex);
95105
return new AnyJobCompleteInfo() { Status = 4, Message = $"Site {config.Store.StorePath} on server {config.Store.ClientMachine}: {ex.Message}" };
106+
96107
}
97108
}
98109
}

0 commit comments

Comments
 (0)