Beispiel #1
0
        public void LoadSettings()
        {
            string appDataPath = Util.GetAppDataFolder();
            var    path        = appDataPath + "\\" + ITEMMANAGERCONFIG;

            if (System.IO.File.Exists(path))
            {
                lock (ITEMMANAGERCONFIG)
                {
                    string configData = System.IO.File.ReadAllText(path);
                    this.ManagedSites = Newtonsoft.Json.JsonConvert.DeserializeObject <List <ManagedSite> >(configData);

                    //foreach managed site enable change notification for edits to domainoptions
                    foreach (var s in this.ManagedSites)
                    {
                        foreach (var d in s.DomainOptions)
                        {
                            d.PropertyChanged += s.DomainOption_PropertyChanged;
                            d.IsChanged        = false;
                        }
                    }
                }
            }
            else
            {
                this.ManagedSites = new List <ManagedSite>();
            }

            foreach (var s in this.ManagedSites)
            {
                s.IsChanged = false;
            }
        }
Beispiel #2
0
        private async Task UpgradeSettings()
        {
            var appDataPath = Util.GetAppDataFolder(_storageSubFolder);

            var json = Path.Combine(appDataPath, $"{ITEMMANAGERCONFIG}.json");
            var db   = Path.Combine(appDataPath, $"{ITEMMANAGERCONFIG}.db");

            if (File.Exists(json) && !File.Exists(db))
            {
                var watch = Stopwatch.StartNew();

                // read managed sites using tokenize stream, this is useful for large files
                var serializer = new JsonSerializer();
                using (var sr = new StreamReader(json))
                    using (var reader = new JsonTextReader(sr))
                    {
                        var managedCertificateList = serializer.Deserialize <List <ManagedCertificate> >(reader);

                        //safety check, if any dupe id's exists (which they shouldn't but the test data set did) make Id unique in the set.
                        var duplicateKeys = managedCertificateList.GroupBy(x => x.Id).Where(group => group.Count() > 1).Select(group => group.Key);
                        foreach (var dupeKey in duplicateKeys)
                        {
                            var count = 0;
                            foreach (var i in managedCertificateList.Where(m => m.Id == dupeKey))
                            {
                                i.Id = i.Id + "_" + count;
                                count++;
                            }
                        }

                        // update cache
                        _managedCertificatesCache.Clear();

                        foreach (var site in managedCertificateList)
                        {
                            site.IsChanged = false;
                            _managedCertificatesCache.AddOrUpdate(site.Id, site, (key, oldValue) => site);
                        }
                    }

                await StoreAllManagedItems(); // upgrade to SQLite db storage

                File.Delete($"{json}.bak");
                File.Move(json, $"{json}.bak");
                Debug.WriteLine($"UpgradeSettings[Json->SQLite] took {watch.ElapsedMilliseconds}ms for {_managedCertificatesCache.Count} records");
            }
            else
            {
                if (!File.Exists(db))
                {
                    // no setting to upgrade, create the empty database
                    await StoreAllManagedItems();
                }
                else
                {
                    // apply schema upgrades
                    await UpgradeSchema();
                }
            }
        }
Beispiel #3
0
        public static void LoadAppSettings()
        {
            string appDataPath = Util.GetAppDataFolder();
            var    path        = appDataPath + "\\" + COREAPPSETTINGSFILE;

            if (System.IO.File.Exists(path))
            {
                lock (COREAPPSETTINGSFILE)
                {
                    string configData = System.IO.File.ReadAllText(path);
                    CoreAppSettings.Current = Newtonsoft.Json.JsonConvert.DeserializeObject <CoreAppSettings>(configData);
                }
            }
            else
            {
                // no core app settings yet, migrate from old settings
                Certify.Properties.Settings.Default.Reload();
                var oldProps = Certify.Properties.Settings.Default;
                CoreAppSettings.Current.CheckForUpdatesAtStartup  = oldProps.CheckForUpdatesAtStartup;
                CoreAppSettings.Current.EnableAppTelematics       = oldProps.EnableAppTelematics;
                CoreAppSettings.Current.EnableDNSValidationChecks = oldProps.EnableDNSValidationChecks;
                CoreAppSettings.Current.EnableEFS = oldProps.EnableEFS;
                CoreAppSettings.Current.EnableValidationProxyAPI = oldProps.EnableValidationProxyAPI;
                CoreAppSettings.Current.IgnoreStoppedSites       = oldProps.ShowOnlyStartedWebsites;
                CoreAppSettings.Current.RenewalIntervalDays      = oldProps.RenewalIntervalDays;
                CoreAppSettings.Current.MaxRenewalRequests       = oldProps.MaxRenewalRequests;
                CoreAppSettings.Current.VaultPath = oldProps.VaultPath;

                CoreAppSettings.Current.LegacySettingsUpgraded = true;
                SaveAppSettings();
            }
        }
