Ejemplo n.º 1
0
        public override async Task <bool> CreateRecord(DnsValidationRecord record)
        {
            try
            {
                var domain     = _domainParser.GetRegisterableDomain(record.Authority.Domain);
                var recordName = RelativeRecordName(domain, record.Authority.Domain);
                await _client.CreateRecord(domain, recordName, RecordType.TXT, record.Value);

                return(true);
            }
            catch
            {
                return(false);
            }
        }
Ejemplo n.º 2
0
        private string ProcessArguments(string identifier, string recordName, string token, string args, bool escapeToken)
        {
            var ret = args;
            // recordName: _acme-challenge.sub.domain.com
            // zoneName: domain.com
            // nodeName: _acme-challenge.sub

            // recordName: domain.com
            // zoneName: domain.com
            // nodeName: @

            var zoneName = _domainParseService.GetRegisterableDomain(identifier);
            var nodeName = "@";

            if (recordName != zoneName)
            {
                // Offset by one to prevent trailing dot
                nodeName = recordName.Substring(0, recordName.Length - zoneName.Length - 1);
            }
            ret = ret.Replace("{ZoneName}", zoneName);
            ret = ret.Replace("{NodeName}", nodeName);
            ret = ret.Replace("{Identifier}", identifier);
            ret = ret.Replace("{RecordName}", recordName);

            // Some tokens start with - which confuses Powershell. We did not want to
            // make a breaking change for .bat or .exe files, so instead escape the
            // token with double quotes, as Powershell discards the quotes anyway and
            // thus it's functionally equivalant.
            if (escapeToken && (ret.Contains(" {Token} ") || ret.EndsWith(" {Token}")))
            {
                ret.Replace("{Token}", "\"{Token}\"");
            }
            ret = ret.Replace("{Token}", token);
            return(ret);
        }
Ejemplo n.º 3
0
        public override async Task <bool> CreateRecord(DnsValidationRecord record)
        {
            try
            {
                var domainname = _domainParser.GetRegisterableDomain(record.Authority.Domain);
                var recordName = RelativeRecordName(domainname, record.Authority.Domain);

                var domains = await _client.GetDomainsAsync();

                domain = domains.FirstOrDefault(d => d.Name.Equals(domainname, StringComparison.OrdinalIgnoreCase));

                if (domain == null)
                {
                    _logService.Error("The following domain could not be found as one of the users domains: {0}", domainname);
                    return(false);
                }

                txt = new DnsRecord(DnsRecordType.TXT, recordName, record.Value);
                txt = await _client.EnsureDnsRecordAsync(domain.Id, txt);

                return(true);
            }
            catch (Exception exception)
            {
                _logService.Error(exception, "Unhandled exception when attempting to create record");
                return(false);
            }
        }
Ejemplo n.º 4
0
 public string GetRootDomain(string domainName)
 {
     if (domainName.EndsWith("."))
     {
         domainName = domainName.TrimEnd('.');
     }
     return(_domainParser.GetRegisterableDomain(domainName));
 }
Ejemplo n.º 5
0
        public override async Task <bool> CreateRecord(DnsValidationRecord record)
        {
            try
            {
                var domain     = _domainParser.GetRegisterableDomain(record.Authority.Domain);
                var recordName = RelativeRecordName(domain, record.Authority.Domain);
                await _dnsService.CreateDnsEntry(
                    domain,
                    new DnsEntry()
                {
                    Content = record.Value,
                    Name    = recordName,
                    Type    = "TXT"
                });

                return(true);
            }
            catch (Exception ex)
            {
                _log.Warning($"Error creating TXT record: {ex.Message}");
                return(false);
            }
        }
