示例#1
0
        } // End Sub Test1

        // https://stackoverflow.com/questions/28612289/tcpclient-connectasync-or-socket-beginconnect-with-non-blocking-timeout-setting
        public static void Test2()
        {
            IDnsSecResolver resolver = new DnsSecRecursiveDnsResolver();

            //using (TcpClient client = new TcpClient("example.com", 443))
            using (TcpClient client = new TcpClient())
            {
                Task t = client.ConnectAsync("example.com", 443);
                t.Wait();


                using (DaneStream stream = new DaneStream(client.GetStream(), resolver))
                {
                    stream.AuthenticateAsClient("example.com", 443);

                    if (stream.IsAuthenticatedByDane)
                    {
                        Console.WriteLine("Stream is authenticated by DANE/TLSA");
                    }

                    // work with the stream
                } // End Using stream
            }     // End Using client
        }         // End Sub Test2
示例#2
0
        } // End Sub Test1

        // https://stackoverflow.com/questions/28612289/tcpclient-connectasync-or-socket-beginconnect-with-non-blocking-timeout-setting
        public static void Test2()
        {
            IDnsSecResolver resolver = new DnsSecRecursiveDnsResolver();

            //using (System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient("example.com", 443))

            using (System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient())
            {
                System.Threading.Tasks.Task t = client.ConnectAsync("example.com", 443);
                t.Wait();

                using (ARSoft.Tools.Net.Net.DaneStream stream = new ARSoft.Tools.Net.Net.DaneStream(client.GetStream(), resolver))
                {
                    stream.AuthenticateAsClient("example.com", 443);

                    if (stream.IsAuthenticatedByDane)
                    {
                        System.Console.WriteLine("Stream is authenticated by DANE/TLSA");
                    }

                    // work with the stream
                } // End Using stream
            }     // End Using client
        }         // End Sub Test2