Beispiel #4
0
        public static void LoadAppSettings()
        {
            string appDataPath = Util.GetAppDataFolder();
            var    path        = appDataPath + "\\" + COREAPPSETTINGSFILE;

            if (System.IO.File.Exists(path))
            {
                //ensure permissions

                //load content
                lock (COREAPPSETTINGSFILE)
                {
                    string configData = System.IO.File.ReadAllText(path);
                    CoreAppSettings.Current = Newtonsoft.Json.JsonConvert.DeserializeObject <CoreAppSettings>(configData);
                }
            }
            else
            {
                // no core app settings yet

                CoreAppSettings.Current.LegacySettingsUpgraded = true;
                CoreAppSettings.Current.IsInstanceRegistered   = false;
                CoreAppSettings.Current.Language = null;

                CoreAppSettings.Current.InstanceId = Guid.NewGuid().ToString();
                SaveAppSettings();
            }

            // if instance id not yet set, create it now and save
            if (String.IsNullOrEmpty(CoreAppSettings.Current.InstanceId))
            {
                CoreAppSettings.Current.InstanceId = Guid.NewGuid().ToString();
                SaveAppSettings();
            }
        }
Beispiel #5
0
        public void StoreSettings()
        {
            string appDataPath = Util.GetAppDataFolder();

            //string siteManagerConfig = Newtonsoft.Json.JsonConvert.SerializeObject(this.ManagedSites, Newtonsoft.Json.Formatting.Indented);

            lock (ITEMMANAGERCONFIG)
            {
                var path = Path.Combine(new string[] { appDataPath, StorageSubfolder, ITEMMANAGERCONFIG });

                //backup settings file
                if (File.Exists(path))
                {
                    // delete old settings backup if present
                    if (File.Exists(path + ".bak"))
                    {
                        System.IO.File.Delete(path + ".bak");
                    }

                    // backup settings
                    System.IO.File.Move(path, path + ".bak");
                }

                // serialize JSON directly to a file
                using (StreamWriter file = File.CreateText(path))
                {
                    JsonSerializer serializer = new JsonSerializer();
                    serializer.Serialize(file, this.ManagedSites);
                }
            }

            // reset IsChanged as all items have been persisted
            ManagedSites.ForEach(s => s.IsChanged = false);
        }
Beispiel #6
0
        /// <summary>
        /// Get the current service log (per line)
        /// </summary>
        /// <param name="type"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public async Task <string[]> GetLog(string type, int limit)
        {
            string logPath = null;

            if (type == "session")
            {
                logPath = Path.Combine(Util.GetAppDataFolder("logs"), "session.log");
            }

            if (logPath != null && System.IO.File.Exists(logPath))
            {
                try
                {
                    // TODO: use reverse stream reader for large files

                    // get last n rows in date order
                    var log = System.IO.File.ReadAllLines(logPath)
                              .Reverse()
                              .Take(limit)
                              .Reverse()
                              .ToArray();

                    return(await Task.FromResult(log));
                }
                catch (Exception exp)
                {
                    return(new string[] { $"Failed to read log: {exp}" });
                }
            }
            else
            {
                return(new string[] { "" });
            }
        }