Ejemplo n.º 6
0
        public IEnumerable <Order> Split(Renewal renewal, Target target)
        {
            var ret   = new Dictionary <string, Order>();
            var parts = new Dictionary <string, List <TargetPart> >();

            foreach (var part in target.Parts)
            {
                foreach (var host in part.GetIdentifiers(true))
                {
                    var domain = host.Value;
                    switch (host)
                    {
                    case DnsIdentifier dns:
                        domain = _domainParseService.GetRegisterableDomain(host.Value.TrimStart('.', '*'));
                        break;

                    default:
                        _log.Warning("Unsupported identifier type {type}", host.Type);
                        break;
                    }
                    var sourceParts = target.Parts.Where(p => p.GetIdentifiers(true).Contains(host));
                    if (!ret.ContainsKey(domain))
                    {
                        var filteredParts = sourceParts.Select(p =>
                                                               new TargetPart(new List <Identifier> {
                            host
                        })
                        {
                            SiteId   = p.SiteId,
                            SiteType = p.SiteType
                        }).ToList();
                        var newTarget = new Target(
                            target.FriendlyName ?? "",
                            host,
                            filteredParts);
                        var newOrder = new Order(
                            renewal,
                            newTarget,
                            friendlyNamePart: domain,
                            cacheKeyPart: domain);
                        ret.Add(domain, newOrder);
                        parts.Add(domain, filteredParts);
                    }
                    else
                    {
                        var existingParts = parts[domain];
                        foreach (var sourcePart in sourceParts)
                        {
                            var existingPart = existingParts.Where(x => sourcePart.SiteId == x.SiteId).FirstOrDefault();
                            if (existingPart == null)
                            {
                                existingPart = new TargetPart(new[] { host })
                                {
                                    SiteId   = sourcePart.SiteId,
                                    SiteType = sourcePart.SiteType
                                };
                                existingParts.Add(existingPart);
                            }
                            else if (!existingPart.Identifiers.Contains(host))
                            {
                                existingPart.Identifiers.Add(host);
                            }
                        }
                    }
                }
            }
            return(ret.Values);
        }
Ejemplo n.º 7
0
 public string GetRootDomain(string domainName)
 {
     return(_domainParser.GetRegisterableDomain(domainName.TrimEnd('.')));
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Get cached list of authoritative name server ip addresses
        /// </summary>
        /// <param name="domainName"></param>
        /// <param name="round"></param>
        /// <returns></returns>
        public async Task <DnsLookupResult> GetAuthority(string domainName, int round = 0, bool followCnames = true, DnsLookupResult?from = null)
        {
            var key = domainName.ToLower().TrimEnd('.');

            try
            {
                // Example: _acme-challenge.sub.example.co.uk
                domainName = domainName.TrimEnd('.');

                // First domain we should try to ask is the tld (e.g. example.co.uk)
                var rootDomain = _domainParser.GetRegisterableDomain(domainName);
                var testZone   = rootDomain;
                var client     = GetDefaultClient(round);

                // Other sub domains we should ask:
                // 1. example
                // 1. sub
                // 2. _acme-challenge
                var remainingParts = domainName.Substring(0, domainName.LastIndexOf(rootDomain))
                                     .Trim('.').Split('.')
                                     .Where(x => !string.IsNullOrEmpty(x));
                remainingParts = remainingParts.Reverse();

                var digDeeper = true;
                IEnumerable <IPAddress>?ipSet = null;
                do
                {
                    // Partial result cachign
                    if (!_authoritativeNs.ContainsKey(testZone))
                    {
                        _log.Verbose("Querying server {server} about {part}", client.IpAddress, testZone);
                        using (LogContext.PushProperty("Domain", testZone))
                        {
                            var tempResult = await client.GetNameServers(testZone, round);

                            _authoritativeNs.TryAdd(testZone, tempResult?.ToList() ?? ipSet ?? _defaultNs);
                        }
                    }
                    ipSet  = _authoritativeNs[testZone];
                    client = Produce(ipSet.OrderBy(x => Guid.NewGuid()).First());

                    // CNAME only valid for full domain. Subdomains may be
                    // regular records again
                    if (followCnames && testZone == key)
                    {
                        var cname = default(string?);
                        if (!_cnames.ContainsKey(key))
                        {
                            _cnames.TryAdd(key, await client.GetCname(testZone));
                        }
                        cname = _cnames[key];
                        if (cname != null)
                        {
                            return(await GetAuthority(cname, round, true, Produce(key, from)));
                        }
                    }

                    if (remainingParts.Any())
                    {
                        testZone       = $"{remainingParts.First()}.{testZone}";
                        remainingParts = remainingParts.Skip(1).ToArray();
                    }
                    else
                    {
                        digDeeper = false;
                    }
                }while (digDeeper);

                if (ipSet == null)
                {
                    throw new Exception("No results");
                }
            }
            catch (Exception ex)
            {
                _log.Warning("Unable to find or contact authoritative name servers for {domainName}: {message}", domainName, ex.Message);
                _authoritativeNs.TryAdd(key, _defaultNs);
            }
            return(Produce(key, from));
        }