Example #1
0
        public void Initialize()
        {
            if (DnsCryptProxyManager.IsDnsCryptProxyInstalled())
            {
                if (DnsCryptProxyManager.IsDnsCryptProxyRunning())
                {
                    _isResolverRunning = true;
                }
            }

            if (DnscryptProxyConfiguration != null && (DnscryptProxyConfiguration.server_names == null || DnscryptProxyConfiguration.server_names.Count == 0))
            {
                _isDnsCryptAutomaticModeEnabled = true;
            }
            else
            {
                _isDnsCryptAutomaticModeEnabled = false;
            }

            if (!string.IsNullOrEmpty(DnscryptProxyConfiguration?.query_log?.file))
            {
                QueryLogViewModel.IsQueryLogLogging = true;
            }

            if (!string.IsNullOrEmpty(DnscryptProxyConfiguration?.blacklist?.log_file))
            {
                DomainBlockLogViewModel.IsDomainBlockLogLogging = true;
            }

            if (!string.IsNullOrEmpty(DnscryptProxyConfiguration?.blacklist?.blacklist_file))
            {
                DomainBlacklistViewModel.IsBlacklistEnabled = true;
            }
        }
Example #2
0
        public MainViewModel(IWindowManager windowManager, IEventAggregator events)
        {
            _windowManager = windowManager;
            _events        = events;
            _events.Subscribe(this);
            _windowTitle           = $"{Global.ApplicationName} {VersionHelper.PublishVersion} {VersionHelper.PublishBuild} [dnscrypt-proxy {DnsCryptProxyManager.GetVersion()}]";
            SelectedTab            = Tabs.MainTab;
            _isSavingConfiguration = false;
            _isWorkingOnService    = false;

            _settingsViewModel = new SettingsViewModel(_windowManager, _events)
            {
                WindowTitle = LocalizationEx.GetUiString("settings", Thread.CurrentThread.CurrentCulture)
            };
            _settingsViewModel.PropertyChanged += SettingsViewModelOnPropertyChanged;
            _queryLogViewModel         = new QueryLogViewModel(_windowManager, _events);
            _domainBlockLogViewModel   = new DomainBlockLogViewModel(_windowManager, _events);
            _domainBlacklistViewModel  = new DomainBlacklistViewModel(_windowManager, _events);
            _addressBlockLogViewModel  = new AddressBlockLogViewModel(_windowManager, _events);
            _addressBlacklistViewModel = new AddressBlacklistViewModel(_windowManager, _events);

            _resolvers = new BindableCollection <AvailableResolver>();
        }
        private MainViewModel(IWindowManager windowManager, IEventAggregator eventAggregator)
        {
            _windowManager = windowManager;
            eventAggregator.Subscribe(this);
            _userData = new UserData(Path.Combine(Directory.GetCurrentDirectory(), Global.UserConfigurationFile));
            // fill the language combobox
            _languages = LocalizationEx.GetSupportedLanguages();
            // automatically use the correct translations if available (fallback: en)
            LocalizeDictionary.Instance.SetCurrentThreadCulture = true;
            // overwrite language detection
            LocalizeDictionary.Instance.Culture = _userData.Language.Equals("auto")
                                ? Thread.CurrentThread.CurrentCulture
                                : new CultureInfo(_userData.Language);
            // select the current language in the combobox
            _selectedLanguage =
                _languages.SingleOrDefault(l => l.ShortCode.Equals(LocalizeDictionary.Instance.Culture.TwoLetterISOLanguageName));

            // this is already defined in the app.manifest, but to be sure check it again
            if (!IsAdministrator())
            {
                _windowManager.ShowMetroMessageBox(
                    LocalizationEx.GetUiString("dialog_message_bad_privileges", Thread.CurrentThread.CurrentCulture),
                    LocalizationEx.GetUiString("dialog_error_title", Thread.CurrentThread.CurrentCulture),
                    MessageBoxButton.OK, BoxType.Error);
                Environment.Exit(1);
            }
            // do a simple check, if all needed files are available
            if (!ValidateDnsCryptProxyFolder())
            {
                _windowManager.ShowMetroMessageBox(
                    LocalizationEx.GetUiString("dialog_message_missing_proxy_files",
                                               Thread.CurrentThread.CurrentCulture),
                    LocalizationEx.GetUiString("dialog_error_title", Thread.CurrentThread.CurrentCulture),
                    MessageBoxButton.OK, BoxType.Error);
                Environment.Exit(1);
            }
            if (_userData.UseIpv6)
            {
                DisplayName = string.Format("{0} {1}", Global.ApplicationName, VersionUtilities.PublishVersion);
            }
            else
            {
                DisplayName = string.Format("{0} {1} ({2})", Global.ApplicationName, VersionUtilities.PublishVersion,
                                            LocalizationEx.GetUiString("global_ipv6_disabled", Thread.CurrentThread.CurrentCulture));
            }

            _resolvers = new List <DnsCryptProxyEntry>();
            _updateResolverListOnStart   = _userData.UpdateResolverListOnStart;
            _isWorkingOnPrimaryService   = false;
            _isWorkingOnSecondaryService = false;

            LocalNetworkInterfaces = new CollectionViewSource {
                Source = _localNetworkInterfaces
            };
            PrimaryDnsCryptProxyManager   = new DnsCryptProxyManager(DnsCryptProxyType.Primary);
            SecondaryDnsCryptProxyManager = new DnsCryptProxyManager(DnsCryptProxyType.Secondary);
            ShowHiddenCards = false;

            if (PrimaryDnsCryptProxyManager.DnsCryptProxy.Parameter.TcpOnly ||
                SecondaryDnsCryptProxyManager.DnsCryptProxy.Parameter.TcpOnly)
            {
                _useTcpOnly = true;
            }

            // check the primary resolver for plugins
            if (PrimaryDnsCryptProxyManager.DnsCryptProxy.Parameter.Plugins.Any())
            {
                _plugins = PrimaryDnsCryptProxyManager.DnsCryptProxy.Parameter.Plugins.ToList();
            }
            else
            {
                if (SecondaryDnsCryptProxyManager.DnsCryptProxy.Parameter.Plugins.Any())
                {
                    _plugins = SecondaryDnsCryptProxyManager.DnsCryptProxy.Parameter.Plugins.ToList();
                }
                else
                {
                    // no stored plugins
                    _plugins = new List <string>();
                }
            }
            var proxyList = Path.Combine(Directory.GetCurrentDirectory(),
                                         Global.DnsCryptProxyFolder, Global.DnsCryptProxyResolverListName);
            var proxyListSignature = Path.Combine(Directory.GetCurrentDirectory(),
                                                  Global.DnsCryptProxyFolder, Global.DnsCryptProxySignatureFileName);

            if (!File.Exists(proxyList) || !File.Exists(proxyListSignature) || UpdateResolverListOnStart)
            {
                // download and verify the proxy list if there is no one.
                AsyncHelpers.RunSync(DnsCryptProxyListManager.UpdateResolverListAsync);
            }

            var dnsProxyList =
                DnsCryptProxyListManager.ReadProxyList(proxyList, proxyListSignature, _userData.UseIpv6);

            if (dnsProxyList != null && dnsProxyList.Any())
            {
                foreach (var dnsProxy in dnsProxyList)
                {
                    if (
                        dnsProxy.Name.Equals(
                            PrimaryDnsCryptProxyManager.DnsCryptProxy.Parameter.ResolverName))
                    {
                        _primaryResolver = dnsProxy;
                        // restore the local port
                        _primaryResolver.LocalPort = PrimaryDnsCryptProxyManager.DnsCryptProxy.Parameter.LocalPort;
                    }
                    if (
                        dnsProxy.Name.Equals(
                            SecondaryDnsCryptProxyManager.DnsCryptProxy.Parameter.ResolverName))
                    {
                        _secondaryResolver = dnsProxy;
                    }
                    _resolvers.Add(dnsProxy);
                }
            }
            else
            {
                _windowManager.ShowMetroMessageBox(
                    string.Format(
                        LocalizationEx.GetUiString("dialog_message_missing_file",
                                                   Thread.CurrentThread.CurrentCulture),
                        proxyList, proxyListSignature),
                    LocalizationEx.GetUiString("dialog_error_title", Thread.CurrentThread.CurrentCulture),
                    MessageBoxButton.OK, BoxType.Error);
                Environment.Exit(1);
            }

            // if there is no selected primary resolver, add a default resolver
            if (PrimaryResolver == null)
            {
                DnsCryptProxyEntry defaultResolver;
                // first check the config file
                if (_userData.PrimaryResolver.Equals("auto"))
                {
                    // automatic, so choose the DefaultPrimaryResolver
                    defaultResolver = dnsProxyList.SingleOrDefault(d => d.Name.Equals(Global.DefaultPrimaryResolverName)) ??
                                      dnsProxyList.SingleOrDefault(d => d.Name.Equals(Global.DefaultPrimaryBackupResolverName));
                }
                else
                {
                    defaultResolver = dnsProxyList.SingleOrDefault(d => d.Name.Equals(_userData.PrimaryResolver)) ??
                                      (dnsProxyList.SingleOrDefault(d => d.Name.Equals(Global.DefaultPrimaryResolverName)) ??
                                       dnsProxyList.SingleOrDefault(d => d.Name.Equals(Global.DefaultPrimaryBackupResolverName)));
                }
                PrimaryResolver = defaultResolver;
            }

            // if there is no selected secondary resolver, add a default resolver
            if (SecondaryResolver == null)
            {
                DnsCryptProxyEntry defaultResolver;
                // first check the config file
                if (_userData.SecondaryResolver.Equals("auto"))
                {
                    // automatic, so choose the DefaultPrimaryResolver
                    defaultResolver = dnsProxyList.SingleOrDefault(d => d.Name.Equals(Global.DefaultSecondaryResolverName)) ??
                                      dnsProxyList.SingleOrDefault(d => d.Name.Equals(Global.DefaultSecondaryBackupResolverName));
                }
                else
                {
                    defaultResolver = dnsProxyList.SingleOrDefault(d => d.Name.Equals(_userData.SecondaryResolver)) ??
                                      (dnsProxyList.SingleOrDefault(d => d.Name.Equals(Global.DefaultSecondaryResolverName)) ??
                                       dnsProxyList.SingleOrDefault(d => d.Name.Equals(Global.DefaultSecondaryBackupResolverName)));
                }

                SecondaryResolver = defaultResolver;
            }


            if (PrimaryDnsCryptProxyManager.IsDnsCryptProxyInstalled())
            {
                if (PrimaryDnsCryptProxyManager.IsDnsCryptProxyRunning())
                {
                    _isPrimaryResolverRunning = true;
                }
            }

            if (SecondaryDnsCryptProxyManager.IsDnsCryptProxyInstalled())
            {
                if (SecondaryDnsCryptProxyManager.IsDnsCryptProxyRunning())
                {
                    _isSecondaryResolverRunning = true;
                }
            }

            if (
                PrimaryDnsCryptProxyManager.DnsCryptProxy.Parameter.LocalAddress.Equals(
                    Global.GlobalGatewayAddress))
            {
                _actAsGlobalGateway   = true;
                _primaryResolverTitle = string.Format("{0} ({1}:{2})",
                                                      LocalizationEx.GetUiString("default_settings_primary_header",
                                                                                 Thread.CurrentThread.CurrentCulture),
                                                      Global.GlobalGatewayAddress, Global.PrimaryResolverPort);
            }
            else
            {
                _actAsGlobalGateway   = false;
                _primaryResolverTitle = string.Format("{0}",
                                                      LocalizationEx.GetUiString("default_settings_primary_header",
                                                                                 Thread.CurrentThread.CurrentCulture));
            }

            _secondaryResolverTitle = string.Format("{0} ({1}:{2})",
                                                    LocalizationEx.GetUiString("default_settings_secondary_header", Thread.CurrentThread.CurrentCulture),
                                                    Global.SecondaryResolverAddress,
                                                    Global.SecondaryResolverPort);

            // check for new version on every application start
            UpdateAsync();
        }
        public async Task HandleDnsCrypt(string filter)
        {
            try
            {
                IsWorking = true;
                if (filter.Equals(Global.DefaultCustomFilterKey))
                {
                    if (_isCustomFilterEnabled)
                    {
                        //disable
                        if (RemoveStaticStamps())
                        {
                            if (DnsCryptProxyManager.IsDnsCryptProxyRunning())
                            {
                                await Task.Run(() => { DnsCryptProxyManager.Stop(); }).ConfigureAwait(false);

                                await Task.Delay(Global.ServiceStopTime).ConfigureAwait(false);
                            }
                            if (DnsCryptProxyManager.IsDnsCryptProxyInstalled())
                            {
                                await Task.Run(() => { DnsCryptProxyManager.Uninstall(); }).ConfigureAwait(false);

                                await Task.Delay(Global.ServiceUninstallTime).ConfigureAwait(false);
                            }
                            HandleNetworkInterfaces(false);

                            //remove stamp from config
                            var stampIndex = _appConfiguration.Proxies.FindIndex(p => p.Name.Equals(filter));
                            if (stampIndex != -1)
                            {
                                _appConfiguration.Proxies.RemoveAt(stampIndex);
                                _appConfigurationService.Configuration = _appConfiguration;
                            }
                        }
                        IsCustomFilterEnabled = false;
                        IsAdultFilterEnabled  = false;
                        IsFamilyFilterEnabled = false;
                    }
                    else
                    {
                        //enable
                        if (SetStaticStamp(filter))
                        {
                            if (!DnsCryptProxyManager.IsDnsCryptProxyInstalled())
                            {
                                await Task.Run(() => { DnsCryptProxyManager.Install(); }).ConfigureAwait(false);

                                await Task.Delay(Global.ServiceInstallTime).ConfigureAwait(false);
                            }
                            if (DnsCryptProxyManager.IsDnsCryptProxyRunning())
                            {
                                await Task.Run(() => { DnsCryptProxyManager.Restart(); }).ConfigureAwait(false);

                                await Task.Delay(Global.ServiceRestartTime).ConfigureAwait(false);
                            }
                            else
                            {
                                await Task.Run(() => { DnsCryptProxyManager.Start(); }).ConfigureAwait(false);

                                await Task.Delay(Global.ServiceStartTime).ConfigureAwait(false);
                            }
                            HandleNetworkInterfaces(true);
                            IsCustomFilterEnabled = true;
                            IsAdultFilterEnabled  = false;
                            IsFamilyFilterEnabled = false;
                        }
                    }
                }
                else if (filter.Equals(Global.DefaultAdultFilterKey))
                {
                    if (_isAdultFilterEnabled)
                    {
                        //disable
                        if (RemoveStaticStamps())
                        {
                            if (DnsCryptProxyManager.IsDnsCryptProxyRunning())
                            {
                                await Task.Run(() => { DnsCryptProxyManager.Stop(); }).ConfigureAwait(false);

                                await Task.Delay(Global.ServiceStopTime).ConfigureAwait(false);
                            }
                            if (DnsCryptProxyManager.IsDnsCryptProxyInstalled())
                            {
                                await Task.Run(() => { DnsCryptProxyManager.Uninstall(); }).ConfigureAwait(false);

                                await Task.Delay(Global.ServiceUninstallTime).ConfigureAwait(false);
                            }
                            HandleNetworkInterfaces(false);
                        }
                        IsCustomFilterEnabled = false;
                        IsAdultFilterEnabled  = false;
                        IsFamilyFilterEnabled = false;
                    }
                    else
                    {
                        //enable
                        if (SetStaticStamp(filter))
                        {
                            if (!DnsCryptProxyManager.IsDnsCryptProxyInstalled())
                            {
                                await Task.Run(() => { DnsCryptProxyManager.Install(); }).ConfigureAwait(false);

                                await Task.Delay(Global.ServiceInstallTime).ConfigureAwait(false);
                            }
                            if (DnsCryptProxyManager.IsDnsCryptProxyRunning())
                            {
                                await Task.Run(() => { DnsCryptProxyManager.Restart(); }).ConfigureAwait(false);

                                await Task.Delay(Global.ServiceRestartTime).ConfigureAwait(false);
                            }
                            else
                            {
                                await Task.Run(() => { DnsCryptProxyManager.Start(); }).ConfigureAwait(false);

                                await Task.Delay(Global.ServiceStartTime).ConfigureAwait(false);
                            }
                            HandleNetworkInterfaces(true);
                            IsAdultFilterEnabled  = true;
                            IsCustomFilterEnabled = false;
                            IsFamilyFilterEnabled = false;
                        }
                    }
                }
                else if (filter.Equals(Global.DefaultFamilyFilterKey))
                {
                    if (_isFamilyFilterEnabled)
                    {
                        //disable
                        if (RemoveStaticStamps())
                        {
                            if (DnsCryptProxyManager.IsDnsCryptProxyRunning())
                            {
                                await Task.Run(() => { DnsCryptProxyManager.Stop(); }).ConfigureAwait(false);

                                await Task.Delay(Global.ServiceStopTime).ConfigureAwait(false);
                            }
                            if (DnsCryptProxyManager.IsDnsCryptProxyInstalled())
                            {
                                await Task.Run(() => { DnsCryptProxyManager.Uninstall(); }).ConfigureAwait(false);

                                await Task.Delay(Global.ServiceUninstallTime).ConfigureAwait(false);
                            }
                            HandleNetworkInterfaces(false);
                        }
                        IsCustomFilterEnabled = false;
                        IsFamilyFilterEnabled = false;
                        IsAdultFilterEnabled  = false;
                    }
                    else
                    {
                        //enable
                        if (SetStaticStamp(filter))
                        {
                            if (!DnsCryptProxyManager.IsDnsCryptProxyInstalled())
                            {
                                await Task.Run(() => { DnsCryptProxyManager.Install(); }).ConfigureAwait(false);

                                await Task.Delay(Global.ServiceInstallTime).ConfigureAwait(false);
                            }
                            if (DnsCryptProxyManager.IsDnsCryptProxyRunning())
                            {
                                await Task.Run(() => { DnsCryptProxyManager.Restart(); }).ConfigureAwait(false);

                                await Task.Delay(Global.ServiceRestartTime).ConfigureAwait(false);
                            }
                            else
                            {
                                await Task.Run(() => { DnsCryptProxyManager.Start(); }).ConfigureAwait(false);

                                await Task.Delay(Global.ServiceStartTime).ConfigureAwait(false);
                            }
                            HandleNetworkInterfaces(true);
                            IsFamilyFilterEnabled = true;
                            IsCustomFilterEnabled = false;
                            IsAdultFilterEnabled  = false;
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                _logger.Log($"HandleDnsCrypt {exception.Message}", Category.Exception, Priority.High);
            }
            finally
            {
                IsWorking = false;
            }
        }
        public MainWindowViewModel(
            ILoggerFacade logger,
            IRegionManager regionManager,
            IEventAggregator eventAggregator,
            ISnackbarMessageQueue snackbarMessageQueue,
            IAppConfigurationService appConfigurationService)
        {
            _logger                  = logger ?? throw new ArgumentNullException(nameof(logger));
            _eventAggregator         = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
            _regionManager           = regionManager ?? throw new ArgumentNullException(nameof(regionManager));
            _messageQueue            = snackbarMessageQueue ?? throw new ArgumentNullException(nameof(snackbarMessageQueue));
            _appConfigurationService = appConfigurationService ?? throw new ArgumentNullException(nameof(appConfigurationService));
            try
            {
                _appConfiguration = _appConfigurationService.Configuration;
                _eventAggregator.GetEvent <StampAddedEvent>().Subscribe(CustomStampAdded);
                NavigateToAboutViewCommand    = new DelegateCommand(NavigateToAboutView);
                NavigateToStampViewCommand    = new DelegateCommand(NavigateToStampView);
                NavigateToSettingsViewCommand = new DelegateCommand(NavigateToSettingsView);
                OpenWebCommand         = new DelegateCommand <string>(OpenUrl);
                CheckForUpdatesCommand = new DelegateCommand(CheckForUpdates);

                HandleCustomFilter = new DelegateCommand(HandleCustomStamp);
                HandleFamilyFilter = new DelegateCommand(async() => await HandleDnsCrypt(Global.DefaultFamilyFilterKey));
                HandleAdultFilter  = new DelegateCommand(async() => await HandleDnsCrypt(Global.DefaultAdultFilterKey));

                IsWorking             = true;
                IsCustomFilterEnabled = false;
                IsFamilyFilterEnabled = false;
                IsAdultFilterEnabled  = false;

                var year = Global.CopyrightYear.ToString();
                if (DateTime.UtcNow.Year != Global.CopyrightYear)
                {
                    year = $"{Global.CopyrightYear} - {DateTime.UtcNow.Year}";
                }
                Footer = $"Copyright © {year} {Global.CompanyName}. {VersionHelper.PublishVersion} {VersionHelper.PublishBuild}";
                ((App)Application.Current).LoggingLevelSwitch.MinimumLevel = (Serilog.Events.LogEventLevel)_appConfiguration.LogLevel;
                _logger.Log($"LogLevel: {_appConfiguration.LogLevel}", Category.Debug, Priority.Low);
                _logger.Log($"{Global.ApplicationName} {VersionHelper.PublishVersion} {VersionHelper.PublishBuild} started", Category.Info, Priority.Medium);
                // check application configuration
                _logger.Log($"checking {Global.AppConfigurationFile}", Category.Info, Priority.Medium);

                var resetApplicationConfig = false;
                if (_appConfiguration != null)
                {
                    if (_appConfiguration.Proxies != null)
                    {
                        foreach (var proxy in _appConfiguration.Proxies)
                        {
                            var decodedStamp = StampTools.Decode(proxy.Stamp);
                            if (decodedStamp != null)
                            {
                                if (decodedStamp.Protocol == DnsCrypt.Models.StampProtocol.DnsCrypt)
                                {
                                    //simple check if the stamp is a valid cleanbrowsing stamp
                                    if (!decodedStamp.ProviderName.Equals(Global.ValidCleanBrowsingDnsCryptStamp))
                                    {
                                        resetApplicationConfig = true;
                                    }
                                }
                                else if (decodedStamp.Protocol == DnsCrypt.Models.StampProtocol.DoH)
                                {
                                    //simple check if the stamp is a valid cleanbrowsing stamp
                                    if (!decodedStamp.Hostname.Equals(Global.ValidCleanBrowsingDohStamp))
                                    {
                                        resetApplicationConfig = true;
                                    }
                                }
                                else
                                {
                                    //unsupported stamp
                                    resetApplicationConfig = true;
                                }
                            }
                            else
                            {
                                resetApplicationConfig = true;
                            }
                            _logger.Log($"{proxy.Name} loaded", Category.Info, Priority.Medium);
                        }
                        _logger.Log($"{Global.AppConfigurationFile} loaded", Category.Info, Priority.Medium);
                    }
                    else
                    {
                        resetApplicationConfig = true;
                    }
                }
                else
                {
                    resetApplicationConfig = true;
                    _logger.Log($"failed to load {Global.AppConfigurationFile}", Category.Warn, Priority.Medium);
                }

                if (resetApplicationConfig)
                {
                    _logger.Log($"reset {Global.AppConfigurationFile} to default", Category.Warn, Priority.Medium);
                    _appConfigurationService.Reset();
                    _appConfiguration = _appConfigurationService.Configuration;
                    if (_appConfiguration == null)
                    {
                        _logger.Log($"failed to reset {Global.AppConfigurationFile}", Category.Exception, Priority.High);
                        Environment.Exit(-1);
                    }
                    else
                    {
                        //no validation this time, just go on
                    }
                }

                _logger.Log($"checking {Global.DnsCryptProxyFolder} folder", Category.Info, Priority.Medium);
                foreach (var proxyFile in Global.DnsCryptProxyFiles)
                {
                    var proxyFilePath = Path.Combine(Directory.GetCurrentDirectory(), Global.DnsCryptProxyFolder, proxyFile);
                    if (!File.Exists(proxyFilePath))
                    {
                        _logger.Log($"missing {proxyFile}", Category.Warn, Priority.Medium);
                    }
                    else
                    {
                        _logger.Log($"found {proxyFile}", Category.Info, Priority.Low);
                    }
                }

                var isValidConfiguration = false;
                _logger.Log($"checking {Global.DnsCryptConfigurationFile}", Category.Info, Priority.Medium);

                var configurationCheck = DnsCryptProxyManager.IsConfigurationFileValid();
                if (configurationCheck.Success)
                {
                    isValidConfiguration = true;
                    _logger.Log($"{Global.DnsCryptConfigurationFile} is valid", Category.Info, Priority.Medium);
                }
                else
                {
                    if (configurationCheck.StandardError.Contains("[FATAL] No servers configured"))
                    {
                        isValidConfiguration = true;
                        _logger.Log($"{Global.DnsCryptConfigurationFile} is valid (but no servers)", Category.Info, Priority.Medium);
                    }
                }

                if (isValidConfiguration)
                {
                    var version = DnsCryptProxyManager.GetVersion();
                    if (!string.IsNullOrEmpty(version))
                    {
                        Title = $"{Global.ApplicationName} (dnscrypt-proxy {version})";
                        _logger.Log($"dnscrypt-proxy version: {version}", Category.Info, Priority.Medium);
                    }
                    else
                    {
                        Title = $"{Global.ApplicationName} (dnscrypt-proxy unknown)";
                        _logger.Log("dnscrypt-proxy version: unknown", Category.Warn, Priority.Medium);
                    }
                    _logger.Log($"loading {Global.DnsCryptConfigurationFile}", Category.Info, Priority.Medium);
                    if (DnscryptProxyConfigurationManager.LoadConfiguration())
                    {
                        _logger.Log($"{Global.DnsCryptConfigurationFile} loaded", Category.Info, Priority.Medium);
                        _dnscryptProxyConfiguration = DnscryptProxyConfigurationManager.DnscryptProxyConfiguration;
                        if (_dnscryptProxyConfiguration.Static != null && _dnscryptProxyConfiguration.Static.Count > 0)
                        {
                            if (_dnscryptProxyConfiguration.Static.ContainsKey(Global.DefaultCustomFilterKey))
                            {
                                _logger.Log($"found {Global.DefaultCustomFilterKey} filter", Category.Info, Priority.Medium);
                                IsCustomFilterEnabled = true;
                            }
                            else if (_dnscryptProxyConfiguration.Static.ContainsKey(Global.DefaultAdultFilterKey))
                            {
                                _logger.Log($"found {Global.DefaultAdultFilterKey} filter", Category.Info, Priority.Medium);
                                IsAdultFilterEnabled = true;
                            }
                            else if (_dnscryptProxyConfiguration.Static.ContainsKey(Global.DefaultFamilyFilterKey))
                            {
                                _logger.Log($"found {Global.DefaultFamilyFilterKey} filter", Category.Info, Priority.Medium);
                                IsFamilyFilterEnabled = true;
                            }
                        }
                        else
                        {
                            _logger.Log("no static filter configured", Category.Info, Priority.Medium);
                        }

                        if (IsCustomFilterEnabled || IsFamilyFilterEnabled || IsAdultFilterEnabled)
                        {
                            if (!DnsCryptProxyManager.IsDnsCryptProxyInstalled())
                            {
                                _logger.Log($"dnscrypt-proxy service is not installed, try install", Category.Info, Priority.High);
                                //install
                                Task.Run(() => { DnsCryptProxyManager.Install(); }).ConfigureAwait(false);
                                Task.Delay(Global.ServiceInstallTime).ConfigureAwait(false);
                            }
                            else
                            {
                                _logger.Log($"dnscrypt-proxy service is already installed", Category.Info, Priority.Medium);
                            }

                            if (!DnsCryptProxyManager.IsDnsCryptProxyRunning())
                            {
                                _logger.Log($"dnscrypt-proxy service is not running, try start", Category.Info, Priority.High);
                                Task.Run(() => { DnsCryptProxyManager.Start(); }).ConfigureAwait(false);
                                Task.Delay(Global.ServiceStartTime).ConfigureAwait(false);
                            }
                            else
                            {
                                _logger.Log($"dnscrypt-proxy service is already running", Category.Info, Priority.Medium);
                            }

                            if (DnsCryptProxyManager.IsDnsCryptProxyRunning())
                            {
                                _logger.Log($"checking dns servers on network interfaces", Category.Info, Priority.High);
                                if (!HandleNetworkInterfaces(true))
                                {
                                    _logger.Log($"could not update dns servers on network interfaces", Category.Warn, Priority.High);
                                }
                            }
                            else
                            {
                                _logger.Log($"could not start dnscrypt-proxy", Category.Warn, Priority.High);
                            }
                        }
                    }
                    else
                    {
                        _logger.Log($"could not load configuration: {Global.DnsCryptConfigurationFile}", Category.Warn, Priority.High);
                        Environment.Exit(-1);
                    }
                }
                else
                {
                    _logger.Log($"invalid {Global.DnsCryptConfigurationFile}", Category.Warn, Priority.High);
                    Environment.Exit(-1);
                }
            }
            catch (Exception ex)
            {
                _logger.Log(ex.Message, Category.Exception, Priority.High);
                Environment.Exit(-1);
            }
            MessageQueue.Enqueue("🐞 You are using a preview version! May contain bugs! 🐞");
            IsWorking = false;
        }