Beispiel #7
0
        public void StoreSettings()
        {
            var    watch       = Stopwatch.StartNew();
            string appDataPath = Util.GetAppDataFolder(StorageSubfolder);

            lock (ITEMMANAGERCONFIG)
            {
                var path = Path.Combine(appDataPath, $"{ITEMMANAGERCONFIG}.db");

                //backup settings file
                if (!File.Exists(path))
                {
                    SQLiteConnection.CreateFile(path);
                    using (var target = new SQLiteConnection($"Data Source={path}"))
                    {
                        target.Open();
                        using (var cmd = new SQLiteCommand("CREATE TABLE managedsettings (id TEXT NOT NULL UNIQUE PRIMARY KEY, json TEXT NOT NULL)", target))
                        {
                            cmd.ExecuteNonQuery();
                        }
                    }
                }

                // save modified items into settings database
                using (var target = new SQLiteConnection($"Data Source={path}"))
                {
                    target.Open();
                    using (var tran = target.BeginTransaction())
                    {
                        foreach (var deleted in ManagedSites.Values.Where(s => s.Deleted).ToList())
                        {
                            using (var cmd = new SQLiteCommand("DELETE FROM managedsettings WHERE id=@id", target))
                            {
                                cmd.Parameters.Add(new SQLiteParameter("@id", deleted.Id));
                                cmd.ExecuteNonQuery();
                            }
                            ManagedSites.Remove(deleted.Id);
                        }
                        foreach (var changed in ManagedSites.Values.Where(s => s.IsChanged))
                        {
                            using (var cmd = new SQLiteCommand("INSERT OR REPLACE INTO managedsettings (id,json) VALUES (@id,@json)", target))
                            {
                                cmd.Parameters.Add(new SQLiteParameter("@id", changed.Id));
                                cmd.Parameters.Add(new SQLiteParameter("@json", JsonConvert.SerializeObject(changed)));
                                cmd.ExecuteNonQuery();
                            }
                            changed.IsChanged = false;
                        }
                        tran.Commit();
                    }
                }
            }

            // reset IsChanged as all items have been persisted
            Debug.WriteLine($"StoreSettings[Sqlite] took {watch.ElapsedMilliseconds}ms for {ManagedSites.Count} records");
        }
Beispiel #8
0
        public void StoreSettings()
        {
            string appDataPath       = Util.GetAppDataFolder();
            string siteManagerConfig = Newtonsoft.Json.JsonConvert.SerializeObject(this.ManagedSites, Newtonsoft.Json.Formatting.Indented);

            lock (ITEMMANAGERCONFIG)
            {
                System.IO.File.WriteAllText(appDataPath + "\\" + ITEMMANAGERCONFIG, siteManagerConfig);
            }
        }
Beispiel #9
0
        public static void SaveAppSettings()
        {
            string appDataPath = Util.GetAppDataFolder();
            string json        = Newtonsoft.Json.JsonConvert.SerializeObject(CoreAppSettings.Current, Newtonsoft.Json.Formatting.Indented);

            lock (COREAPPSETTINGSFILE)
            {
                System.IO.File.WriteAllText(appDataPath + "\\" + COREAPPSETTINGSFILE, json);
            }
        }
Beispiel #10
0
        public static void LoadAppSettings()
        {
            string appDataPath = Util.GetAppDataFolder();
            var    path        = appDataPath + "\\" + COREAPPSETTINGSFILE;

            if (System.IO.File.Exists(path))
            {
                //ensure permissions

                //load content
                lock (COREAPPSETTINGSFILE)
                {
                    string configData = System.IO.File.ReadAllText(path);
                    CoreAppSettings.Current = Newtonsoft.Json.JsonConvert.DeserializeObject <CoreAppSettings>(configData);
                }
            }
            else
            {
                // no core app settings yet, migrate from old settings
                //Certify.Properties.Settings.Default.Reload();
                //var oldProps = Certify.Properties.Settings.Default;

                /* CoreAppSettings.Current.CheckForUpdatesAtStartup = oldProps.CheckForUpdatesAtStartup;
                 * CoreAppSettings.Current.EnableAppTelematics = oldProps.EnableAppTelematics;
                 * CoreAppSettings.Current.EnableDNSValidationChecks = oldProps.EnableDNSValidationChecks;
                 * CoreAppSettings.Current.EnableEFS = oldProps.EnableEFS;
                 * CoreAppSettings.Current.EnableValidationProxyAPI = oldProps.EnableValidationProxyAPI;
                 * CoreAppSettings.Current.IgnoreStoppedSites = oldProps.ShowOnlyStartedWebsites;
                 * CoreAppSettings.Current.RenewalIntervalDays = oldProps.RenewalIntervalDays;
                 * CoreAppSettings.Current.MaxRenewalRequests = oldProps.MaxRenewalRequests;
                 * CoreAppSettings.Current.VaultPath = oldProps.VaultPath;*/

                CoreAppSettings.Current.LegacySettingsUpgraded = true;
                CoreAppSettings.Current.IsInstanceRegistered   = false;
                CoreAppSettings.Current.Language = null;
                CoreAppSettings.Current.UseBackgroundServiceAutoRenewal = true;

                CoreAppSettings.Current.InstanceId = Guid.NewGuid().ToString();
                SaveAppSettings();
            }

            // if instance id not yet set, create it now and save
            if (String.IsNullOrEmpty(CoreAppSettings.Current.InstanceId))
            {
                CoreAppSettings.Current.InstanceId = Guid.NewGuid().ToString();
                SaveAppSettings();
            }
        }
