/// <summary>
		///   Forces to update all hints using the given resolver
		/// </summary>
		/// <param name="resolver">The resolver to use for resolving the new hints</param>
		public void Update(IDnsResolver resolver)
		{
			Zone zone = new Zone(DomainName.Root);

			var nameServer = resolver.Resolve<NsRecord>(DomainName.Root, RecordType.Ns);
			zone.AddRange(nameServer);

			foreach (var nsRecord in nameServer)
			{
				zone.AddRange(resolver.Resolve<ARecord>(nsRecord.NameServer, RecordType.A));
				zone.AddRange(resolver.Resolve<AaaaRecord>(nsRecord.NameServer, RecordType.Aaaa));
			}

			zone.AddRange(resolver.Resolve<DnsKeyRecord>(DomainName.Root, RecordType.DnsKey).Where(x => x.IsSecureEntryPoint));

			LoadZoneInternal(zone);

			Save(zone);
		}
        /// <summary>
        ///   Forces to update all hints using the given resolver
        /// </summary>
        /// <param name="resolver">The resolver to use for resolving the new hints</param>
#if NETSTANDARD
        public async System.Threading.Tasks.Task UpdateAsync(IDnsResolver resolver)
        {
            Zone zone = new Zone(DomainName.Root);

            var nameServer = await resolver.ResolveAsync <NsRecord>(DomainName.Root, RecordType.Ns);

            zone.AddRange(nameServer);

            var aRecordTasks     = new List <System.Threading.Tasks.Task <List <ARecord> > >(nameServer.Count);
            var aaaaRecordTasks  = new List <System.Threading.Tasks.Task <List <AaaaRecord> > >(nameServer.Count);
            var dnsKeyRecordTask = resolver.ResolveAsync <DnsKeyRecord>(DomainName.Root, RecordType.DnsKey);

            foreach (var nsRecord in nameServer)
            {
                aRecordTasks.Add(resolver.ResolveAsync <ARecord>(nsRecord.NameServer, RecordType.A));
                aaaaRecordTasks.Add(resolver.ResolveAsync <AaaaRecord>(nsRecord.NameServer, RecordType.Aaaa));
            }

            var aRecords = await System.Threading.Tasks.Task.WhenAll(aRecordTasks);

            foreach (var aRecordList in aRecords)
            {
                zone.AddRange(aRecordList);
            }

            var aaaaRecords = await System.Threading.Tasks.Task.WhenAll(aaaaRecordTasks);

            foreach (var aaaaRecordList in aaaaRecords)
            {
                zone.AddRange(aaaaRecordList);
            }

            zone.AddRange((await dnsKeyRecordTask).Where(x => x.IsSecureEntryPoint));

            LoadZoneInternal(zone);

            Save(zone);
        }
