/// <summary>
        ///     Refresh the resolver list from the newest csv file.
        /// </summary>
        /// <exception cref="UnauthorizedAccessException"></exception>
        /// <exception cref="NotSupportedException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        public async void RefreshResolverListAsync()
        {
            IsRefreshingResolverList = true;
            var state = await DnsCryptProxyListManager.UpdateResolverListAsync().ConfigureAwait(false);

            await Task.Run(() =>
            {
                // we do this, to prevent excessive usage
                Thread.Sleep(2000);
            }).ConfigureAwait(false);

            if (state)
            {
                var proxyList = Path.Combine(Directory.GetCurrentDirectory(),
                                             Global.DnsCryptProxyFolder, Global.DnsCryptProxyResolverListName);
                var proxyListSignature = Path.Combine(Directory.GetCurrentDirectory(),
                                                      Global.DnsCryptProxyFolder, Global.DnsCryptProxySignatureFileName);
                var dnsProxyList =
                    DnsCryptProxyListManager.ReadProxyList(proxyList, proxyListSignature, _userData.UseIpv6);
                if (dnsProxyList != null && dnsProxyList.Any())
                {
                    Resolvers.Clear();
                    foreach (var dnsProxy in dnsProxyList)
                    {
                        if (
                            dnsProxy.ProviderPublicKey.Equals(
                                PrimaryDnsCryptProxyManager.DnsCryptProxy.Parameter.ProviderKey))
                        {
                            _primaryResolver = dnsProxy;
                            // restore the local port
                            _primaryResolver.LocalPort = PrimaryDnsCryptProxyManager.DnsCryptProxy.Parameter.LocalPort;
                        }
                        if (
                            dnsProxy.ProviderPublicKey.Equals(
                                SecondaryDnsCryptProxyManager.DnsCryptProxy.Parameter.ProviderKey))
                        {
                            _secondaryResolver = dnsProxy;
                        }
                        Resolvers.Add(dnsProxy);
                    }
                }
            }
            else
            {
                _windowManager.ShowMetroMessageBox(
                    LocalizationEx.GetUiString("dialog_message_refresh_failed", Thread.CurrentThread.CurrentCulture),
                    LocalizationEx.GetUiString("dialog_warning_title", Thread.CurrentThread.CurrentCulture),
                    MessageBoxButton.OK, BoxType.Warning);
            }
            IsRefreshingResolverList = false;
        }
        private DnsCryptProxyParameter ConvertProxyEntryToParameter(DnsCryptProxyEntry dnsCryptProxyEntry,
                                                                    DnsCryptProxyType dnsCryptProxyType)
        {
            var dnsCryptProxyParameter = new DnsCryptProxyParameter
            {
                ProviderKey     = dnsCryptProxyEntry.ProviderPublicKey,
                Plugins         = Plugins.ToArray(),
                ProviderName    = dnsCryptProxyEntry.ProviderName,
                ResolverAddress = dnsCryptProxyEntry.ResolverAddress,
                ResolverName    = dnsCryptProxyEntry.Name,
                LocalPort       = dnsCryptProxyEntry.LocalPort,
                ResolversList   =
                    Path.Combine(Directory.GetCurrentDirectory(), Global.DnsCryptProxyFolder,
                                 Global.DnsCryptProxyResolverListName),
                EphemeralKeys = true,
                TcpOnly       = UseTcpOnly
            };

            if (dnsCryptProxyType == DnsCryptProxyType.Primary)
            {
                if (ActAsGlobalGateway)
                {
                    dnsCryptProxyParameter.LocalAddress = Global.GlobalGatewayAddress;
                }
                else
                {
                    dnsCryptProxyParameter.LocalAddress = Global.PrimaryResolverAddress;
                }
            }
            else
            {
                dnsCryptProxyParameter.LocalAddress = Global.SecondaryResolverAddress;
            }

            return(dnsCryptProxyParameter);
        }
