public CertifyManager() { var serverConfig = SharedUtils.ServiceConfigManager.GetAppServiceConfig(); SettingsManager.LoadAppSettings(); InitLogging(serverConfig); Util.SetSupportedTLSVersions(); _itemManager = new ItemManager(); _serverProvider = (ICertifiedServer) new ServerProviderIIS(); _progressResults = new ObservableCollection <RequestProgressState>(); _pluginManager = new PluginManager(); _pluginManager.LoadPlugins(new List <string> { "Licensing", "DashboardClient", "DeploymentTasks" }); // TODO: convert providers to plugins, allow for async init var userAgent = Util.GetUserAgent(); var certes = new CertesACMEProvider(Management.Util.GetAppDataFolder() + "\\certes", userAgent); certes.InitProvider(_serviceLog).Wait(); _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(); } _httpChallengePort = serverConfig.HttpChallengeServerPort; _httpChallengeServerClient.Timeout = new TimeSpan(0, 0, 5); if (_tc != null) { _tc.TrackEvent("ServiceStarted"); } _serviceLog?.Information("Certify Manager Started"); PerformUpgrades().Wait(); }
private async Task <IACMEClientProvider> GetACMEProvider(AccountDetails account, string acmeApiEndpoint = null) { // get or init acme provider required for the given account if (_acmeClientProviders.TryGetValue(account.StorageKey, out var provider)) { return(provider); } else { var userAgent = Util.GetUserAgent(); var newProvider = new CertesACMEProvider(acmeApiEndpoint, Management.Util.GetAppDataFolder() + "\\certes_" + account.StorageKey, userAgent); await newProvider.InitProvider(_serviceLog, account); _acmeClientProviders.TryAdd(account.StorageKey, newProvider); return(newProvider); } }
public async Task <UpdateCheck> CheckForUpdates(string appVersion) { //get app version try { var client = new HttpClient(); client.DefaultRequestHeaders.Add("User-Agent", Util.GetUserAgent()); var response = await client.GetAsync(Models.API.Config.APIBaseURI + "update?version=" + appVersion); if (response.IsSuccessStatusCode) { var json = await response.Content.ReadAsStringAsync(); /*json = @"{ * 'version': { * 'major': 2, * 'minor': 0, * 'patch': 3 * }, * 'message': { * 'body': 'There is an awesome update available.', * 'downloadPageURL': 'https://certify.webprofusion.com', * 'releaseNotesURL': 'https://certify.webprofusion.com/home/changelog', * 'isMandatory': true * } * }";*/ var checkResult = Newtonsoft.Json.JsonConvert.DeserializeObject <UpdateCheck>(json); return(CompareVersions(appVersion, checkResult)); } return(new UpdateCheck { IsNewerVersion = false, InstalledVersion = AppVersion.FromString(appVersion) }); } catch (Exception) { return(null); } }
private async Task <IACMEClientProvider> GetACMEProvider(string storageKey, string acmeApiEndpoint = null, AccountDetails account = null, bool allowUntrustedTsl = false) { // get or init acme provider required for the given account if (_acmeClientProviders.TryGetValue(storageKey, out var provider)) { return(provider); } else { var userAgent = Util.GetUserAgent(); var providerPath = Path.Combine(Management.Util.GetAppDataFolder(), "certes_" + storageKey); var newProvider = new CertesACMEProvider(acmeApiEndpoint, providerPath, userAgent, allowUntrustedTsl); await newProvider.InitProvider(_serviceLog, account); _acmeClientProviders.TryAdd(storageKey, newProvider); return(newProvider); } }
private async Task PerformAccountUpgrades() { // check if there are no registered contacts, if so see if we are upgrading from a vault var accounts = await GetAccountRegistrations(); if (!accounts.Any()) { // if we have no accounts we need to check for required upgrades // contacts may be JSON or legacy vault // create provider pointing to legacy storage var apiEndpoint = _certificateAuthorities[StandardCertAuthorities.LETS_ENCRYPT].ProductionAPIEndpoint; var provider = new CertesACMEProvider(apiEndpoint, Management.Util.GetAppDataFolder() + "\\certes", Util.GetUserAgent()); await provider.InitProvider(_serviceLog); var acc = (provider as CertesACMEProvider).GetCurrentAcmeAccount(); if (acc != null) { // we have a legacy certes account to migrate to the newer account store var newId = Guid.NewGuid().ToString(); acc.ID = newId; acc.StorageKey = newId; acc.IsStagingAccount = false; acc.CertificateAuthorityId = StandardCertAuthorities.LETS_ENCRYPT; accounts.Add(acc); await StoreAccountAsCredential(acc); } if (accounts.Count() == 0) { // still no accounts, check for old vault upgrade var acmeVaultMigration = new Models.Compat.ACMEVaultUpgrader(); if (acmeVaultMigration.HasACMEVault()) { var email = acmeVaultMigration.GetContact(); if (!string.IsNullOrEmpty(email)) { var registerResult = await provider.AddNewAccountAndAcceptTOS(_serviceLog, email); if (registerResult.IsSuccess) { var newId = Guid.NewGuid().ToString(); acc = registerResult.Result; acc.ID = newId; acc.StorageKey = newId; acc.IsStagingAccount = false; acc.CertificateAuthorityId = StandardCertAuthorities.LETS_ENCRYPT; accounts.Add(acc); await StoreAccountAsCredential(acc); _serviceLog?.Information("Account upgrade completed (vault)"); } else { _serviceLog?.Information($"Account upgrade failed (vault):{registerResult?.Message}"); } } } } } }
private async Task <bool> StartHttpChallengeServer() { if (!await IsHttpChallengeProcessStarted()) { var cliPath = $"{AppContext.BaseDirectory}certify.exe"; _httpChallengeProcessInfo = new ProcessStartInfo(cliPath, $"httpchallenge keys={_httpChallengeControlKey},{_httpChallengeCheckKey}") { RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = false, WorkingDirectory = AppContext.BaseDirectory }; try { _httpChallengeProcess = new Process { StartInfo = _httpChallengeProcessInfo }; _httpChallengeProcess.Start(); await Task.Delay(1000); } catch (Exception) { // failed to start process _httpChallengeProcess = null; return(false); } if (_httpChallengeServerClient == null) { _httpChallengeServerClient = new System.Net.Http.HttpClient(); _httpChallengeServerClient.DefaultRequestHeaders.Add("User-Agent", Util.GetUserAgent() + " CertifyManager"); } return(await IsHttpChallengeProcessStarted()); } else { await StopHttpChallengeServer(); return(false); } }
public async Task <UpdateCheck> DownloadUpdate() { var result = await CheckForUpdates(); #if DEBUG result.IsNewerVersion = true; #endif if (result.IsNewerVersion) { string updatePath; try { updatePath = CreateLocalAppDataPath("updates"); } catch (Exception) { throw new Exception("Update failed to download. Could not create temp folder under %APPDATA%"); } //https://github.com/dotnet/corefx/issues/6849 var tempFile = Path.Combine(new string[] { updatePath, "CertifySSL_" + result.Version.ToString() + "_Setup.tmp" }); var setupFile = tempFile.Replace(".tmp", ".exe"); var downloadVerified = false; if (File.Exists(setupFile)) { // file already downloaded, see if it's already valid if (VerifyUpdateFile(setupFile, result.Message.SHA256, throwOnDeviation: false)) { downloadVerified = true; } } if (!downloadVerified) { // download and verify new setup try { using (var client = new HttpClient()) { client.DefaultRequestHeaders.Add("User-Agent", Util.GetUserAgent()); using (var response = client.GetAsync(result.Message.DownloadFileURL, HttpCompletionOption.ResponseHeadersRead).Result) { response.EnsureSuccessStatusCode(); using (Stream contentStream = await response.Content.ReadAsStreamAsync(), fileStream = new FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true)) { var totalRead = 0L; var totalReads = 0L; var buffer = new byte[8192]; var isMoreToRead = true; do { var read = await contentStream.ReadAsync(buffer, 0, buffer.Length); if (read == 0) { isMoreToRead = false; } else { await fileStream.WriteAsync(buffer, 0, read); totalRead += read; totalReads += 1; if (totalReads % 512 == 0) { Console.WriteLine(string.Format("total bytes downloaded so far: {0:n0}", totalRead)); } } }while (isMoreToRead); fileStream.Close(); } } } } catch (Exception exp) { System.Diagnostics.Debug.WriteLine("Failed to download update: " + exp.ToString()); downloadVerified = false; } // verify temp file if (!downloadVerified && VerifyUpdateFile(tempFile, result.Message.SHA256, throwOnDeviation: true)) { downloadVerified = true; if (File.Exists(setupFile)) { File.Delete(setupFile); //delete existing file } File.Move(tempFile, setupFile); // final setup file } } if (downloadVerified) { // setup is ready to run result.UpdateFilePath = setupFile; } } return(result); }