Beispiel #11
0
        private void InitLogging(Shared.ServiceConfig serverConfig)
        {
            _loggingLevelSwitch = new Serilog.Core.LoggingLevelSwitch(Serilog.Events.LogEventLevel.Information);

            SetLoggingLevel(serverConfig?.LogLevel);

            _serviceLog = new Loggy(
                new LoggerConfiguration()
                .MinimumLevel.ControlledBy(_loggingLevelSwitch)
                .WriteTo.Debug()
                .WriteTo.File(Path.Combine(Util.GetAppDataFolder("logs"), "session.log"), shared: true, flushToDiskInterval: new TimeSpan(0, 0, 10), rollOnFileSizeLimit: true, fileSizeLimitBytes: 5 * 1024 * 1024)
                .CreateLogger()
                );

            _serviceLog?.Information($"Logging started: {_loggingLevelSwitch.MinimumLevel}");
        }
Beispiel #12
0
        public static void LoadAppSettings()
        {
            try
            {
                var appDataPath = Util.GetAppDataFolder();
                var path        = Path.Combine(appDataPath, COREAPPSETTINGSFILE);

                if (System.IO.File.Exists(path))
                {
                    //ensure permissions

                    //load content
                    lock (COREAPPSETTINGSFILE)
                    {
                        var configData = System.IO.File.ReadAllText(path);
                        CoreAppSettings.Current = Newtonsoft.Json.JsonConvert.DeserializeObject <CoreAppSettings>(configData);

                        // init new settings if not set
                        if (CoreAppSettings.Current.CertificateCleanupMode == null)
                        {
                            CoreAppSettings.Current.CertificateCleanupMode = CertificateCleanupMode.AfterExpiry;
                        }
                    }
                }
                else
                {
                    // no core app settings yet

                    ApplyDefaults();
                    SaveAppSettings();
                }

                // if instance id not yet set, create it now and save
                if (string.IsNullOrEmpty(CoreAppSettings.Current.InstanceId))
                {
                    CoreAppSettings.Current.InstanceId = Guid.NewGuid().ToString();
                    SaveAppSettings();
                }
            }
            catch (Exception)
            {
                // failed to load app settings, settings may be corrupt or user may not have permission to read or write
                // use defaults, but don't save

                ApplyDefaults();
            }
        }
Beispiel #13
0
        public CertifyManager()
        {
            _serviceLog = new Loggy(
                new LoggerConfiguration()
                .MinimumLevel.Verbose()
                .WriteTo.Debug()
                .WriteTo.File(Util.GetAppDataFolder("logs") + "\\sessionlog.txt", shared: true, flushToDiskInterval: new TimeSpan(0, 0, 10))
                .CreateLogger()
                );

            Util.SetSupportedTLSVersions();

            _itemManager    = new ItemManager();
            _serverProvider = (ICertifiedServer) new ServerProviderIIS();

            _progressResults = new ObservableCollection <RequestProgressState>();

            _pluginManager = new PluginManager();
            _pluginManager.LoadPlugins();

            // TODO: convert providers to plugins
            var certes = new Certify.Providers.Certes.CertesACMEProvider(Management.Util.GetAppDataFolder() + "\\certes");

            _acmeClientProvider = certes;
            _vaultProvider      = certes;

            // init remaining utilities and optionally enable telematics
            _challengeDiagnostics = new ChallengeDiagnostics(CoreAppSettings.Current.EnableValidationProxyAPI);

            if (CoreAppSettings.Current.EnableAppTelematics)
            {
                _tc = new Util().InitTelemetry();
            }

            PerformUpgrades();

            var serverConfig = Util.GetAppServiceConfig();

            _httpChallengePort = serverConfig.HttpChallengeServerPort;
            _httpChallengeServerClient.Timeout = new TimeSpan(0, 0, 5);

            if (_tc != null)
            {
                _tc.TrackEvent("ServiceStarted");
            }
        }
