public async Task TestGetManagedCertificates() { var filter = new ManagedCertificateFilter(); var result = await _client.GetManagedCertificates(filter); Assert.IsNotNull(result, $"Fetched {result.Count} managed sites"); }
public async Task <List <ManagedCertificate> > GetManagedCertificates(ManagedCertificateFilter filter = null) { var list = await _itemManager.GetAll(filter); if (filter?.IncludeExternal == true) { if (_pluginManager?.CertificateManagerProviders?.Any() == true) { // TODO: cache providers/results // check if we have any external sources of managed certificates foreach (var p in _pluginManager.CertificateManagerProviders) { if (p != null) { var pluginType = p.GetType(); var providers = p.GetProviders(pluginType); foreach (var cp in providers) { var certManager = p.GetProvider(pluginType, cp.Id); var certs = await certManager.GetManagedCertificates(filter); list.AddRange(certs); } } else { System.Diagnostics.Debug.WriteLine("Failed to create provider from plugin [Certificate Manager] "); } } } } return(list); }
public async Task <List <ManagedCertificate> > GetManagedCertificates(ManagedCertificateFilter filter = null) { var list = await _itemManager.GetManagedCertificates(filter); if (filter?.IncludeExternal == true) { if (_pluginManager?.CertificateManagerProviders?.Any() == true) { // TODO: cache providers/results // check if we have any external sources of managed certificates foreach (var p in _pluginManager.CertificateManagerProviders) { var providers = p.GetProviders(); foreach (var cp in providers) { var certManager = p.GetProvider(cp.Id); var certs = await certManager.GetManagedCertificates(filter); list.AddRange(certs); } } } } return(list); }
private async void Export_Click(object sender, RoutedEventArgs e) { var filter = new ManagedCertificateFilter { }; var settings = new ExportSettings { }; var dialog = new SaveFileDialog(); // prompt user for save file location and perform export to json file dialog.FileName = $"certifytheweb_export_{DateTime.Now.ToString("yyyyMMdd")}.json"; dialog.DefaultExt = "json"; dialog.Filter = "Json files (*.json)|*.json|All files (*.*)|*.*"; if (dialog.ShowDialog() == true) { var savePath = dialog.FileName; settings.EncryptionSecret = txtSecret.Password; var export = await MainViewModel.GetSettingsExport(filter, settings, false); var json = JsonConvert.SerializeObject(export, new JsonSerializerSettings { Formatting = Formatting.Indented, NullValueHandling = NullValueHandling.Ignore }); System.IO.File.WriteAllText(savePath, json); (App.Current as App).ShowNotification("Export completed OK", App.NotificationType.Success); } }
public async Task <List <ManagedCertificate> > GetAll(ManagedCertificateFilter filter = null) { #if DEBUG // filter.PageIndex = 0; // filter.PageSize = 100; #endif var items = await LoadAllManagedCertificates(filter); if (filter != null) { if (!string.IsNullOrEmpty(filter.Id)) { items = items.Where(i => i.Id.ToLowerInvariant().Trim() == filter.Id.ToLowerInvariant().Trim()); } if (!string.IsNullOrEmpty(filter.Name)) { items = items.Where(i => i.Name.ToLowerInvariant().Trim() == filter.Name.ToLowerInvariant().Trim()); } if (!string.IsNullOrEmpty(filter.Keyword)) { items = items.Where(i => i.Name.ToLowerInvariant().Contains(filter.Keyword.ToLowerInvariant())); } if (!string.IsNullOrEmpty(filter.ChallengeType)) { items = items.Where(i => i.RequestConfig.Challenges != null && i.RequestConfig.Challenges.Any(t => t.ChallengeType == filter.ChallengeType)); } if (!string.IsNullOrEmpty(filter.ChallengeProvider)) { items = items.Where(i => i.RequestConfig.Challenges != null && i.RequestConfig.Challenges.Any(t => t.ChallengeProvider == filter.ChallengeProvider)); } if (!string.IsNullOrEmpty(filter.StoredCredentialKey)) { items = items.Where(i => i.RequestConfig.Challenges != null && i.RequestConfig.Challenges.Any(t => t.ChallengeCredentialKey == filter.StoredCredentialKey)); } //TODO: IncludeOnlyNextAutoRenew if (filter.MaxResults > 0) { items = items.Take(filter.MaxResults); } } return(items.ToList()); }
public async Task TestGetManagedCertificate() { //get full list var filter = new ManagedCertificateFilter { MaxResults = 10 }; var results = await _client.GetManagedCertificates(filter); Assert.IsTrue(results.Count > 0, "Got one or more managed sites"); //attempt to get single item var site = await _client.GetManagedCertificate(results[0].Id); Assert.IsNotNull(site, $"Fetched single managed site details"); }
public async Task <List <ManagedCertificate> > GetManagedCertificates(ManagedCertificateFilter filter) { var response = await PostAsync("managedcertificates/search/", filter); var serializer = new JsonSerializer(); using (var sr = new StreamReader(await response.Content.ReadAsStreamAsync())) using (var reader = new JsonTextReader(sr)) { var managedCertificateList = serializer.Deserialize <List <ManagedCertificate> >(reader); foreach (var s in managedCertificateList) { s.IsChanged = false; } return(managedCertificateList); } }
public async Task <List <ManagedCertificate> > GetManagedCertificates(ManagedCertificateFilter filter = null, bool reloadAll = true) { // Don't reload settings unless we need to or we are unsure if any items have changed if (!_managedCertificatesCache.Any() || IsSingleInstanceMode == false || reloadAll) { await LoadAllManagedCertificates(); } // filter and convert dictionary to list TODO: use db instead of in memory filter? var items = _managedCertificatesCache.Values.AsQueryable(); if (filter != null) { if (!string.IsNullOrEmpty(filter.Name)) { items = items.Where(i => i.Name.ToLowerInvariant().Trim() == filter.Name.ToLowerInvariant().Trim()); } if (!string.IsNullOrEmpty(filter.Keyword)) { items = items.Where(i => i.Name.ToLowerInvariant().Contains(filter.Keyword.ToLowerInvariant())); } if (!string.IsNullOrEmpty(filter.ChallengeType)) { items = items.Where(i => i.RequestConfig.Challenges != null && i.RequestConfig.Challenges.Any(t => t.ChallengeType == filter.ChallengeType)); } if (!string.IsNullOrEmpty(filter.ChallengeProvider)) { items = items.Where(i => i.RequestConfig.Challenges != null && i.RequestConfig.Challenges.Any(t => t.ChallengeProvider == filter.ChallengeProvider)); } if (!string.IsNullOrEmpty(filter.StoredCredentialKey)) { items = items.Where(i => i.RequestConfig.Challenges != null && i.RequestConfig.Challenges.Any(t => t.ChallengeCredentialKey == filter.StoredCredentialKey)); } //TODO: IncludeOnlyNextAutoRenew if (filter.MaxResults > 0) { items = items.Take(filter.MaxResults); } } return(new List <ManagedCertificate>(items)); }
private async void Export_Click(object sender, RoutedEventArgs e) { var filter = new ManagedCertificateFilter { }; var settings = new ExportSettings { }; var dialog = new SaveFileDialog(); // prompt user for save file location and perform export to json file dialog.FileName = $"certifytheweb_export_{DateTime.Now.ToString("yyyyMMdd")}.json"; if (dialog.ShowDialog() == true) { var savePath = dialog.FileName; var export = await MainViewModel.GetSettingsExport(filter, settings, false); var json = JsonConvert.SerializeObject(export); System.IO.File.WriteAllText(savePath, json); (App.Current as App).ShowNotification("Export completed OK", App.NotificationType.Success); } }
public async Task <List <ManagedCertificate> > Search(ManagedCertificateFilter filter) { DebugLog(); return(await _certifyManager.GetManagedCertificates(filter)); }
public async Task <List <ManagedCertificate> > GetManagedCertificates(ManagedCertificateFilter filter = null) { var list = new List <ManagedCertificate>(); if (await IsPresent()) { var directorySearch = new DirectoryInfo(_settingsPath); var configFiles = directorySearch.GetFiles("order.json", SearchOption.AllDirectories); foreach (var config in configFiles) { try { var cfg = JsonConvert.DeserializeObject <ConfigSettings>(File.ReadAllText(config.FullName)); var managedCert = new ManagedCertificate { Id = "posh-acme://" + cfg.Id, Name = cfg.FriendlyName, ItemType = ManagedCertificateType.SSL_ExternallyManaged, SourceId = Definition.Id, SourceName = Definition.Title, // CertificateThumbprintHash = lastSuccess?.Thumbprint, DateRenewed = cfg.RenewAfter, DateExpiry = cfg.CertExpires, LastRenewalStatus = cfg.Status == "valid" ? RequestState.Success : (cfg.Status != null ? RequestState.Error : (RequestState?)null), DateLastRenewalAttempt = config.LastWriteTime, RequestConfig = new CertRequestConfig { PrimaryDomain = cfg.MainDomain, SubjectAlternativeNames = cfg.SANs }, DomainOptions = new System.Collections.ObjectModel.ObservableCollection <DomainOption> { new DomainOption { Domain = cfg.MainDomain, IsPrimaryDomain = true, IsManualEntry = true, IsSelected = true } } }; if (managedCert.RequestConfig.SubjectAlternativeNames != null) { var domains = managedCert.RequestConfig.SubjectAlternativeNames.Where(d => d != managedCert.RequestConfig.PrimaryDomain).Distinct(); foreach (var d in domains) { managedCert.DomainOptions.Add(new DomainOption { Domain = d, IsManualEntry = true, IsPrimaryDomain = false }); } } managedCert.IsChanged = false; list.Add(managedCert); } catch (Exception exp) { System.Diagnostics.Debug.WriteLine($"Failed to parse config: [{config}] " + exp); } } } return(list); }
public async Task <List <ManagedCertificate> > GetManagedCertificates(ManagedCertificateFilter filter = null) { var list = new List <ManagedCertificate>(); if (await IsPresent()) { var directorySearch = new DirectoryInfo(Path.Combine(_settingsPath, "renewal")); if (directorySearch.Exists) { var configFiles = directorySearch.GetFiles("*.conf", SearchOption.AllDirectories); foreach (var config in configFiles) { try { var id = config.Name.Replace(".conf", ""); var managedCert = new ManagedCertificate { Id = "certbot://" + id, Name = id, ItemType = ManagedCertificateType.SSL_ExternallyManaged, SourceId = Definition.Id, SourceName = Definition.Title }; var certFile = new FileInfo(Path.Combine(_settingsPath, "live", id, "cert.pem")); if (certFile.Exists) { try { var cert = Certify.Management.CertificateManager.ReadCertificateFromPem(certFile.FullName); var parsedCert = new System.Security.Cryptography.X509Certificates.X509Certificate2(cert.GetEncoded()); managedCert.DateStart = cert.NotBefore; managedCert.DateExpiry = cert.NotAfter; managedCert.DateRenewed = cert.NotBefore; managedCert.DateLastRenewalAttempt = cert.NotBefore; managedCert.CertificateThumbprintHash = parsedCert.Thumbprint; managedCert.CertificatePath = certFile.FullName; managedCert.LastRenewalStatus = RequestState.Success; if (cert.NotAfter < DateTime.Now.AddDays(29)) { // assume certs with less than 30 days left have failed to renew managedCert.LastRenewalStatus = RequestState.Error; managedCert.RenewalFailureMessage = "Check certbot configuration. This certificate will expire in less than 30 days and has not yet automatically renewed."; } managedCert.RequestConfig = new CertRequestConfig { PrimaryDomain = parsedCert.SubjectName.Name }; var sn = ((System.Collections.ArrayList)cert.GetSubjectAlternativeNames()); List <string> sans = new List <string>(); foreach (System.Collections.ArrayList s in sn) { sans.Add(s[1].ToString()); } managedCert.RequestConfig.SubjectAlternativeNames = sans.ToArray(); managedCert.DomainOptions = new System.Collections.ObjectModel.ObservableCollection <DomainOption> { new DomainOption { Domain = managedCert.RequestConfig.PrimaryDomain, IsPrimaryDomain = true, IsManualEntry = true, IsSelected = true } }; } catch (Exception exp) { System.Diagnostics.Debug.WriteLine("Failed to parse cert: " + exp); } } //var cfg = ParseIni(File.ReadAllText(config.FullName)); managedCert.IsChanged = false; list.Add(managedCert); } catch (Exception exp) { System.Diagnostics.Debug.WriteLine($"Failed to parse config: [{config}] " + exp); } } } } return(list); }
public async Task <List <ManagedCertificate> > GetManagedCertificates(ManagedCertificateFilter filter = null) => await _itemManager.GetManagedCertificates(filter, true);
public async Task <List <ManagedCertificate> > GetManagedCertificates(ManagedCertificateFilter filter = null) { return(await this._itemManager.GetManagedCertificates(filter, true)); }
/// <summary> /// Export the managed certificates and related settings for the given filter /// </summary> /// <param name="filter"></param> /// <returns>Package of exported settings</returns> public async Task <ImportExportPackage> PerformExport(ManagedCertificateFilter filter, ExportSettings settings, bool isPreview) { var salt = Guid.NewGuid().ToString(); var export = new ImportExportPackage { SourceName = Environment.MachineName, ExportDate = DateTime.Now, SystemVersion = Certify.Management.Util.GetAppVersion(), EncryptionSalt = salt, EncryptionValidation = new EncryptedContent { Content = EncryptBytes(Encoding.ASCII.GetBytes("Secret"), settings.EncryptionSecret, salt), Scheme = EncryptionScheme } }; // export managed certs, related certificate files, stored credentials // deployment tasks with local script or path references will need to copy the scripts separately. Need a summary of items to copy. var managedCerts = await _itemManager.GetAll(filter); export.Content = new ImportExportContent { ManagedCertificates = managedCerts, CertificateFiles = new List <EncryptedContent>(), Scripts = new List <EncryptedContent>(), CertificateAuthorities = new List <CertificateAuthority>(), StoredCredentials = new List <StoredCredential>() }; // for each managed cert, export the current certificate files (if present) foreach (var c in managedCerts) { if (!string.IsNullOrEmpty(c.CertificatePath) && System.IO.File.Exists(c.CertificatePath)) { var certBytes = System.IO.File.ReadAllBytes(c.CertificatePath); var encryptedBytes = EncryptBytes(certBytes, settings.EncryptionSecret, export.EncryptionSalt); var content = new EncryptedContent { Filename = c.CertificatePath, Scheme = EncryptionScheme, Content = encryptedBytes }; export.Content.CertificateFiles.Add(content); } if (c.PreRequestTasks?.Any() == true) { export.Content.Scripts.AddRange(GetTaskScriptsAndContent(c.PreRequestTasks, settings.EncryptionSecret, export.EncryptionSalt)); } if (c.PostRequestTasks?.Any() == true) { export.Content.Scripts.AddRange(GetTaskScriptsAndContent(c.PostRequestTasks, settings.EncryptionSecret, export.EncryptionSalt)); } } // for each managed cert, check used stored credentials (DNS challenges or deployment tasks) var allCredentials = await _credentialsManager.GetCredentials(); var usedCredentials = new List <StoredCredential>(); if (settings.ExportAllStoredCredentials) { usedCredentials.AddRange(allCredentials); } else { foreach (var c in managedCerts) { // gather credentials used by cert if (c.CertificatePasswordCredentialId != null) { if (!usedCredentials.Any(u => u.StorageKey == c.CertificatePasswordCredentialId)) { usedCredentials.Add(allCredentials.Find(a => a.StorageKey == c.CertificatePasswordCredentialId)); } } // gather credentials used by tasks var allTasks = new List <Config.DeploymentTaskConfig>(); if (c.PreRequestTasks != null) { allTasks.AddRange(c.PreRequestTasks); } if (c.PostRequestTasks != null) { allTasks.AddRange(c.PostRequestTasks); } if (allTasks.Any()) { var usedTaskCredentials = allTasks .Select(t => t.ChallengeCredentialKey) .Distinct() .Where(t => allCredentials.Any(ac => ac.StorageKey == t)); foreach (var used in usedTaskCredentials) { if (!usedCredentials.Any(u => u.StorageKey == used)) { usedCredentials.Add(allCredentials.FirstOrDefault(u => u.StorageKey == used)); } } } } } // decrypt each used stored credential, re-encrypt and base64 encode secret foreach (var c in usedCredentials) { var decrypted = await _credentialsManager.GetUnlockedCredential(c.StorageKey); if (decrypted != null) { var encBytes = EncryptBytes(Encoding.UTF8.GetBytes(decrypted), settings.EncryptionSecret, export.EncryptionSalt); c.Secret = Convert.ToBase64String(encBytes); } } export.Content.StoredCredentials = usedCredentials; // for each managed cert, check and summarise used local scripts // copy acme-dns settings // export acme accounts? return(export); }
private async Task <IQueryable <ManagedCertificate> > LoadAllManagedCertificates(ManagedCertificateFilter filter) { var managedCertificates = new List <ManagedCertificate>(); var watch = Stopwatch.StartNew(); // FIXME: this query should called only when absolutely required as the result set may be very large if (File.Exists(_dbPath)) { var sql = "SELECT id, json FROM manageditem"; if (filter?.PageIndex != null && filter?.PageSize != null) { sql += $" LIMIT {filter.PageSize} OFFSET {filter.PageIndex}"; //sql += $" WHERE id NOT IN (SELECT id FROM manageditem ORDER BY id ASC LIMIT {filter.PageSize * filter.PageIndex}) ORDER BY id ASC LIMIT {filter.PageIndex}"; } using (var db = new SQLiteConnection(_connectionString)) using (var cmd = new SQLiteCommand(sql, db)) { await db.OpenAsync(); using (var reader = await cmd.ExecuteReaderAsync()) { while (await reader.ReadAsync()) { var itemId = (string)reader["id"]; var managedCertificate = JsonConvert.DeserializeObject <ManagedCertificate>((string)reader["json"]); // in some cases users may have previously manipulated the id, causing // duplicates. Correct the ID here (database Id is unique): if (managedCertificate.Id != itemId) { managedCertificate.Id = itemId; Debug.WriteLine("LoadSettings: Corrected managed site id: " + managedCertificate.Name); } managedCertificates.Add(managedCertificate); } reader.Close(); } } foreach (var site in managedCertificates) { site.IsChanged = false; } } Debug.WriteLine($"LoadAllManagedCertificates[SQLite] took {watch.ElapsedMilliseconds}ms for {managedCertificates.Count} records"); return(managedCertificates.AsQueryable()); }
/// <summary> /// Perform full export of app configuration /// </summary> /// <param name="filter"></param> /// <param name="settings"></param> /// <param name="isPreview">If true, export is a preview only</param> /// <returns></returns> public async Task <ImportExportPackage> GetSettingsExport(ManagedCertificateFilter filter, ExportSettings settings, bool isPreview) { var pkg = await _certifyClient.PerformExport(new ExportRequest { Filter = filter, Settings = settings, IsPreviewMode = isPreview }); return(pkg); }