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();
        }
Exemplo n.º 2
0
        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);
            }
        }
Exemplo n.º 3
0
        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);
            }
        }
Exemplo n.º 4
0
        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);
            }
        }
Exemplo n.º 5
0
        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);
            }
        }
Exemplo n.º 7
0
        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);
        }