diff --git a/CitrixAdcOrchestratorJobExtension/CitrixAdcStore.cs b/CitrixAdcOrchestratorJobExtension/CitrixAdcStore.cs index 6381775..f8ce10e 100644 --- a/CitrixAdcOrchestratorJobExtension/CitrixAdcStore.cs +++ b/CitrixAdcOrchestratorJobExtension/CitrixAdcStore.cs @@ -15,6 +15,7 @@ using System; using System.IO; using System.Linq; +using System.Collections.Generic; using System.Runtime.ConstrainedExecution; using System.Security.Cryptography.X509Certificates; using System.Text; @@ -551,43 +552,23 @@ public void UpdateBindings(string keyPairName, string virtualServerName, string public void LinkToIssuer(string cert, string privateKeyPassword, string keyPairName) { - int pageSize = 50; - sslcertkey certKey = sslcertkey.get(_nss, keyPairName); - - filtervalue[] filters = new filtervalue[0]; - filters[0] = new filtervalue("certificatetype", "ROOT_CERT|INTM_CERT"); - int caTotal = Convert.ToInt32(sslcertkey.count_filtered(_nss, filters)); - if (caTotal == 0) - throw new Exception("No CA certificates were found in Netscaler instance. Certificate successfully added but not linked to its issuer."); - - int pageCount = (caTotal / pageSize) + 1; - options o = new options(); - o.set_pagesize(50); - - X509Certificate2 x509Cert = new X509Certificate2(Encoding.ASCII.GetBytes(cert)); - bool certFound = false; - for (int i = 1; i <= pageCount; i++) + sslcertificatechain chain = sslcertificatechain.get(_nss, keyPairName); + if (chain.chaincomplete == 1) { - if (certFound) - break; - o.set_pageno(i); - sslcertkey[] caCerts = sslcertkey.get_filtered(_nss, filters); - - foreach(sslcertkey caCert in caCerts) - { - if (caCert.subject == x509Cert.Issuer) - { - certKey.linkcertkeyname = caCert.certkey; - certFound = true; - break; - } - } + Logger.LogDebug($"Certificate {keyPairName} already linked to {chain.chainlinked}"); + return; } - if (certFound) - sslcertkey.link(_nss, certKey); - else - throw new Exception("No issuing CA certificate was found for the added certificate. Certificate successfully added but not linked to its issuer.") + if (chain.chainpossiblelinks == null || string.IsNullOrEmpty(chain.chainpossiblelinks[0]) || chain.chainpossiblelinks.Length == 0) + { + string msg = $"Certificate added, but link not performed. No Issuing CA Certificate exists for {keyPairName}."; + Logger.LogWarning(msg); + throw new LinkException(msg); + } + + sslcertkey certKey = sslcertkey.get(_nss, keyPairName); + certKey.linkcertkeyname = chain.chainpossiblelinks[0]; + sslcertkey.link(_nss, certKey); } private (byte[], byte[]) GetPemFromPfx(byte[] pfxBytes, char[] pfxPassword) @@ -893,4 +874,9 @@ public void SaveConfiguration() } } } + + public class LinkException : Exception + { + public LinkException(string message) : base(message) { } + } } \ No newline at end of file diff --git a/CitrixAdcOrchestratorJobExtension/Inventory.cs b/CitrixAdcOrchestratorJobExtension/Inventory.cs index 669dd86..dbbb975 100644 --- a/CitrixAdcOrchestratorJobExtension/Inventory.cs +++ b/CitrixAdcOrchestratorJobExtension/Inventory.cs @@ -85,12 +85,12 @@ private JobResult ProcessJob(CitrixAdcStore store, InventoryJobConfiguration job _logger.LogDebug("Getting file list..."); var files = store.ListFiles(); - Dictionary existing = jobConfiguration.LastInventory.ToDictionary(i => i.Alias, i => i.Thumbprints.First()); + ///////Dictionary existing = jobConfiguration.LastInventory.ToDictionary(i => i.Alias, i => i.Thumbprints.First()); // ReSharper disable once CollectionNeverQueried.Local HashSet processedAliases = new HashSet(); //union the remote keys + last Inventory - List contentsToCheck = files?.Select(x => x.filename).Union(existing.Keys).ToList() ?? new List(); + List contentsToCheck = files?.Select(x => x.filename).ToList() ?? new List(); _logger.LogDebug("Getting KeyPair list..."); var keyPairList = store.ListKeyPairs(); diff --git a/CitrixAdcOrchestratorJobExtension/Management.cs b/CitrixAdcOrchestratorJobExtension/Management.cs index 3b902f0..f0f9d14 100644 --- a/CitrixAdcOrchestratorJobExtension/Management.cs +++ b/CitrixAdcOrchestratorJobExtension/Management.cs @@ -20,6 +20,8 @@ using Microsoft.Extensions.Logging; using Newtonsoft.Json; using System.IO; +using static Org.BouncyCastle.Math.EC.ECCurve; +using com.citrix.netscaler.nitro.resource.config.pq; namespace Keyfactor.Extensions.Orchestrator.CitricAdc { @@ -141,9 +143,9 @@ private JobResult ProcessJob(CitrixAdcStore store, ManagementJobConfiguration jo _logger.LogDebug("Begin Add..."); var virtualServerName = (string)jobConfiguration.JobProperties["virtualServerName"]; var sniCert = (string)jobConfiguration.JobProperties["sniCert"]; - var linkToIssuer = false; - if (jobConfiguration.JobProperties.ContainsKey("linkToIssuer")) - linkToIssuer = (bool)jobConfiguration.JobProperties["linkToIssuer"]; + + dynamic properties = JsonConvert.DeserializeObject(jobConfiguration.CertificateStoreDetails.Properties.ToString()); + var linkToIssuer = properties.linkToIssuer == null || string.IsNullOrEmpty(properties.linkToIssuer.Value) ? false : Convert.ToBoolean(properties.linkToIssuer.Value); //Check if Keypair name exists, if so, we need to append something to it so we don't get downtime var keyPairName = jobConfiguration.JobCertificate.Alias; @@ -186,14 +188,26 @@ private JobResult ProcessJob(CitrixAdcStore store, ManagementJobConfiguration jo if (x?.Thumbprint == _thumbprint) { _logger.LogTrace($"Thumbprint Match: {_thumbprint}"); - foreach (var sBinding in binding.sslcertkey_sslvserver_binding) + if (binding.sslcertkey_sslvserver_binding == null) { _logger.LogTrace( - $"Starting PerformAdd Binding Name: {sBinding.servername} kp.certkey: {kp.certkey}"); + $"Starting PerformAdd Binding kp.certkey: {kp.certkey}"); PerformAdd(store, jobConfiguration.JobCertificate, kp.certkey, - sBinding.servername, true,sniCert, linkToIssuer); + virtualServerName, true, sniCert, linkToIssuer); _logger.LogTrace( - $"Finished PerformAdd Binding Name: {sBinding.servername} kp.certkey: {kp.certkey}"); + $"Finished PerformAdd kp.certkey: {kp.certkey}"); + } + else + { + foreach (var sBinding in binding.sslcertkey_sslvserver_binding) + { + _logger.LogTrace( + $"Starting PerformAdd Binding Name: {sBinding.servername} kp.certkey: {kp.certkey}"); + PerformAdd(store, jobConfiguration.JobCertificate, kp.certkey, + sBinding.servername, true, sniCert, linkToIssuer); + _logger.LogTrace( + $"Finished PerformAdd Binding Name: {sBinding.servername} kp.certkey: {kp.certkey}"); + } } } } @@ -231,6 +245,16 @@ private JobResult ProcessJob(CitrixAdcStore store, ManagementJobConfiguration jo }; } } + catch (LinkException ex) + { + //Status: 2=Success, 3=Warning, 4=Error + return new JobResult + { + Result = OrchestratorJobStatusJobResult.Warning, + JobHistoryId = jobConfiguration.JobHistoryId, + FailureMessage = ex.Message + }; + } catch (Exception ex) { //Status: 2=Success, 3=Warning, 4=Error