示例#3
0
        public async Task <List <ActionResult> > CheckDNS(ILog log, string domain, bool?useProxyAPI = null, bool includeIPCheck = true)
        {
            var results = new List <ActionResult>();

            log.Information("CheckDNS: performing DNS checks. This option can be disabled in Settings if required.");

            if (string.IsNullOrEmpty(domain))
            {
                results.Add(new ActionResult {
                    IsSuccess = false, Message = "CheckDNS: Cannot check null or empty DNS name."
                });
                log.Error(results.Last().Message);
                return(results);
            }

            // if validation proxy enabled, DNS for the domain being validated is checked via our
            // remote API rather than directly on the servers
            var useProxy = useProxyAPI ?? _enableValidationProxyAPI;

            if (useProxy)
            {
                // TODO: update proxy and implement proxy check here return (ok, message);
            }

            // check dns resolves to IP
            if (includeIPCheck)
            {
                try
                {
                    log.Information($"Checking DNS name resolves to IP: {domain}");

                    var result = await Dns.GetHostEntryAsync(domain); // this throws SocketException for bad DNS

                    results.Add(new ActionResult
                    {
                        IsSuccess = true,
                        Message   = $"CheckDNS: '{domain}' resolved to an IP Address {result.AddressList[0]}. "
                    });
                }
                catch
                {
                    results.Add(new ActionResult
                    {
                        IsSuccess = false,
                        Message   = $"CheckDNS: '{domain}' failed to resolve to an IP Address. "
                    });

                    log.Error(results.Last().Message);
                    return(results);
                }
            }

            DnsMessage caa_query = null;
            DomainName dn        = null;

            try
            {
                // check CAA
                dn        = DomainName.Parse(domain);
                caa_query = DnsClient.Default.Resolve(dn, RecordType.CAA);
            }
            catch (Exception exp)
            {
                log.Error(exp, $"'{domain}' DNS error resolving CAA : {exp.Message}");
            }

            if (caa_query == null || caa_query.ReturnCode != ReturnCode.NoError)
            {
                // dns lookup failed

                results.Add(new ActionResult
                {
                    IsSuccess = false,
                    Message   = $"CheckDNS: '{domain}' failed to parse or resolve CAA. "
                });

                log.Error(results.Last().Message);
                return(results);
            }

            if (caa_query.AnswerRecords.Where(r => r is CAARecord).Count() > 0)
            {
                // dns returned at least 1 CAA record, check for validity
                if (!caa_query.AnswerRecords.Where(r => r is CAARecord).Cast <CAARecord>()
                    .Any(r => (r.Tag == "issue" || r.Tag == "issuewild") &&
                         r.Value == "letsencrypt.org"))
                {
                    // there were no CAA records of "[flag] [tag] [value]" where [tag] = issue |
                    // issuewild and [value] = letsencrypt.org
                    // see: https://letsencrypt.org/docs/caa/

                    results.Add(new ActionResult
                    {
                        IsSuccess = false,
                        Message   = $"CheckDNS: '{domain}' DNS CAA verification failed - existing CAA record prevent issuance for letsencrypt.org CA."
                    });

                    log.Warning(results.Last().Message);
                    return(results);
                }
            }

            // now either there were no CAA records returned (i.e. CAA is not configured) or the CAA
            // records are correctly configured

            // check DNSSEC
            var dnssec = new DnsSecRecursiveDnsResolver();

            try
            {
                log.Information("Checking DNSSEC resolution");

                var res = await dnssec.ResolveSecureAsync <ARecord>(dn);

                var isOk = res.ValidationResult != DnsSecValidationResult.Bogus;

                if (isOk)
                {
                    results.Add(new ActionResult
                    {
                        IsSuccess = true,
                        Message   = $"CheckDNS: '{domain}' DNSSEC Check OK - Validation Result: {res.ValidationResult}"
                    });
                }
                else
                {
                    results.Add(new ActionResult
                    {
                        IsSuccess = isOk,
                        Message   = $"CheckDNS: '{domain}'DNSSEC Check Failed - Validation Result: {res.ValidationResult}"
                    });
                }
            }
            catch (DnsSecValidationException exp)
            {
                // invalid dnssec
                results.Add(new ActionResult
                {
                    IsSuccess = false,
                    Message   = $"CheckDNS: '{domain}'DNSSEC Check Failed - {exp.Message}"
                });
                log.Warning(results.Last().Message);
            }
            catch (Exception exp)
            {
                // domain failed to resolve from this machine
                results.Add(new ActionResult
                {
                    IsSuccess = false,
                    Message   = $"CheckDNS: '{domain}' DNS error resolving DnsSecRecursiveDnsResolver - {exp.Message}"
                });
            }

            return(results);
        }