Beispiel #14
0
        public static bool SaveCustomCertificateAuthorities(List <CertificateAuthority> caList)
        {
            var appDataPath = Util.GetAppDataFolder();
            var path        = Path.Combine(appDataPath, "ca.json");

            try
            {
                var json = Newtonsoft.Json.JsonConvert.SerializeObject(caList, Newtonsoft.Json.Formatting.Indented);
                System.IO.File.WriteAllText(path, json);
                return(true);
            }
            catch (Exception exp)
            {
                // Failed to save custom certificate authorities
                return(false);
            }
        }
Beispiel #15
0
        public void LoadSettings()
        {
            // FIXME: this method should be async and called only when absolutely required, these
            //        files can be hundreds of megabytes
            string appDataPath = Util.GetAppDataFolder();
            var    path        = Path.Combine(new string[] { appDataPath, StorageSubfolder, ITEMMANAGERCONFIG });

            if (System.IO.File.Exists(path))
            {
                lock (ITEMMANAGERCONFIG)
                {
                    // string configData = System.IO.File.ReadAllText(path); this.ManagedSites = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ManagedSite>>(configData);

                    ManagedSites = new List <ManagedSite>();

                    // read managed sites using tokenize stream, this is useful for large files
                    using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
                    {
                        using (StreamReader sr = new StreamReader(fs))
                        {
                            using (JsonTextReader reader = new JsonTextReader(sr))
                            {
                                while (reader.Read())
                                {
                                    if (reader.TokenType == JsonToken.StartObject)
                                    {
                                        // Load each Managed Site from the stream into memory
                                        ManagedSites.Add(JObject.Load(reader).ToObject <ManagedSite>());
                                    }
                                }
                            }
                        }
                    }

                    // reset IsChanged for all loaded settings
                    ManagedSites.ForEach(s => s.IsChanged = false);
                }
            }
            else
            {
                ManagedSites = new List <ManagedSite>();
            }
        }
Beispiel #16
0
        public static List <CertificateAuthority> GetCustomCertificateAuthorities()
        {
            var caList      = new List <CertificateAuthority>();
            var appDataPath = Util.GetAppDataFolder();
            var path        = appDataPath + "\\ca.json";

            if (System.IO.File.Exists(path))
            {
                var configData = System.IO.File.ReadAllText(path);
                try
                {
                    caList = Newtonsoft.Json.JsonConvert.DeserializeObject <List <CertificateAuthority> >(configData);
                }
                catch (Exception exp)
                {
                    throw new Exception($"Failed to load custom certificate authorities:: {path} {exp}");
                }
            }

            return(caList);
        }
Beispiel #17
0
        public void LoadSettings()
        {
            UpgradeSettings();

            var watch = Stopwatch.StartNew();
            // FIXME: this method should be async and called only when absolutely required, these
            //        files can be hundreds of megabytes
            string appDataPath = Util.GetAppDataFolder(StorageSubfolder);
            var    path        = Path.Combine(appDataPath, $"{ITEMMANAGERCONFIG}.db");

            if (File.Exists(path))
            {
                lock (ITEMMANAGERCONFIG)
                {
                    var managedSites = new List <ManagedSite>();
                    using (var target = new SQLiteConnection($"Data Source={path}"))
                        using (var cmd = new SQLiteCommand("SELECT json FROM managedsettings", target))
                        {
                            target.Open();
                            using (var reader = cmd.ExecuteReader())
                            {
                                while (reader.Read())
                                {
                                    managedSites.Add(JsonConvert.DeserializeObject <ManagedSite>((string)reader["json"]));
                                }
                            }
                        }
                    foreach (var site in managedSites)
                    {
                        site.IsChanged = false;
                    }
                    ManagedSites = managedSites.ToDictionary(s => s.Id);
                }
            }
            else
            {
                ManagedSites = new Dictionary <string, ManagedSite>();
            }
            Debug.WriteLine($"LoadSettings[Sqlite] took {watch.ElapsedMilliseconds}ms for {ManagedSites.Count} records");
        }
