AuthZoneInfo.cs 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174
  1. /*
  2. Technitium DNS Server
  3. Copyright (C) 2024 Shreyas Zare (shreyas@technitium.com)
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. using DnsServerCore.Dns.Dnssec;
  16. using DnsServerCore.Dns.ResourceRecords;
  17. using System;
  18. using System.Collections.Generic;
  19. using System.IO;
  20. using System.Net;
  21. using System.Net.Sockets;
  22. using System.Threading.Tasks;
  23. using TechnitiumLibrary.IO;
  24. using TechnitiumLibrary.Net;
  25. using TechnitiumLibrary.Net.Dns;
  26. using TechnitiumLibrary.Net.Dns.ResourceRecords;
  27. namespace DnsServerCore.Dns.Zones
  28. {
  29. public enum AuthZoneType : byte
  30. {
  31. Unknown = 0,
  32. Primary = 1,
  33. Secondary = 2,
  34. Stub = 3,
  35. Forwarder = 4
  36. }
  37. public sealed class AuthZoneInfo : IComparable<AuthZoneInfo>
  38. {
  39. #region variables
  40. readonly ApexZone _apexZone;
  41. readonly string _name;
  42. readonly AuthZoneType _type;
  43. readonly bool _disabled;
  44. readonly AuthZoneTransfer _zoneTransfer;
  45. readonly IReadOnlyCollection<NetworkAddress> _zoneTransferNameServers;
  46. readonly AuthZoneNotify _notify;
  47. readonly IReadOnlyCollection<IPAddress> _notifyNameServers;
  48. readonly AuthZoneUpdate _update;
  49. readonly IReadOnlyCollection<NetworkAddress> _updateIpAddresses;
  50. readonly DateTime _lastModified;
  51. readonly DateTime _expiry;
  52. readonly IReadOnlyList<DnsResourceRecord> _zoneHistory; //for IXFR support
  53. readonly IReadOnlyDictionary<string, object> _zoneTransferTsigKeyNames;
  54. readonly IReadOnlyDictionary<string, IReadOnlyDictionary<string, IReadOnlyList<DnsResourceRecordType>>> _updateSecurityPolicies;
  55. readonly IReadOnlyCollection<DnssecPrivateKey> _dnssecPrivateKeys;
  56. #endregion
  57. #region constructor
  58. public AuthZoneInfo(string name, AuthZoneType type, bool disabled)
  59. {
  60. _name = name;
  61. _type = type;
  62. _disabled = disabled;
  63. switch (_type)
  64. {
  65. case AuthZoneType.Primary:
  66. _zoneTransfer = AuthZoneTransfer.AllowOnlyZoneNameServers;
  67. _notify = AuthZoneNotify.ZoneNameServers;
  68. _update = AuthZoneUpdate.Deny;
  69. break;
  70. default:
  71. _zoneTransfer = AuthZoneTransfer.Deny;
  72. _notify = AuthZoneNotify.None;
  73. _update = AuthZoneUpdate.Deny;
  74. break;
  75. }
  76. }
  77. public AuthZoneInfo(BinaryReader bR, DateTime lastModified)
  78. {
  79. byte version = bR.ReadByte();
  80. switch (version)
  81. {
  82. case 1:
  83. case 2:
  84. case 3:
  85. case 4:
  86. case 5:
  87. case 6:
  88. case 7:
  89. case 8:
  90. case 9:
  91. case 10:
  92. case 11:
  93. _name = bR.ReadShortString();
  94. _type = (AuthZoneType)bR.ReadByte();
  95. _disabled = bR.ReadBoolean();
  96. if (version >= 2)
  97. {
  98. {
  99. _zoneTransfer = (AuthZoneTransfer)bR.ReadByte();
  100. int count = bR.ReadByte();
  101. if (count > 0)
  102. {
  103. NetworkAddress[] networks = new NetworkAddress[count];
  104. if (version >= 9)
  105. {
  106. for (int i = 0; i < count; i++)
  107. networks[i] = NetworkAddress.ReadFrom(bR);
  108. }
  109. else
  110. {
  111. for (int i = 0; i < count; i++)
  112. {
  113. IPAddress address = IPAddressExtensions.ReadFrom(bR);
  114. switch (address.AddressFamily)
  115. {
  116. case AddressFamily.InterNetwork:
  117. networks[i] = new NetworkAddress(address, 32);
  118. break;
  119. case AddressFamily.InterNetworkV6:
  120. networks[i] = new NetworkAddress(address, 128);
  121. break;
  122. default:
  123. throw new InvalidOperationException();
  124. }
  125. }
  126. }
  127. _zoneTransferNameServers = networks;
  128. }
  129. }
  130. {
  131. _notify = (AuthZoneNotify)bR.ReadByte();
  132. int count = bR.ReadByte();
  133. if (count > 0)
  134. {
  135. IPAddress[] nameServers = new IPAddress[count];
  136. for (int i = 0; i < count; i++)
  137. nameServers[i] = IPAddressExtensions.ReadFrom(bR);
  138. _notifyNameServers = nameServers;
  139. }
  140. }
  141. if (version >= 6)
  142. {
  143. _update = (AuthZoneUpdate)bR.ReadByte();
  144. int count = bR.ReadByte();
  145. if (count > 0)
  146. {
  147. NetworkAddress[] networks = new NetworkAddress[count];
  148. if (version >= 9)
  149. {
  150. for (int i = 0; i < count; i++)
  151. networks[i] = NetworkAddress.ReadFrom(bR);
  152. }
  153. else
  154. {
  155. for (int i = 0; i < count; i++)
  156. {
  157. IPAddress address = IPAddressExtensions.ReadFrom(bR);
  158. switch (address.AddressFamily)
  159. {
  160. case AddressFamily.InterNetwork:
  161. networks[i] = new NetworkAddress(address, 32);
  162. break;
  163. case AddressFamily.InterNetworkV6:
  164. networks[i] = new NetworkAddress(address, 128);
  165. break;
  166. default:
  167. throw new InvalidOperationException();
  168. }
  169. }
  170. }
  171. _updateIpAddresses = networks;
  172. }
  173. }
  174. }
  175. else
  176. {
  177. switch (_type)
  178. {
  179. case AuthZoneType.Primary:
  180. _zoneTransfer = AuthZoneTransfer.AllowOnlyZoneNameServers;
  181. _notify = AuthZoneNotify.ZoneNameServers;
  182. _update = AuthZoneUpdate.Deny;
  183. break;
  184. default:
  185. _zoneTransfer = AuthZoneTransfer.Deny;
  186. _notify = AuthZoneNotify.None;
  187. _update = AuthZoneUpdate.Deny;
  188. break;
  189. }
  190. }
  191. if (version >= 8)
  192. _lastModified = bR.ReadDateTime();
  193. else
  194. _lastModified = lastModified;
  195. switch (_type)
  196. {
  197. case AuthZoneType.Primary:
  198. if (version >= 3)
  199. {
  200. int count = bR.ReadInt32();
  201. DnsResourceRecord[] zoneHistory = new DnsResourceRecord[count];
  202. if (version >= 11)
  203. {
  204. for (int i = 0; i < count; i++)
  205. {
  206. zoneHistory[i] = new DnsResourceRecord(bR.BaseStream);
  207. if (bR.ReadBoolean())
  208. zoneHistory[i].Tag = new HistoryRecordInfo(bR);
  209. }
  210. }
  211. else
  212. {
  213. for (int i = 0; i < count; i++)
  214. {
  215. zoneHistory[i] = new DnsResourceRecord(bR.BaseStream);
  216. zoneHistory[i].Tag = new HistoryRecordInfo(bR);
  217. }
  218. }
  219. _zoneHistory = zoneHistory;
  220. }
  221. if (version >= 4)
  222. {
  223. int count = bR.ReadByte();
  224. Dictionary<string, object> tsigKeyNames = new Dictionary<string, object>(count);
  225. for (int i = 0; i < count; i++)
  226. tsigKeyNames.Add(bR.ReadShortString(), null);
  227. _zoneTransferTsigKeyNames = tsigKeyNames;
  228. }
  229. if (version >= 7)
  230. {
  231. int count = bR.ReadByte();
  232. Dictionary<string, IReadOnlyDictionary<string, IReadOnlyList<DnsResourceRecordType>>> updateSecurityPolicies = new Dictionary<string, IReadOnlyDictionary<string, IReadOnlyList<DnsResourceRecordType>>>(count);
  233. for (int i = 0; i < count; i++)
  234. {
  235. string tsigKeyName = bR.ReadShortString().ToLower();
  236. if (!updateSecurityPolicies.TryGetValue(tsigKeyName, out IReadOnlyDictionary<string, IReadOnlyList<DnsResourceRecordType>> policyMap))
  237. {
  238. policyMap = new Dictionary<string, IReadOnlyList<DnsResourceRecordType>>();
  239. updateSecurityPolicies.Add(tsigKeyName, policyMap);
  240. }
  241. int policyCount = bR.ReadByte();
  242. for (int j = 0; j < policyCount; j++)
  243. {
  244. string domain = bR.ReadShortString().ToLower();
  245. if (!policyMap.TryGetValue(domain, out IReadOnlyList<DnsResourceRecordType> types))
  246. {
  247. types = new List<DnsResourceRecordType>();
  248. (policyMap as Dictionary<string, IReadOnlyList<DnsResourceRecordType>>).Add(domain, types);
  249. }
  250. int typeCount = bR.ReadByte();
  251. for (int k = 0; k < typeCount; k++)
  252. (types as List<DnsResourceRecordType>).Add((DnsResourceRecordType)bR.ReadUInt16());
  253. }
  254. }
  255. _updateSecurityPolicies = updateSecurityPolicies;
  256. }
  257. else if (version >= 6)
  258. {
  259. int count = bR.ReadByte();
  260. Dictionary<string, IReadOnlyDictionary<string, IReadOnlyList<DnsResourceRecordType>>> updateSecurityPolicies = new Dictionary<string, IReadOnlyDictionary<string, IReadOnlyList<DnsResourceRecordType>>>(count);
  261. Dictionary<string, IReadOnlyList<DnsResourceRecordType>> defaultAllowPolicy = new Dictionary<string, IReadOnlyList<DnsResourceRecordType>>(1);
  262. defaultAllowPolicy.Add(_name, new List<DnsResourceRecordType>() { DnsResourceRecordType.ANY });
  263. defaultAllowPolicy.Add("*." + _name, new List<DnsResourceRecordType>() { DnsResourceRecordType.ANY });
  264. for (int i = 0; i < count; i++)
  265. updateSecurityPolicies.Add(bR.ReadShortString().ToLower(), defaultAllowPolicy);
  266. _updateSecurityPolicies = updateSecurityPolicies;
  267. }
  268. if (version >= 5)
  269. {
  270. int count = bR.ReadByte();
  271. if (count > 0)
  272. {
  273. List<DnssecPrivateKey> dnssecPrivateKeys = new List<DnssecPrivateKey>(count);
  274. for (int i = 0; i < count; i++)
  275. dnssecPrivateKeys.Add(DnssecPrivateKey.ReadFrom(bR));
  276. _dnssecPrivateKeys = dnssecPrivateKeys;
  277. }
  278. }
  279. break;
  280. case AuthZoneType.Secondary:
  281. _expiry = bR.ReadDateTime();
  282. if (version >= 4)
  283. {
  284. int count = bR.ReadInt32();
  285. DnsResourceRecord[] zoneHistory = new DnsResourceRecord[count];
  286. if (version >= 11)
  287. {
  288. for (int i = 0; i < count; i++)
  289. {
  290. zoneHistory[i] = new DnsResourceRecord(bR.BaseStream);
  291. if (bR.ReadBoolean())
  292. zoneHistory[i].Tag = new HistoryRecordInfo(bR);
  293. }
  294. }
  295. else
  296. {
  297. for (int i = 0; i < count; i++)
  298. {
  299. zoneHistory[i] = new DnsResourceRecord(bR.BaseStream);
  300. zoneHistory[i].Tag = new HistoryRecordInfo(bR);
  301. }
  302. }
  303. _zoneHistory = zoneHistory;
  304. }
  305. if (version >= 4)
  306. {
  307. int count = bR.ReadByte();
  308. Dictionary<string, object> tsigKeyNames = new Dictionary<string, object>(count);
  309. for (int i = 0; i < count; i++)
  310. tsigKeyNames.Add(bR.ReadShortString(), null);
  311. _zoneTransferTsigKeyNames = tsigKeyNames;
  312. }
  313. if (version == 6)
  314. {
  315. //MUST skip old version data
  316. int count = bR.ReadByte();
  317. Dictionary<string, object> tsigKeyNames = new Dictionary<string, object>(count);
  318. for (int i = 0; i < count; i++)
  319. tsigKeyNames.Add(bR.ReadShortString(), null);
  320. }
  321. break;
  322. case AuthZoneType.Stub:
  323. _expiry = bR.ReadDateTime();
  324. break;
  325. case AuthZoneType.Forwarder:
  326. if (version >= 10)
  327. {
  328. int count = bR.ReadByte();
  329. Dictionary<string, IReadOnlyDictionary<string, IReadOnlyList<DnsResourceRecordType>>> updateSecurityPolicies = new Dictionary<string, IReadOnlyDictionary<string, IReadOnlyList<DnsResourceRecordType>>>(count);
  330. for (int i = 0; i < count; i++)
  331. {
  332. string tsigKeyName = bR.ReadShortString().ToLower();
  333. if (!updateSecurityPolicies.TryGetValue(tsigKeyName, out IReadOnlyDictionary<string, IReadOnlyList<DnsResourceRecordType>> policyMap))
  334. {
  335. policyMap = new Dictionary<string, IReadOnlyList<DnsResourceRecordType>>();
  336. updateSecurityPolicies.Add(tsigKeyName, policyMap);
  337. }
  338. int policyCount = bR.ReadByte();
  339. for (int j = 0; j < policyCount; j++)
  340. {
  341. string domain = bR.ReadShortString().ToLower();
  342. if (!policyMap.TryGetValue(domain, out IReadOnlyList<DnsResourceRecordType> types))
  343. {
  344. types = new List<DnsResourceRecordType>();
  345. (policyMap as Dictionary<string, IReadOnlyList<DnsResourceRecordType>>).Add(domain, types);
  346. }
  347. int typeCount = bR.ReadByte();
  348. for (int k = 0; k < typeCount; k++)
  349. (types as List<DnsResourceRecordType>).Add((DnsResourceRecordType)bR.ReadUInt16());
  350. }
  351. }
  352. _updateSecurityPolicies = updateSecurityPolicies;
  353. }
  354. break;
  355. }
  356. break;
  357. default:
  358. throw new InvalidDataException("AuthZoneInfo format version not supported.");
  359. }
  360. }
  361. internal AuthZoneInfo(ApexZone apexZone, bool loadHistory = false)
  362. {
  363. _apexZone = apexZone;
  364. _name = _apexZone.Name;
  365. if (_apexZone is PrimaryZone primaryZone)
  366. {
  367. _type = AuthZoneType.Primary;
  368. if (loadHistory)
  369. _zoneHistory = primaryZone.GetZoneHistory();
  370. _zoneTransferTsigKeyNames = primaryZone.ZoneTransferTsigKeyNames;
  371. _updateSecurityPolicies = primaryZone.UpdateSecurityPolicies;
  372. _dnssecPrivateKeys = primaryZone.DnssecPrivateKeys;
  373. }
  374. else if (_apexZone is SecondaryZone secondaryZone)
  375. {
  376. _type = AuthZoneType.Secondary;
  377. if (loadHistory)
  378. _zoneHistory = secondaryZone.GetZoneHistory();
  379. _expiry = secondaryZone.Expiry;
  380. _zoneTransferTsigKeyNames = secondaryZone.ZoneTransferTsigKeyNames;
  381. }
  382. else if (_apexZone is StubZone stubZone)
  383. {
  384. _type = AuthZoneType.Stub;
  385. _expiry = stubZone.Expiry;
  386. }
  387. else if (_apexZone is ForwarderZone forwarderZone)
  388. {
  389. _type = AuthZoneType.Forwarder;
  390. _updateSecurityPolicies = forwarderZone.UpdateSecurityPolicies;
  391. }
  392. else
  393. {
  394. _type = AuthZoneType.Unknown;
  395. }
  396. _disabled = _apexZone.Disabled;
  397. _zoneTransfer = _apexZone.ZoneTransfer;
  398. _zoneTransferNameServers = _apexZone.ZoneTransferNameServers;
  399. _notify = _apexZone.Notify;
  400. _notifyNameServers = _apexZone.NotifyNameServers;
  401. _update = _apexZone.Update;
  402. _updateIpAddresses = _apexZone.UpdateIpAddresses;
  403. _lastModified = _apexZone.LastModified;
  404. }
  405. #endregion
  406. #region public
  407. public IReadOnlyList<DnsResourceRecord> GetApexRecords(DnsResourceRecordType type)
  408. {
  409. if (_apexZone is null)
  410. throw new InvalidOperationException();
  411. return _apexZone.GetRecords(type);
  412. }
  413. public void TriggerNotify()
  414. {
  415. if (_apexZone is null)
  416. throw new InvalidOperationException();
  417. switch (_type)
  418. {
  419. case AuthZoneType.Primary:
  420. (_apexZone as PrimaryZone).TriggerNotify();
  421. break;
  422. case AuthZoneType.Secondary:
  423. (_apexZone as SecondaryZone).TriggerNotify();
  424. break;
  425. default:
  426. throw new InvalidOperationException();
  427. }
  428. }
  429. public void TriggerRefresh()
  430. {
  431. if (_apexZone is null)
  432. throw new InvalidOperationException();
  433. switch (_type)
  434. {
  435. case AuthZoneType.Secondary:
  436. (_apexZone as SecondaryZone).TriggerRefresh();
  437. break;
  438. case AuthZoneType.Stub:
  439. (_apexZone as StubZone).TriggerRefresh();
  440. break;
  441. default:
  442. throw new InvalidOperationException();
  443. }
  444. }
  445. public void TriggerResync()
  446. {
  447. if (_apexZone is null)
  448. throw new InvalidOperationException();
  449. switch (_type)
  450. {
  451. case AuthZoneType.Secondary:
  452. (_apexZone as SecondaryZone).TriggerResync();
  453. break;
  454. case AuthZoneType.Stub:
  455. (_apexZone as StubZone).TriggerResync();
  456. break;
  457. default:
  458. throw new InvalidOperationException();
  459. }
  460. }
  461. public Task<IReadOnlyList<NameServerAddress>> GetPrimaryNameServerAddressesAsync(DnsServer dnsServer)
  462. {
  463. if (_apexZone is null)
  464. throw new InvalidOperationException();
  465. return _apexZone.GetPrimaryNameServerAddressesAsync(dnsServer);
  466. }
  467. public Task<IReadOnlyList<NameServerAddress>> GetSecondaryNameServerAddressesAsync(DnsServer dnsServer)
  468. {
  469. if (_apexZone is null)
  470. throw new InvalidOperationException();
  471. return _apexZone.GetSecondaryNameServerAddressesAsync(dnsServer);
  472. }
  473. public void WriteTo(BinaryWriter bW)
  474. {
  475. if (_apexZone is null)
  476. throw new InvalidOperationException();
  477. bW.Write((byte)11); //version
  478. bW.WriteShortString(_name);
  479. bW.Write((byte)_type);
  480. bW.Write(_disabled);
  481. bW.Write((byte)_zoneTransfer);
  482. if (_zoneTransferNameServers is null)
  483. {
  484. bW.Write((byte)0);
  485. }
  486. else
  487. {
  488. bW.Write(Convert.ToByte(_zoneTransferNameServers.Count));
  489. foreach (NetworkAddress networkAddress in _zoneTransferNameServers)
  490. networkAddress.WriteTo(bW);
  491. }
  492. bW.Write((byte)_notify);
  493. if (_notifyNameServers is null)
  494. {
  495. bW.Write((byte)0);
  496. }
  497. else
  498. {
  499. bW.Write(Convert.ToByte(_notifyNameServers.Count));
  500. foreach (IPAddress nameServer in _notifyNameServers)
  501. nameServer.WriteTo(bW);
  502. }
  503. bW.Write((byte)_update);
  504. if (_updateIpAddresses is null)
  505. {
  506. bW.Write((byte)0);
  507. }
  508. else
  509. {
  510. bW.Write(Convert.ToByte(_updateIpAddresses.Count));
  511. foreach (NetworkAddress networkAddress in _updateIpAddresses)
  512. networkAddress.WriteTo(bW);
  513. }
  514. bW.Write(_lastModified);
  515. switch (_type)
  516. {
  517. case AuthZoneType.Primary:
  518. if (_zoneHistory is null)
  519. {
  520. bW.Write(0);
  521. }
  522. else
  523. {
  524. bW.Write(_zoneHistory.Count);
  525. foreach (DnsResourceRecord record in _zoneHistory)
  526. {
  527. record.WriteTo(bW.BaseStream);
  528. if (record.Tag is HistoryRecordInfo rrInfo)
  529. {
  530. bW.Write(true);
  531. rrInfo.WriteTo(bW);
  532. }
  533. else
  534. {
  535. bW.Write(false);
  536. }
  537. }
  538. }
  539. if (_zoneTransferTsigKeyNames is null)
  540. {
  541. bW.Write((byte)0);
  542. }
  543. else
  544. {
  545. bW.Write(Convert.ToByte(_zoneTransferTsigKeyNames.Count));
  546. foreach (KeyValuePair<string, object> tsigKeyName in _zoneTransferTsigKeyNames)
  547. bW.WriteShortString(tsigKeyName.Key);
  548. }
  549. if (_updateSecurityPolicies is null)
  550. {
  551. bW.Write((byte)0);
  552. }
  553. else
  554. {
  555. bW.Write(Convert.ToByte(_updateSecurityPolicies.Count));
  556. foreach (KeyValuePair<string, IReadOnlyDictionary<string, IReadOnlyList<DnsResourceRecordType>>> updateSecurityPolicy in _updateSecurityPolicies)
  557. {
  558. bW.WriteShortString(updateSecurityPolicy.Key);
  559. bW.Write(Convert.ToByte(updateSecurityPolicy.Value.Count));
  560. foreach (KeyValuePair<string, IReadOnlyList<DnsResourceRecordType>> policyMap in updateSecurityPolicy.Value)
  561. {
  562. bW.WriteShortString(policyMap.Key);
  563. bW.Write(Convert.ToByte(policyMap.Value.Count));
  564. foreach (DnsResourceRecordType type in policyMap.Value)
  565. bW.Write((ushort)type);
  566. }
  567. }
  568. }
  569. if (_dnssecPrivateKeys is null)
  570. {
  571. bW.Write((byte)0);
  572. }
  573. else
  574. {
  575. bW.Write(Convert.ToByte(_dnssecPrivateKeys.Count));
  576. foreach (DnssecPrivateKey dnssecPrivateKey in _dnssecPrivateKeys)
  577. dnssecPrivateKey.WriteTo(bW);
  578. }
  579. break;
  580. case AuthZoneType.Secondary:
  581. bW.Write(_expiry);
  582. if (_zoneHistory is null)
  583. {
  584. bW.Write(0);
  585. }
  586. else
  587. {
  588. bW.Write(_zoneHistory.Count);
  589. foreach (DnsResourceRecord record in _zoneHistory)
  590. {
  591. record.WriteTo(bW.BaseStream);
  592. if (record.Tag is HistoryRecordInfo rrInfo)
  593. {
  594. bW.Write(true);
  595. rrInfo.WriteTo(bW);
  596. }
  597. else
  598. {
  599. bW.Write(false);
  600. }
  601. }
  602. }
  603. if (_zoneTransferTsigKeyNames is null)
  604. {
  605. bW.Write((byte)0);
  606. }
  607. else
  608. {
  609. bW.Write(Convert.ToByte(_zoneTransferTsigKeyNames.Count));
  610. foreach (KeyValuePair<string, object> tsigKeyName in _zoneTransferTsigKeyNames)
  611. bW.WriteShortString(tsigKeyName.Key);
  612. }
  613. break;
  614. case AuthZoneType.Stub:
  615. bW.Write(_expiry);
  616. break;
  617. case AuthZoneType.Forwarder:
  618. if (_updateSecurityPolicies is null)
  619. {
  620. bW.Write((byte)0);
  621. }
  622. else
  623. {
  624. bW.Write(Convert.ToByte(_updateSecurityPolicies.Count));
  625. foreach (KeyValuePair<string, IReadOnlyDictionary<string, IReadOnlyList<DnsResourceRecordType>>> updateSecurityPolicy in _updateSecurityPolicies)
  626. {
  627. bW.WriteShortString(updateSecurityPolicy.Key);
  628. bW.Write(Convert.ToByte(updateSecurityPolicy.Value.Count));
  629. foreach (KeyValuePair<string, IReadOnlyList<DnsResourceRecordType>> policyMap in updateSecurityPolicy.Value)
  630. {
  631. bW.WriteShortString(policyMap.Key);
  632. bW.Write(Convert.ToByte(policyMap.Value.Count));
  633. foreach (DnsResourceRecordType type in policyMap.Value)
  634. bW.Write((ushort)type);
  635. }
  636. }
  637. }
  638. break;
  639. }
  640. }
  641. public int CompareTo(AuthZoneInfo other)
  642. {
  643. return _name.CompareTo(other._name);
  644. }
  645. public override bool Equals(object obj)
  646. {
  647. if (ReferenceEquals(this, obj))
  648. return true;
  649. if (obj is not AuthZoneInfo other)
  650. return false;
  651. return _name.Equals(other._name, StringComparison.OrdinalIgnoreCase);
  652. }
  653. public override int GetHashCode()
  654. {
  655. return HashCode.Combine(_name);
  656. }
  657. public override string ToString()
  658. {
  659. return _name;
  660. }
  661. #endregion
  662. #region properties
  663. internal ApexZone ApexZone
  664. { get { return _apexZone; } }
  665. public string Name
  666. { get { return _name; } }
  667. public AuthZoneType Type
  668. { get { return _type; } }
  669. public bool Disabled
  670. {
  671. get
  672. {
  673. if (_apexZone is null)
  674. return _disabled;
  675. return _apexZone.Disabled;
  676. }
  677. set
  678. {
  679. if (_apexZone is null)
  680. throw new InvalidOperationException();
  681. _apexZone.Disabled = value;
  682. }
  683. }
  684. public AuthZoneTransfer ZoneTransfer
  685. {
  686. get
  687. {
  688. if (_apexZone is null)
  689. return _zoneTransfer;
  690. return _apexZone.ZoneTransfer;
  691. }
  692. set
  693. {
  694. if (_apexZone is null)
  695. throw new InvalidOperationException();
  696. _apexZone.ZoneTransfer = value;
  697. }
  698. }
  699. public IReadOnlyCollection<NetworkAddress> ZoneTransferNameServers
  700. {
  701. get
  702. {
  703. if (_apexZone is null)
  704. return _zoneTransferNameServers;
  705. return _apexZone.ZoneTransferNameServers;
  706. }
  707. set
  708. {
  709. if (_apexZone is null)
  710. throw new InvalidOperationException();
  711. _apexZone.ZoneTransferNameServers = value;
  712. }
  713. }
  714. public AuthZoneNotify Notify
  715. {
  716. get
  717. {
  718. if (_apexZone is null)
  719. return _notify;
  720. return _apexZone.Notify;
  721. }
  722. set
  723. {
  724. if (_apexZone is null)
  725. throw new InvalidOperationException();
  726. _apexZone.Notify = value;
  727. }
  728. }
  729. public IReadOnlyCollection<IPAddress> NotifyNameServers
  730. {
  731. get
  732. {
  733. if (_apexZone is null)
  734. return _notifyNameServers;
  735. return _apexZone.NotifyNameServers;
  736. }
  737. set
  738. {
  739. if (_apexZone is null)
  740. throw new InvalidOperationException();
  741. _apexZone.NotifyNameServers = value;
  742. }
  743. }
  744. public AuthZoneUpdate Update
  745. {
  746. get
  747. {
  748. if (_apexZone is null)
  749. return _update;
  750. return _apexZone.Update;
  751. }
  752. set
  753. {
  754. if (_apexZone is null)
  755. throw new InvalidOperationException();
  756. _apexZone.Update = value;
  757. }
  758. }
  759. public IReadOnlyCollection<NetworkAddress> UpdateIpAddresses
  760. {
  761. get
  762. {
  763. if (_apexZone is null)
  764. return _updateIpAddresses;
  765. return _apexZone.UpdateIpAddresses;
  766. }
  767. set
  768. {
  769. if (_apexZone is null)
  770. throw new InvalidOperationException();
  771. _apexZone.UpdateIpAddresses = value;
  772. }
  773. }
  774. public DateTime LastModified
  775. {
  776. get
  777. {
  778. if (_apexZone is null)
  779. return _lastModified;
  780. return _apexZone.LastModified;
  781. }
  782. }
  783. public DateTime Expiry
  784. {
  785. get
  786. {
  787. if (_apexZone is null)
  788. return _expiry;
  789. switch (_type)
  790. {
  791. case AuthZoneType.Secondary:
  792. return (_apexZone as SecondaryZone).Expiry;
  793. case AuthZoneType.Stub:
  794. return (_apexZone as StubZone).Expiry;
  795. default:
  796. throw new InvalidOperationException();
  797. }
  798. }
  799. }
  800. public IReadOnlyList<DnsResourceRecord> ZoneHistory
  801. {
  802. get
  803. {
  804. if (_apexZone is null)
  805. return _zoneHistory;
  806. return _apexZone.GetZoneHistory();
  807. }
  808. }
  809. public IReadOnlyDictionary<string, object> ZoneTransferTsigKeyNames
  810. {
  811. get
  812. {
  813. if (_apexZone is null)
  814. return _zoneTransferTsigKeyNames;
  815. return _apexZone.ZoneTransferTsigKeyNames;
  816. }
  817. set
  818. {
  819. if (_apexZone is null)
  820. throw new InvalidOperationException();
  821. switch (_type)
  822. {
  823. case AuthZoneType.Primary:
  824. case AuthZoneType.Secondary:
  825. _apexZone.ZoneTransferTsigKeyNames = value;
  826. break;
  827. default:
  828. throw new InvalidOperationException();
  829. }
  830. }
  831. }
  832. public IReadOnlyDictionary<string, IReadOnlyDictionary<string, IReadOnlyList<DnsResourceRecordType>>> UpdateSecurityPolicies
  833. {
  834. get
  835. {
  836. if (_apexZone is null)
  837. return _updateSecurityPolicies;
  838. return _apexZone.UpdateSecurityPolicies;
  839. }
  840. set
  841. {
  842. if (_apexZone is null)
  843. throw new InvalidOperationException();
  844. switch (_type)
  845. {
  846. case AuthZoneType.Primary:
  847. case AuthZoneType.Forwarder:
  848. _apexZone.UpdateSecurityPolicies = value;
  849. break;
  850. default:
  851. throw new InvalidOperationException();
  852. }
  853. }
  854. }
  855. public IReadOnlyCollection<DnssecPrivateKey> DnssecPrivateKeys
  856. {
  857. get
  858. {
  859. if (_apexZone is null)
  860. return _dnssecPrivateKeys;
  861. switch (_type)
  862. {
  863. case AuthZoneType.Primary:
  864. return (_apexZone as PrimaryZone).DnssecPrivateKeys;
  865. default:
  866. throw new InvalidOperationException();
  867. }
  868. }
  869. }
  870. public AuthZoneDnssecStatus DnssecStatus
  871. {
  872. get
  873. {
  874. if (_apexZone is null)
  875. throw new InvalidOperationException();
  876. return _apexZone.DnssecStatus;
  877. }
  878. }
  879. public uint DnsKeyTtl
  880. {
  881. get
  882. {
  883. if (_apexZone is null)
  884. throw new InvalidOperationException();
  885. switch (_type)
  886. {
  887. case AuthZoneType.Primary:
  888. return (_apexZone as PrimaryZone).GetDnsKeyTtl();
  889. default:
  890. throw new InvalidOperationException();
  891. }
  892. }
  893. }
  894. public bool Internal
  895. {
  896. get
  897. {
  898. if (_apexZone is null)
  899. throw new InvalidOperationException();
  900. switch (_type)
  901. {
  902. case AuthZoneType.Primary:
  903. return (_apexZone as PrimaryZone).Internal;
  904. default:
  905. return false;
  906. }
  907. }
  908. }
  909. public bool IsExpired
  910. {
  911. get
  912. {
  913. if (_apexZone is null)
  914. throw new InvalidOperationException();
  915. switch (_type)
  916. {
  917. case AuthZoneType.Secondary:
  918. return (_apexZone as SecondaryZone).IsExpired;
  919. case AuthZoneType.Stub:
  920. return (_apexZone as StubZone).IsExpired;
  921. default:
  922. return false;
  923. }
  924. }
  925. }
  926. public string[] NotifyFailed
  927. {
  928. get
  929. {
  930. if (_apexZone is null)
  931. throw new InvalidOperationException();
  932. switch (_type)
  933. {
  934. case AuthZoneType.Primary:
  935. return (_apexZone as PrimaryZone).NotifyFailed;
  936. case AuthZoneType.Secondary:
  937. return (_apexZone as SecondaryZone).NotifyFailed;
  938. default:
  939. throw new InvalidOperationException();
  940. }
  941. }
  942. }
  943. public bool SyncFailed
  944. {
  945. get
  946. {
  947. if (_apexZone is null)
  948. throw new InvalidOperationException();
  949. switch (_type)
  950. {
  951. case AuthZoneType.Secondary:
  952. return (_apexZone as SecondaryZone).SyncFailed;
  953. case AuthZoneType.Stub:
  954. return (_apexZone as StubZone).SyncFailed;
  955. default:
  956. throw new InvalidOperationException();
  957. }
  958. }
  959. }
  960. #endregion
  961. }
  962. }