示例#4
0
        public (bool Ok, string Message) CheckDNS(string domain, bool?useProxyAPI = null)
        {
            // helper function to log the error then return the ValueTuple
            Func <string, (bool, string)> errorResponse = (msg) =>
            {
                msg = $"CheckDNS: {msg}\nDNS checks can be disabled in Settings if required.";
                Log(msg);
                return(false, msg);
            };

            if (String.IsNullOrEmpty(domain))
            {
                return(errorResponse("Cannot check null or empty DNS name."));
            }

            // if validation proxy enabled, DNS for the domain being validated is checked via our
            // remote API rather than directly on the servers
            bool useProxy = useProxyAPI ?? CoreAppSettings.Current.EnableValidationProxyAPI;

            if (useProxy)
            {
                // TODO: update proxy and implement proxy check here return (ok, message);
            }

            // check dns
            try
            {
                Dns.GetHostEntry(domain); // this throws SocketException for bad DNS
            }
            catch
            {
                return(errorResponse($"'{domain}' failed to resolve to an IP Address."));
            }

            DnsMessage caa_query = null;
            DomainName dn        = null;

            try
            {
                // check CAA
                dn        = DomainName.Parse(domain);
                caa_query = DnsClient.Default.Resolve(dn, RecordType.CAA);
            }
            catch (Exception exp)
            {
                Log($"'{domain}' DNS error resolving CAA: " + exp.ToString());
            }

            if (caa_query == null || caa_query.ReturnCode != ReturnCode.NoError)
            {
                // dns lookup failed
                return(errorResponse($"'{domain}' failed to parse or resolve CAA."));
            }

            if (caa_query.AnswerRecords.Where(r => r is CAARecord).Count() > 0)
            {
                // dns returned at least 1 CAA record, check for validity
                if (!caa_query.AnswerRecords.Where(r => r is CAARecord).Cast <CAARecord>()
                    .Any(r => (r.Tag == "issue" || r.Tag == "issuewild") &&
                         r.Value == "letsencrypt.org"))
                {
                    // there were no CAA records of "[flag] [tag] [value]" where [tag] = issue |
                    // issuewild and [value] = letsencrypt.org
                    // see: https://letsencrypt.org/docs/caa/
                    return(errorResponse($"'{domain}' DNS CAA verification failed."));
                }
            }
            // now either there were no CAA records returned (i.e. CAA is not configured) or the CAA
            // records are correctly configured

            // note: this seems to need to run in a Task or it hangs forever when called from the WPF UI
            if (!Task.Run(async() =>
            {
                // check DNSSEC
                var dnssec = new DnsSecRecursiveDnsResolver();
                try
                {
                    var res = await dnssec.ResolveSecureAsync <ARecord>(dn);
                    return(res.ValidationResult != DnsSecValidationResult.Bogus);
                }
                catch (DnsSecValidationException)
                {
                    // invalid dnssec
                    return(false);
                }
                catch (Exception exp)
                {
                    // domain failed to resolve from this machine
                    Log($"'{domain}' DNS error resolving DnsSecRecursiveDnsResolver: " + exp.ToString());
                    return(false);
                }
            }).Result)
            {
                return(errorResponse($"'{domain}' DNSSEC verification failed."));
            }
            return(true, "");
        }
示例#5
0
        public (bool Ok, string Message) CheckDNS(string domain, bool?useProxyAPI = null)
        {
            // if validation proxy enabled, DNS for the domain being validated is checked via our
            // remote API rather than directly on the servers
            bool useProxy = useProxyAPI ?? Certify.Properties.Settings.Default.EnableValidationProxyAPI;

            if (useProxy)
            {
                // TODO: update proxy and implement proxy check here
                // return (ok, message);
            }

            var dn  = DomainName.Parse(domain);
            var dns = DnsClient.Default.Resolve(dn, RecordType.CAA);

            if (dns == null || dns.ReturnCode != ReturnCode.NoError)
            {
                // dns lookup failed
                string message = $"DNS lookup failed for '{domain}'";
                Log(message);
                return(false, message);
            }

            // check CAA
            if (dns.AnswerRecords.Where(r => r is CAARecord).Count() > 0)
            {
                // dns returned at least 1 CAA record, check for validity
                if (!dns.AnswerRecords.Where(r => r is CAARecord).Cast <CAARecord>()
                    .Any(r => (r.Tag == "issue" || r.Tag == "issuewild") &&
                         r.Value == "letsencrypt.org"))
                {
                    // there were no CAA records of "[flag] [tag] [value]"
                    // where [tag] = issue | issuewild
                    // and [value] = letsencrypt.org
                    // see: https://letsencrypt.org/docs/caa/
                    string message = $"DNS CAA verification failed for '{domain}'";
                    Log(message);
                    return(false, message);
                }
            }
            // now either there were no CAA records returned (i.e. CAA is not configured)
            // or the CAA records are correctly configured

            // note: this seems to need to run in a Task or it hangs forever
            // when called from the WPF UI
            if (!Task.Run(async() =>
            {
                // check DNSSEC
                var dnssec = new DnsSecRecursiveDnsResolver();
                try
                {
                    var res = await dnssec.ResolveSecureAsync <ARecord>(dn);
                    return(res.ValidationResult != DnsSecValidationResult.Bogus);
                }
                catch (DnsSecValidationException)
                {
                    // invalid dnssec
                    return(false);
                }
            }).Result)
            {
                string message = $"DNSSEC verification failed for '{domain}'";
                Log(message);
                return(false, message);
            }
            return(true, "");
        }