Example #3
0
        public static async Task <DnsCryptProxyEntryExtra> Analyse(DnsCryptProxyEntry dnsCryptProxyEntry)
        {
            var dnsCryptProxyEntryExtra = new DnsCryptProxyEntryExtra();

            try
            {
                string address;
                var    port = 443;
                if (dnsCryptProxyEntry.ResolverAddress.Contains(":"))
                {
                    if (dnsCryptProxyEntry.ResolverAddress.StartsWith("["))
                    {
                        return(null);
                    }
                    var t = dnsCryptProxyEntry.ResolverAddress.Split(':');
                    address = t[0];
                    port    = Convert.ToInt32(t[1]);
                }
                else
                {
                    address = dnsCryptProxyEntry.ResolverAddress;
                }

                var providerKey = Utilities.HexToBinary(dnsCryptProxyEntry.ProviderPublicKey);
                var request     = new ClientRequest(address, port);
                request.Questions.Add(new Question(Domain.FromString(dnsCryptProxyEntry.ProviderName), RecordType.TXT));
                request.RecursionDesired = true;
                var sw       = Stopwatch.StartNew();
                var response = await request.Resolve();

                sw.Stop();

                foreach (var answerRecord in response.AnswerRecords)
                {
                    var certificates = new List <Certificate>();
                    var tr           = Encoding.ASCII.GetString(ArrayHelper.SubArray(answerRecord.Data, 0, 9));
                    if (tr.Equals("|DNSC\0\u0001\0\0") || tr.Equals("|DNSC\0\u0002\0\0"))
                    {
                        var certificate = ExtractCertificate(ArrayHelper.SubArray(answerRecord.Data, 9), providerKey);
                        if (certificate != null)
                        {
                            if (certificate.Valid)
                            {
                                certificates.Add(certificate);
                            }
                        }
                    }
                    if (certificates.Count > 0)
                    {
                        var newestCertificate = certificates.OrderByDescending(item => item.Serial).FirstOrDefault();
                        if (newestCertificate != null)
                        {
                            dnsCryptProxyEntryExtra.Certificate = newestCertificate;
                            dnsCryptProxyEntryExtra.Succeeded   = true;
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        return(null);
                    }
                }
                dnsCryptProxyEntryExtra.ResponseTime = sw.ElapsedMilliseconds;
            }
            catch (Exception)
            {
                return(null);
            }
            return(dnsCryptProxyEntryExtra);
        }
        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 static List <DnsCryptProxyEntry> ReadProxyList(string proxyListFile, bool filterIpv6 = true, bool onlyDnsSec = true, bool onlyNoLogs = true)
        {
            var dnsCryptProxyList = new List <DnsCryptProxyEntry>();

            using (var parser = new TextFieldParser(proxyListFile)
            {
                HasFieldsEnclosedInQuotes = true
            })
            {
                parser.SetDelimiters(",");
                while (!parser.EndOfData)
                {
                    var s   = parser.ReadFields();
                    var tmp = new DnsCryptProxyEntry
                    {
                        Name                        = ClearString(s[0]),
                        FullName                    = ClearString(s[1]),
                        Description                 = ClearString(s[2]),
                        Location                    = ClearString(s[3]),
                        Coordinates                 = ClearString(s[4]),
                        Url                         = ClearString(s[5]),
                        Version                     = s[6],
                        DnssecValidation            = (s[7].Equals("yes")),
                        NoLogs                      = (s[8].Equals("yes")),
                        Namecoin                    = (s[9].Equals("yes")),
                        ResolverAddress             = ClearString(s[10]),
                        ProviderName                = ClearString(s[11]),
                        ProviderPublicKey           = ClearString(s[12]),
                        ProviderPublicKeyTextRecord = ClearString(s[13]),
                        LocalPort                   = 53       //set the default port
                    };
                    if (!tmp.Description.Equals("Description"))
                    {
                        if (filterIpv6)
                        {
                            if (!tmp.ResolverAddress.StartsWith("["))
                            {
                                var add = true;
                                add = !onlyDnsSec || tmp.DnssecValidation;

                                if (add)
                                {
                                    add = !onlyNoLogs || tmp.NoLogs;
                                }

                                if (add)
                                {
                                    dnsCryptProxyList.Add(tmp);
                                }
                            }
                        }
                        else
                        {
                            var add = true;
                            add = !onlyDnsSec || tmp.DnssecValidation;

                            if (add)
                            {
                                add = !onlyNoLogs || tmp.NoLogs;
                            }

                            if (add)
                            {
                                dnsCryptProxyList.Add(tmp);
                            }
                        }
                    }
                }
            }

            return(dnsCryptProxyList);
        }
        public static List <DnsCryptProxyEntry> ReadProxyList(string proxyListFile, string proxyListSignature, bool filterIpv6 = true)
        {
            if (!File.Exists(proxyListFile))
            {
                return(null);
            }
            if (!File.Exists(proxyListSignature))
            {
                return(null);
            }

            var dnsCryptProxyList = new List <DnsCryptProxyEntry>();

            var signature = Minisign.LoadSignatureFromFile(proxyListSignature);
            var publicKey = Minisign.LoadPublicKeyFromString(Global.PublicKey);

            // only load signed files!
            if (Minisign.ValidateSignature(proxyListFile, signature, publicKey))
            {
                using (var parser = new TextFieldParser(proxyListFile)
                {
                    HasFieldsEnclosedInQuotes = true
                })
                {
                    parser.SetDelimiters(",");
                    while (!parser.EndOfData)
                    {
                        var s   = parser.ReadFields();
                        var tmp = new DnsCryptProxyEntry
                        {
                            Name                        = ClearString(s[0]),
                            FullName                    = ClearString(s[1]),
                            Description                 = ClearString(s[2]),
                            Location                    = ClearString(s[3]),
                            Coordinates                 = ClearString(s[4]),
                            Url                         = ClearString(s[5]),
                            Version                     = s[6],
                            DnssecValidation            = (s[7].Equals("yes")),
                            NoLogs                      = (s[8].Equals("yes")),
                            Namecoin                    = (s[9].Equals("yes")),
                            ResolverAddress             = ClearString(s[10]),
                            ProviderName                = ClearString(s[11]),
                            ProviderPublicKey           = ClearString(s[12]),
                            ProviderPublicKeyTextRecord = ClearString(s[13]),
                            LocalPort                   = Global.PrimaryResolverPort   //set the default port
                        };
                        if (!tmp.Description.Equals("Description"))
                        {
                            if (filterIpv6)
                            {
                                if (!tmp.ResolverAddress.StartsWith("["))
                                {
                                    dnsCryptProxyList.Add(tmp);
                                }
                            }
                            else
                            {
                                dnsCryptProxyList.Add(tmp);
                            }
                        }
                    }
                }
            }
            return(dnsCryptProxyList);
        }