Beispiel #18
0
        private void UpgradeSettings()
        {
            var    watch       = Stopwatch.StartNew();
            string appDataPath = Util.GetAppDataFolder(StorageSubfolder);
            var    json        = Path.Combine(appDataPath, $"{ITEMMANAGERCONFIG}.json");
            var    db          = Path.Combine(appDataPath, $"{ITEMMANAGERCONFIG}.db");

            if (File.Exists(json) && !File.Exists(db))
            {
                lock (ITEMMANAGERCONFIG)
                {
                    // read managed sites using tokenize stream, this is useful for large files
                    var serializer = new JsonSerializer();
                    using (StreamReader sr = new StreamReader(json))
                        using (JsonTextReader reader = new JsonTextReader(sr))
                        {
                            var managedSiteList = serializer.Deserialize <List <ManagedSite> >(reader);

                            //safety check, if any dupe id's exists (which they shouldn't but the test data set did) make Id unique in the set.
                            var duplicateKeys = managedSiteList.GroupBy(x => x.Id).Where(group => group.Count() > 1).Select(group => group.Key);
                            foreach (var dupeKey in duplicateKeys)
                            {
                                var count = 0;
                                foreach (var i in managedSiteList.Where(m => m.Id == dupeKey))
                                {
                                    i.Id = i.Id + "_" + count;
                                    count++;
                                }
                            }

                            ManagedSites = managedSiteList.ToDictionary(s => s.Id);
                        }
                }

                StoreSettings(); // upgrade to SQLite db storage
                File.Delete($"{json}.bak");
                File.Move(json, $"{json}.bak");
                Debug.WriteLine($"UpgradeSettings[Json->Sqlite] took {watch.ElapsedMilliseconds}ms for {ManagedSites.Count} records");
            }
        }
Beispiel #19
0
        public void LoadSettings()
        {
            string appDataPath = Util.GetAppDataFolder();
            var    path        = appDataPath + "\\" + ITEMMANAGERCONFIG;

            if (System.IO.File.Exists(path))
            {
                lock (ITEMMANAGERCONFIG)
                {
                    string configData = System.IO.File.ReadAllText(path);
                    this.ManagedSites = Newtonsoft.Json.JsonConvert.DeserializeObject <List <ManagedSite> >(configData);
                }
            }
            else
            {
                this.ManagedSites = new List <ManagedSite>();
            }

            foreach (var s in this.ManagedSites)
            {
                s.IsChanged = false;
            }
        }
Beispiel #20
0
        private string GetDbPath()
        {
            string appDataPath = Util.GetAppDataFolder(StorageSubfolder);

            return(Path.Combine(appDataPath, $"{ITEMMANAGERCONFIG}.db"));
        }
Beispiel #21
0
        private string GetDbPath()
        {
            var appDataPath = Util.GetAppDataFolder(StorageSubfolder);

            return(Path.Combine(appDataPath, $"{CREDENTIALSTORE}.db"));
        }
Beispiel #22
0
        public async Task PerformCertificateCleanup()
        {
            try
            {
                var mode = CoreAppSettings.Current.CertificateCleanupMode;
                if (mode == null)
                {
                    mode = CertificateCleanupMode.AfterExpiry;
                }

                if (mode != CertificateCleanupMode.None)
                {
                    var excludedCertThumprints = new List <string>();

                    // excluded thumbprints are all certs currently tracked as managed certs
                    var managedCerts = await GetManagedCertificates();

                    foreach (var c in managedCerts)
                    {
                        if (!string.IsNullOrEmpty(c.CertificateThumbprintHash))
                        {
                            excludedCertThumprints.Add(c.CertificateThumbprintHash.ToLower());
                        }
                    }

                    if (mode == CertificateCleanupMode.FullCleanup)
                    {
                        // cleanup old pfx files in asset store(s), if any
                        var assetPath = Path.Combine(Util.GetAppDataFolder(), "certes", "assets");
                        if (Directory.Exists(assetPath))
                        {
                            var ext = new List <string> {
                                ".pfx"
                            };
                            DeleteOldCertificateFiles(assetPath, ext);
                        }

                        assetPath = Path.Combine(Util.GetAppDataFolder(), "assets");
                        if (Directory.Exists(assetPath))
                        {
                            var ext = new List <string> {
                                ".pfx", ".key", ".crt", ".pem"
                            };
                            DeleteOldCertificateFiles(assetPath, ext);
                        }
                    }

                    // this will only perform expiry cleanup, as no specific thumbprint provided
                    var certsRemoved = CertificateManager.PerformCertificateStoreCleanup(
                        (CertificateCleanupMode)mode,
                        DateTime.Now,
                        matchingName: null,
                        excludedThumbprints: excludedCertThumprints,
                        log: _serviceLog
                        );
                }
            }
            catch (Exception exp)
            {
                // log exception
                _serviceLog?.Error("Failed to perform certificate cleanup: " + exp.ToString());
            }
        }