예제 #3
0
        private Zone SignWithNSec3(DateTime inception, DateTime expiration, List <DnsKeyRecord> zoneSigningKeys, List <DnsKeyRecord> keySigningKeys, NSec3HashAlgorithm nsec3Algorithm, int nsec3Iterations, byte[] nsec3Salt, bool nsec3OptOut)
        {
            var soaRecord         = _records.OfType <SoaRecord>().First();
            var subZoneNameserver = _records.Where(x => (x.RecordType == RecordType.Ns) && (x.Name != Name)).ToList();
            var subZones          = subZoneNameserver.Select(x => x.Name).Distinct().ToList();
            var unsignedRecords   = _records.Where(x => subZones.Any(y => x.Name.IsSubDomainOf(y))).ToList();           // glue records

            if (nsec3OptOut)
            {
                unsignedRecords = unsignedRecords.Union(subZoneNameserver.Where(x => !_records.Any(y => (y.RecordType == RecordType.Ds) && (y.Name == x.Name)))).ToList();                 // delegations without DS record
            }
            var recordsByName = _records.Except(unsignedRecords).Union(zoneSigningKeys).Union(keySigningKeys).GroupBy(x => x.Name).Select(x => new Tuple <DomainName, List <DnsRecordBase> >(x.Key, x.OrderBy(y => y.RecordType == RecordType.Soa ? -1 : (int)y.RecordType).ToList())).OrderBy(x => x.Item1).ToList();

            byte nsec3RecordFlags = (byte)(nsec3OptOut ? 1 : 0);

            Zone res = new Zone(Name, Count * 3);
            List <NSec3Record> nSec3Records = new List <NSec3Record>(Count);

            if (nsec3Salt == null)
            {
                nsec3Salt = SecureRandom.GetSeed(8);
            }

            recordsByName[0].Item2.Add(new NSec3ParamRecord(soaRecord.Name, soaRecord.RecordClass, 0, nsec3Algorithm, 0, (ushort)nsec3Iterations, nsec3Salt));

            HashSet <DomainName> allNames = new HashSet <DomainName>();

            for (int i = 0; i < recordsByName.Count; i++)
            {
                List <RecordType> recordTypes = new List <RecordType>();

                DomainName currentName = recordsByName[i].Item1;

                foreach (var recordsByType in recordsByName[i].Item2.GroupBy(x => x.RecordType))
                {
                    List <DnsRecordBase> records = recordsByType.ToList();

                    recordTypes.Add(recordsByType.Key);
                    res.AddRange(records);

                    // do not sign nameserver delegations for sub zones
                    if ((records[0].RecordType == RecordType.Ns) && (currentName != Name))
                    {
                        continue;
                    }

                    recordTypes.Add(RecordType.RrSig);

                    foreach (var key in zoneSigningKeys)
                    {
                        res.Add(new RrSigRecord(records, key, inception, expiration));
                    }
                    if (records[0].RecordType == RecordType.DnsKey)
                    {
                        foreach (var key in keySigningKeys)
                        {
                            res.Add(new RrSigRecord(records, key, inception, expiration));
                        }
                    }
                }

                byte[] hash = recordsByName[i].Item1.GetNSec3Hash(nsec3Algorithm, nsec3Iterations, nsec3Salt);
                nSec3Records.Add(new NSec3Record(DomainName.ParseFromMasterfile(hash.ToBase32HexString()) + Name, soaRecord.RecordClass, soaRecord.NegativeCachingTTL, nsec3Algorithm, nsec3RecordFlags, (ushort)nsec3Iterations, nsec3Salt, hash, recordTypes));

                allNames.Add(currentName);
                for (int j = currentName.LabelCount - Name.LabelCount; j > 0; j--)
                {
                    DomainName possibleNonTerminal = currentName.GetParentName(j);

                    if (!allNames.Contains(possibleNonTerminal))
                    {
                        hash = possibleNonTerminal.GetNSec3Hash(nsec3Algorithm, nsec3Iterations, nsec3Salt);
                        nSec3Records.Add(new NSec3Record(DomainName.ParseFromMasterfile(hash.ToBase32HexString()) + Name, soaRecord.RecordClass, soaRecord.NegativeCachingTTL, nsec3Algorithm, nsec3RecordFlags, (ushort)nsec3Iterations, nsec3Salt, hash, new List <RecordType>()));

                        allNames.Add(possibleNonTerminal);
                    }
                }
            }

            nSec3Records = nSec3Records.OrderBy(x => x.Name).ToList();

            byte[] firstNextHashedOwnerName = nSec3Records[0].NextHashedOwnerName;

            for (int i = 1; i < nSec3Records.Count; i++)
            {
                nSec3Records[i - 1].NextHashedOwnerName = nSec3Records[i].NextHashedOwnerName;
            }

            nSec3Records[nSec3Records.Count - 1].NextHashedOwnerName = firstNextHashedOwnerName;

            foreach (var nSec3Record in nSec3Records)
            {
                res.Add(nSec3Record);

                foreach (var key in zoneSigningKeys)
                {
                    res.Add(new RrSigRecord(new List <DnsRecordBase>()
                    {
                        nSec3Record
                    }, key, inception, expiration));
                }
            }

            res.AddRange(unsignedRecords);

            return(res);
        }
예제 #4
0
        private Zone SignWithNSec(DateTime inception, DateTime expiration, List <DnsKeyRecord> zoneSigningKeys, List <DnsKeyRecord> keySigningKeys)
        {
            var soaRecord     = _records.OfType <SoaRecord>().First();
            var subZones      = _records.Where(x => (x.RecordType == RecordType.Ns) && (x.Name != Name)).Select(x => x.Name).Distinct().ToList();
            var glueRecords   = _records.Where(x => subZones.Any(y => x.Name.IsSubDomainOf(y))).ToList();
            var recordsByName = _records.Except(glueRecords).Union(zoneSigningKeys).Union(keySigningKeys).GroupBy(x => x.Name).Select(x => new Tuple <DomainName, List <DnsRecordBase> >(x.Key, x.OrderBy(y => y.RecordType == RecordType.Soa ? -1 : (int)y.RecordType).ToList())).OrderBy(x => x.Item1).ToList();

            Zone res = new Zone(Name, Count * 3);

            for (int i = 0; i < recordsByName.Count; i++)
            {
                List <RecordType> recordTypes = new List <RecordType>();

                DomainName currentName = recordsByName[i].Item1;

                foreach (var recordsByType in recordsByName[i].Item2.GroupBy(x => x.RecordType))
                {
                    List <DnsRecordBase> records = recordsByType.ToList();

                    recordTypes.Add(recordsByType.Key);
                    res.AddRange(records);

                    // do not sign nameserver delegations for sub zones
                    if ((records[0].RecordType == RecordType.Ns) && (currentName != Name))
                    {
                        continue;
                    }

                    recordTypes.Add(RecordType.RrSig);

                    foreach (var key in zoneSigningKeys)
                    {
                        res.Add(new RrSigRecord(records, key, inception, expiration));
                    }
                    if (records[0].RecordType == RecordType.DnsKey)
                    {
                        foreach (var key in keySigningKeys)
                        {
                            res.Add(new RrSigRecord(records, key, inception, expiration));
                        }
                    }
                }

                recordTypes.Add(RecordType.NSec);

                NSecRecord nsecRecord = new NSecRecord(recordsByName[i].Item1, soaRecord.RecordClass, soaRecord.NegativeCachingTTL, recordsByName[(i + 1) % recordsByName.Count].Item1, recordTypes);
                res.Add(nsecRecord);

                foreach (var key in zoneSigningKeys)
                {
                    res.Add(new RrSigRecord(new List <DnsRecordBase>()
                    {
                        nsecRecord
                    }, key, inception, expiration));
                }
            }

            res.AddRange(glueRecords);

            return(res);
        }