Example #1
0
        private void LoadZoneInternal(ZoneCollection zone)
        {
            var nameServers = zone.OfType <NsRecord>().Where(x => x.Name == DomainName.Root).Select(x => x.NameServer);

            RootServers = zone.Where(x => x.RecordType == RecordType.A || x.RecordType == RecordType.Aaaa).Join(nameServers, x => x.Name, x => x, (x, y) => ((IAddressRecord)x).Address).ToList();
            RootKeys    = zone.OfType <DnsKeyRecord>().Where(x => (x.Name == DomainName.Root) && x.IsSecureEntryPoint).Select(x => new DsRecord(x, x.TimeToLive, DnsSecDigestType.Sha256)).ToList();
        }
        /// <summary>
        ///   Loads the hints from the local file
        /// </summary>
        /// <returns></returns>
        protected override ZoneCollection Load()
        {
            if (!File.Exists(_fileName))
            {
                throw new FileNotFoundException();
            }

            return(ZoneCollection.ParseMasterFile(DomainName.Root, _fileName));
        }
 /// <summary>
 ///   Saves the hints to the local file
 /// </summary>
 /// <param name="zone">The zone to save</param>
 protected override void Save(ZoneCollection zone)
 {
     using (StreamWriter writer = new StreamWriter(_fileName))
     {
         foreach (DnsRecordBase record in zone)
         {
             writer.WriteLine(record.ToString());
         }
     }
 }
Example #4
0
        private void EnsureInit()
        {
            if (!_isInitiated)
            {
                ZoneCollection zone = Load();

                LoadZoneInternal(zone);

                _isInitiated = true;
            }
        }
Example #5
0
        /// <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)
        {
            ZoneCollection zone = new ZoneCollection(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);
        }
Example #6
0
 /// <summary>
 ///   Saves the hints to a local storage
 /// </summary>
 /// <param name="zone"></param>
 protected abstract void Save(ZoneCollection zone);
Example #7
0
        private ZoneCollection 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);

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

            if (nsec3Salt == null)
            {
                nsec3Salt = _secureRandom.GenerateSeed(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);
        }
Example #8
0
        private ZoneCollection 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();

            ZoneCollection res = new ZoneCollection(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);
        }