WebServiceSettingsApi.cs 103 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122
  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.Auth;
  16. using DnsServerCore.Dns;
  17. using Microsoft.AspNetCore.Http;
  18. using System;
  19. using System.Collections.Generic;
  20. using System.Collections.Immutable;
  21. using System.IO;
  22. using System.IO.Compression;
  23. using System.Linq;
  24. using System.Net;
  25. using System.Net.Mail;
  26. using System.Net.Sockets;
  27. using System.Text;
  28. using System.Text.Json;
  29. using System.Threading;
  30. using System.Threading.Tasks;
  31. using TechnitiumLibrary;
  32. using TechnitiumLibrary.Net;
  33. using TechnitiumLibrary.Net.Dns;
  34. using TechnitiumLibrary.Net.Dns.ClientConnection;
  35. using TechnitiumLibrary.Net.Dns.ResourceRecords;
  36. using TechnitiumLibrary.Net.Proxy;
  37. namespace DnsServerCore
  38. {
  39. sealed class WebServiceSettingsApi : IDisposable
  40. {
  41. #region variables
  42. static readonly char[] _commaSeparator = new char[] { ',' };
  43. readonly DnsWebService _dnsWebService;
  44. Timer _blockListUpdateTimer;
  45. DateTime _blockListLastUpdatedOn;
  46. int _blockListUpdateIntervalHours = 24;
  47. const int BLOCK_LIST_UPDATE_TIMER_INITIAL_INTERVAL = 5000;
  48. const int BLOCK_LIST_UPDATE_TIMER_PERIODIC_INTERVAL = 900000;
  49. Timer _temporaryDisableBlockingTimer;
  50. DateTime _temporaryDisableBlockingTill;
  51. #endregion
  52. #region constructor
  53. public WebServiceSettingsApi(DnsWebService dnsWebService)
  54. {
  55. _dnsWebService = dnsWebService;
  56. }
  57. #endregion
  58. #region IDisposable
  59. bool _disposed;
  60. public void Dispose()
  61. {
  62. if (_disposed)
  63. return;
  64. if (_blockListUpdateTimer is not null)
  65. _blockListUpdateTimer.Dispose();
  66. if (_temporaryDisableBlockingTimer is not null)
  67. _temporaryDisableBlockingTimer.Dispose();
  68. _disposed = true;
  69. }
  70. #endregion
  71. #region block list
  72. private void ForceUpdateBlockLists(bool forceReload)
  73. {
  74. Task.Run(async delegate ()
  75. {
  76. if (await _dnsWebService.DnsServer.BlockListZoneManager.UpdateBlockListsAsync(forceReload))
  77. {
  78. //block lists were updated
  79. //save last updated on time
  80. _blockListLastUpdatedOn = DateTime.UtcNow;
  81. _dnsWebService.SaveConfigFile();
  82. }
  83. });
  84. }
  85. public void StartBlockListUpdateTimer(bool forceUpdateAndReload)
  86. {
  87. if (_blockListUpdateTimer is null)
  88. {
  89. if (forceUpdateAndReload)
  90. _blockListLastUpdatedOn = default;
  91. _blockListUpdateTimer = new Timer(async delegate (object state)
  92. {
  93. try
  94. {
  95. if (DateTime.UtcNow > _blockListLastUpdatedOn.AddHours(_blockListUpdateIntervalHours))
  96. {
  97. if (await _dnsWebService.DnsServer.BlockListZoneManager.UpdateBlockListsAsync(_blockListLastUpdatedOn == default))
  98. {
  99. //block lists were updated
  100. //save last updated on time
  101. _blockListLastUpdatedOn = DateTime.UtcNow;
  102. _dnsWebService.SaveConfigFile();
  103. }
  104. }
  105. }
  106. catch (Exception ex)
  107. {
  108. _dnsWebService._log.Write("DNS Server encountered an error while updating block lists.\r\n" + ex.ToString());
  109. }
  110. }, null, BLOCK_LIST_UPDATE_TIMER_INITIAL_INTERVAL, BLOCK_LIST_UPDATE_TIMER_PERIODIC_INTERVAL);
  111. }
  112. }
  113. public void StopBlockListUpdateTimer()
  114. {
  115. if (_blockListUpdateTimer is not null)
  116. {
  117. _blockListUpdateTimer.Dispose();
  118. _blockListUpdateTimer = null;
  119. }
  120. }
  121. public void StopTemporaryDisableBlockingTimer()
  122. {
  123. Timer temporaryDisableBlockingTimer = _temporaryDisableBlockingTimer;
  124. if (temporaryDisableBlockingTimer is not null)
  125. temporaryDisableBlockingTimer.Dispose();
  126. }
  127. #endregion
  128. #region private
  129. private void RestartService(bool restartDnsService, bool restartWebService, IReadOnlyList<IPAddress> oldWebServiceLocalAddresses, int oldWebServiceHttpPort, int oldWebServiceTlsPort)
  130. {
  131. if (restartDnsService)
  132. {
  133. _ = Task.Run(async delegate ()
  134. {
  135. _dnsWebService._log.Write("Attempting to restart DNS service.");
  136. try
  137. {
  138. await _dnsWebService.DnsServer.StopAsync();
  139. await _dnsWebService.DnsServer.StartAsync();
  140. _dnsWebService._log.Write("DNS service was restarted successfully.");
  141. }
  142. catch (Exception ex)
  143. {
  144. _dnsWebService._log.Write("Failed to restart DNS service.\r\n" + ex.ToString());
  145. }
  146. });
  147. }
  148. if (restartWebService)
  149. {
  150. _ = Task.Run(async delegate ()
  151. {
  152. await Task.Delay(2000); //wait for this HTTP response to be delivered before stopping web server
  153. _dnsWebService._log.Write("Attempting to restart web service.");
  154. try
  155. {
  156. await _dnsWebService.StopWebServiceAsync();
  157. await _dnsWebService.TryStartWebServiceAsync(oldWebServiceLocalAddresses, oldWebServiceHttpPort, oldWebServiceTlsPort);
  158. _dnsWebService._log.Write("Web service was restarted successfully.");
  159. }
  160. catch (Exception ex)
  161. {
  162. _dnsWebService._log.Write("Failed to restart web service.\r\n" + ex.ToString());
  163. }
  164. });
  165. }
  166. }
  167. private static async Task CreateBackupEntryFromFileAsync(ZipArchive backupZip, string sourceFileName, string entryName)
  168. {
  169. using (FileStream fS = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
  170. {
  171. ZipArchiveEntry entry = backupZip.CreateEntry(entryName);
  172. DateTime lastWrite = File.GetLastWriteTime(sourceFileName);
  173. // If file to be archived has an invalid last modified time, use the first datetime representable in the Zip timestamp format
  174. // (midnight on January 1, 1980):
  175. if (lastWrite.Year < 1980 || lastWrite.Year > 2107)
  176. lastWrite = new DateTime(1980, 1, 1, 0, 0, 0);
  177. entry.LastWriteTime = lastWrite;
  178. using (Stream sE = entry.Open())
  179. {
  180. await fS.CopyToAsync(sE);
  181. }
  182. }
  183. }
  184. private void WriteDnsSettings(Utf8JsonWriter jsonWriter)
  185. {
  186. //general
  187. jsonWriter.WriteString("version", _dnsWebService.GetServerVersion());
  188. jsonWriter.WriteString("uptimestamp", _dnsWebService._uptimestamp);
  189. jsonWriter.WriteString("dnsServerDomain", _dnsWebService.DnsServer.ServerDomain);
  190. jsonWriter.WriteStringArray("dnsServerLocalEndPoints", _dnsWebService.DnsServer.LocalEndPoints);
  191. jsonWriter.WriteStringArray("dnsServerIPv4SourceAddresses", DnsClientConnection.IPv4SourceAddresses);
  192. jsonWriter.WriteStringArray("dnsServerIPv6SourceAddresses", DnsClientConnection.IPv6SourceAddresses);
  193. jsonWriter.WriteNumber("defaultRecordTtl", _dnsWebService._zonesApi.DefaultRecordTtl);
  194. jsonWriter.WriteString("defaultResponsiblePerson", _dnsWebService.DnsServer.ResponsiblePersonInternal?.Address);
  195. jsonWriter.WriteBoolean("useSoaSerialDateScheme", _dnsWebService.DnsServer.AuthZoneManager.UseSoaSerialDateScheme);
  196. jsonWriter.WriteStringArray("zoneTransferAllowedNetworks", _dnsWebService.DnsServer.ZoneTransferAllowedNetworks);
  197. jsonWriter.WriteStringArray("notifyAllowedNetworks", _dnsWebService.DnsServer.NotifyAllowedNetworks);
  198. jsonWriter.WriteBoolean("dnsAppsEnableAutomaticUpdate", _dnsWebService._appsApi.EnableAutomaticUpdate);
  199. jsonWriter.WriteBoolean("preferIPv6", _dnsWebService.DnsServer.PreferIPv6);
  200. jsonWriter.WriteNumber("udpPayloadSize", _dnsWebService.DnsServer.UdpPayloadSize);
  201. jsonWriter.WriteBoolean("dnssecValidation", _dnsWebService.DnsServer.DnssecValidation);
  202. jsonWriter.WriteBoolean("eDnsClientSubnet", _dnsWebService.DnsServer.EDnsClientSubnet);
  203. jsonWriter.WriteNumber("eDnsClientSubnetIPv4PrefixLength", _dnsWebService.DnsServer.EDnsClientSubnetIPv4PrefixLength);
  204. jsonWriter.WriteNumber("eDnsClientSubnetIPv6PrefixLength", _dnsWebService.DnsServer.EDnsClientSubnetIPv6PrefixLength);
  205. jsonWriter.WriteString("eDnsClientSubnetIpv4Override", _dnsWebService.DnsServer.EDnsClientSubnetIpv4Override?.ToString());
  206. jsonWriter.WriteString("eDnsClientSubnetIpv6Override", _dnsWebService.DnsServer.EDnsClientSubnetIpv6Override?.ToString());
  207. jsonWriter.WriteNumber("qpmLimitRequests", _dnsWebService.DnsServer.QpmLimitRequests);
  208. jsonWriter.WriteNumber("qpmLimitErrors", _dnsWebService.DnsServer.QpmLimitErrors);
  209. jsonWriter.WriteNumber("qpmLimitSampleMinutes", _dnsWebService.DnsServer.QpmLimitSampleMinutes);
  210. jsonWriter.WriteNumber("qpmLimitIPv4PrefixLength", _dnsWebService.DnsServer.QpmLimitIPv4PrefixLength);
  211. jsonWriter.WriteNumber("qpmLimitIPv6PrefixLength", _dnsWebService.DnsServer.QpmLimitIPv6PrefixLength);
  212. jsonWriter.WritePropertyName("qpmLimitBypassList");
  213. jsonWriter.WriteStartArray();
  214. if (_dnsWebService.DnsServer.QpmLimitBypassList is not null)
  215. {
  216. foreach (NetworkAddress network in _dnsWebService.DnsServer.QpmLimitBypassList)
  217. jsonWriter.WriteStringValue(network.ToString());
  218. }
  219. jsonWriter.WriteEndArray();
  220. jsonWriter.WriteNumber("clientTimeout", _dnsWebService.DnsServer.ClientTimeout);
  221. jsonWriter.WriteNumber("tcpSendTimeout", _dnsWebService.DnsServer.TcpSendTimeout);
  222. jsonWriter.WriteNumber("tcpReceiveTimeout", _dnsWebService.DnsServer.TcpReceiveTimeout);
  223. jsonWriter.WriteNumber("quicIdleTimeout", _dnsWebService.DnsServer.QuicIdleTimeout);
  224. jsonWriter.WriteNumber("quicMaxInboundStreams", _dnsWebService.DnsServer.QuicMaxInboundStreams);
  225. jsonWriter.WriteNumber("listenBacklog", _dnsWebService.DnsServer.ListenBacklog);
  226. //web service
  227. jsonWriter.WritePropertyName("webServiceLocalAddresses");
  228. jsonWriter.WriteStartArray();
  229. foreach (IPAddress localAddress in _dnsWebService._webServiceLocalAddresses)
  230. {
  231. if (localAddress.AddressFamily == AddressFamily.InterNetworkV6)
  232. jsonWriter.WriteStringValue("[" + localAddress.ToString() + "]");
  233. else
  234. jsonWriter.WriteStringValue(localAddress.ToString());
  235. }
  236. jsonWriter.WriteEndArray();
  237. jsonWriter.WriteNumber("webServiceHttpPort", _dnsWebService._webServiceHttpPort);
  238. jsonWriter.WriteBoolean("webServiceEnableTls", _dnsWebService._webServiceEnableTls);
  239. jsonWriter.WriteBoolean("webServiceEnableHttp3", _dnsWebService._webServiceEnableHttp3);
  240. jsonWriter.WriteBoolean("webServiceHttpToTlsRedirect", _dnsWebService._webServiceHttpToTlsRedirect);
  241. jsonWriter.WriteBoolean("webServiceUseSelfSignedTlsCertificate", _dnsWebService._webServiceUseSelfSignedTlsCertificate);
  242. jsonWriter.WriteNumber("webServiceTlsPort", _dnsWebService._webServiceTlsPort);
  243. jsonWriter.WriteString("webServiceTlsCertificatePath", _dnsWebService._webServiceTlsCertificatePath);
  244. jsonWriter.WriteString("webServiceTlsCertificatePassword", "************");
  245. jsonWriter.WriteString("webServiceRealIpHeader", _dnsWebService._webServiceRealIpHeader);
  246. //optional protocols
  247. jsonWriter.WriteBoolean("enableDnsOverUdpProxy", _dnsWebService.DnsServer.EnableDnsOverUdpProxy);
  248. jsonWriter.WriteBoolean("enableDnsOverTcpProxy", _dnsWebService.DnsServer.EnableDnsOverTcpProxy);
  249. jsonWriter.WriteBoolean("enableDnsOverHttp", _dnsWebService.DnsServer.EnableDnsOverHttp);
  250. jsonWriter.WriteBoolean("enableDnsOverTls", _dnsWebService.DnsServer.EnableDnsOverTls);
  251. jsonWriter.WriteBoolean("enableDnsOverHttps", _dnsWebService.DnsServer.EnableDnsOverHttps);
  252. jsonWriter.WriteBoolean("enableDnsOverHttp3", _dnsWebService.DnsServer.EnableDnsOverHttp3);
  253. jsonWriter.WriteBoolean("enableDnsOverQuic", _dnsWebService.DnsServer.EnableDnsOverQuic);
  254. jsonWriter.WriteNumber("dnsOverUdpProxyPort", _dnsWebService.DnsServer.DnsOverUdpProxyPort);
  255. jsonWriter.WriteNumber("dnsOverTcpProxyPort", _dnsWebService.DnsServer.DnsOverTcpProxyPort);
  256. jsonWriter.WriteNumber("dnsOverHttpPort", _dnsWebService.DnsServer.DnsOverHttpPort);
  257. jsonWriter.WriteNumber("dnsOverTlsPort", _dnsWebService.DnsServer.DnsOverTlsPort);
  258. jsonWriter.WriteNumber("dnsOverHttpsPort", _dnsWebService.DnsServer.DnsOverHttpsPort);
  259. jsonWriter.WriteNumber("dnsOverQuicPort", _dnsWebService.DnsServer.DnsOverQuicPort);
  260. jsonWriter.WriteString("dnsTlsCertificatePath", _dnsWebService._dnsTlsCertificatePath);
  261. jsonWriter.WriteString("dnsTlsCertificatePassword", "************");
  262. jsonWriter.WriteString("dnsOverHttpRealIpHeader", _dnsWebService.DnsServer.DnsOverHttpRealIpHeader);
  263. //tsig
  264. jsonWriter.WritePropertyName("tsigKeys");
  265. {
  266. jsonWriter.WriteStartArray();
  267. if (_dnsWebService.DnsServer.TsigKeys is not null)
  268. {
  269. foreach (KeyValuePair<string, TsigKey> tsigKey in _dnsWebService.DnsServer.TsigKeys.ToImmutableSortedDictionary())
  270. {
  271. jsonWriter.WriteStartObject();
  272. jsonWriter.WriteString("keyName", tsigKey.Key);
  273. jsonWriter.WriteString("sharedSecret", tsigKey.Value.SharedSecret);
  274. jsonWriter.WriteString("algorithmName", tsigKey.Value.AlgorithmName);
  275. jsonWriter.WriteEndObject();
  276. }
  277. }
  278. jsonWriter.WriteEndArray();
  279. }
  280. //recursion
  281. jsonWriter.WriteString("recursion", _dnsWebService.DnsServer.Recursion.ToString());
  282. jsonWriter.WritePropertyName("recursionNetworkACL");
  283. {
  284. jsonWriter.WriteStartArray();
  285. if (_dnsWebService.DnsServer.RecursionNetworkACL is not null)
  286. {
  287. foreach (NetworkAccessControl nac in _dnsWebService.DnsServer.RecursionNetworkACL)
  288. jsonWriter.WriteStringValue(nac.ToString());
  289. }
  290. jsonWriter.WriteEndArray();
  291. }
  292. jsonWriter.WriteBoolean("randomizeName", _dnsWebService.DnsServer.RandomizeName);
  293. jsonWriter.WriteBoolean("qnameMinimization", _dnsWebService.DnsServer.QnameMinimization);
  294. jsonWriter.WriteBoolean("nsRevalidation", _dnsWebService.DnsServer.NsRevalidation);
  295. jsonWriter.WriteNumber("resolverRetries", _dnsWebService.DnsServer.ResolverRetries);
  296. jsonWriter.WriteNumber("resolverTimeout", _dnsWebService.DnsServer.ResolverTimeout);
  297. jsonWriter.WriteNumber("resolverConcurrency", _dnsWebService.DnsServer.ResolverConcurrency);
  298. jsonWriter.WriteNumber("resolverMaxStackCount", _dnsWebService.DnsServer.ResolverMaxStackCount);
  299. //cache
  300. jsonWriter.WriteBoolean("saveCache", _dnsWebService._saveCache);
  301. jsonWriter.WriteBoolean("serveStale", _dnsWebService.DnsServer.ServeStale);
  302. jsonWriter.WriteNumber("serveStaleTtl", _dnsWebService.DnsServer.CacheZoneManager.ServeStaleTtl);
  303. jsonWriter.WriteNumber("serveStaleAnswerTtl", _dnsWebService.DnsServer.CacheZoneManager.ServeStaleAnswerTtl);
  304. jsonWriter.WriteNumber("serveStaleResetTtl", _dnsWebService.DnsServer.CacheZoneManager.ServeStaleResetTtl);
  305. jsonWriter.WriteNumber("serveStaleMaxWaitTime", _dnsWebService.DnsServer.ServeStaleMaxWaitTime);
  306. jsonWriter.WriteNumber("cacheMaximumEntries", _dnsWebService.DnsServer.CacheZoneManager.MaximumEntries);
  307. jsonWriter.WriteNumber("cacheMinimumRecordTtl", _dnsWebService.DnsServer.CacheZoneManager.MinimumRecordTtl);
  308. jsonWriter.WriteNumber("cacheMaximumRecordTtl", _dnsWebService.DnsServer.CacheZoneManager.MaximumRecordTtl);
  309. jsonWriter.WriteNumber("cacheNegativeRecordTtl", _dnsWebService.DnsServer.CacheZoneManager.NegativeRecordTtl);
  310. jsonWriter.WriteNumber("cacheFailureRecordTtl", _dnsWebService.DnsServer.CacheZoneManager.FailureRecordTtl);
  311. jsonWriter.WriteNumber("cachePrefetchEligibility", _dnsWebService.DnsServer.CachePrefetchEligibility);
  312. jsonWriter.WriteNumber("cachePrefetchTrigger", _dnsWebService.DnsServer.CachePrefetchTrigger);
  313. jsonWriter.WriteNumber("cachePrefetchSampleIntervalInMinutes", _dnsWebService.DnsServer.CachePrefetchSampleIntervalInMinutes);
  314. jsonWriter.WriteNumber("cachePrefetchSampleEligibilityHitsPerHour", _dnsWebService.DnsServer.CachePrefetchSampleEligibilityHitsPerHour);
  315. //blocking
  316. jsonWriter.WriteBoolean("enableBlocking", _dnsWebService.DnsServer.EnableBlocking);
  317. jsonWriter.WriteBoolean("allowTxtBlockingReport", _dnsWebService.DnsServer.AllowTxtBlockingReport);
  318. jsonWriter.WritePropertyName("blockingBypassList");
  319. jsonWriter.WriteStartArray();
  320. if (_dnsWebService.DnsServer.BlockingBypassList is not null)
  321. {
  322. foreach (NetworkAddress network in _dnsWebService.DnsServer.BlockingBypassList)
  323. jsonWriter.WriteStringValue(network.ToString());
  324. }
  325. jsonWriter.WriteEndArray();
  326. if (!_dnsWebService.DnsServer.EnableBlocking && (DateTime.UtcNow < _temporaryDisableBlockingTill))
  327. jsonWriter.WriteString("temporaryDisableBlockingTill", _temporaryDisableBlockingTill);
  328. jsonWriter.WriteString("blockingType", _dnsWebService.DnsServer.BlockingType.ToString());
  329. jsonWriter.WriteNumber("blockingAnswerTtl", _dnsWebService.DnsServer.BlockingAnswerTtl);
  330. jsonWriter.WritePropertyName("customBlockingAddresses");
  331. jsonWriter.WriteStartArray();
  332. foreach (DnsARecordData record in _dnsWebService.DnsServer.CustomBlockingARecords)
  333. jsonWriter.WriteStringValue(record.Address.ToString());
  334. foreach (DnsAAAARecordData record in _dnsWebService.DnsServer.CustomBlockingAAAARecords)
  335. jsonWriter.WriteStringValue(record.Address.ToString());
  336. jsonWriter.WriteEndArray();
  337. jsonWriter.WritePropertyName("blockListUrls");
  338. if ((_dnsWebService.DnsServer.BlockListZoneManager.AllowListUrls.Count == 0) && (_dnsWebService.DnsServer.BlockListZoneManager.BlockListUrls.Count == 0))
  339. {
  340. jsonWriter.WriteNullValue();
  341. }
  342. else
  343. {
  344. jsonWriter.WriteStartArray();
  345. foreach (Uri allowListUrl in _dnsWebService.DnsServer.BlockListZoneManager.AllowListUrls)
  346. jsonWriter.WriteStringValue("!" + allowListUrl.AbsoluteUri);
  347. foreach (Uri blockListUrl in _dnsWebService.DnsServer.BlockListZoneManager.BlockListUrls)
  348. jsonWriter.WriteStringValue(blockListUrl.AbsoluteUri);
  349. jsonWriter.WriteEndArray();
  350. }
  351. jsonWriter.WriteNumber("blockListUpdateIntervalHours", _blockListUpdateIntervalHours);
  352. if (_blockListUpdateTimer is not null)
  353. {
  354. DateTime blockListNextUpdatedOn = _blockListLastUpdatedOn.AddHours(_blockListUpdateIntervalHours);
  355. jsonWriter.WriteString("blockListNextUpdatedOn", blockListNextUpdatedOn);
  356. }
  357. //proxy & forwarders
  358. jsonWriter.WritePropertyName("proxy");
  359. if (_dnsWebService.DnsServer.Proxy == null)
  360. {
  361. jsonWriter.WriteNullValue();
  362. }
  363. else
  364. {
  365. jsonWriter.WriteStartObject();
  366. NetProxy proxy = _dnsWebService.DnsServer.Proxy;
  367. jsonWriter.WriteString("type", proxy.Type.ToString());
  368. jsonWriter.WriteString("address", proxy.Address);
  369. jsonWriter.WriteNumber("port", proxy.Port);
  370. NetworkCredential credential = proxy.Credential;
  371. if (credential != null)
  372. {
  373. jsonWriter.WriteString("username", credential.UserName);
  374. jsonWriter.WriteString("password", credential.Password);
  375. }
  376. jsonWriter.WritePropertyName("bypass");
  377. jsonWriter.WriteStartArray();
  378. foreach (NetProxyBypassItem item in proxy.BypassList)
  379. jsonWriter.WriteStringValue(item.Value);
  380. jsonWriter.WriteEndArray();
  381. jsonWriter.WriteEndObject();
  382. }
  383. jsonWriter.WritePropertyName("forwarders");
  384. DnsTransportProtocol forwarderProtocol = DnsTransportProtocol.Udp;
  385. if (_dnsWebService.DnsServer.Forwarders == null)
  386. {
  387. jsonWriter.WriteNullValue();
  388. }
  389. else
  390. {
  391. forwarderProtocol = _dnsWebService.DnsServer.Forwarders[0].Protocol;
  392. jsonWriter.WriteStartArray();
  393. foreach (NameServerAddress forwarder in _dnsWebService.DnsServer.Forwarders)
  394. jsonWriter.WriteStringValue(forwarder.OriginalAddress);
  395. jsonWriter.WriteEndArray();
  396. }
  397. jsonWriter.WriteString("forwarderProtocol", forwarderProtocol.ToString());
  398. jsonWriter.WriteBoolean("concurrentForwarding", _dnsWebService.DnsServer.ConcurrentForwarding);
  399. jsonWriter.WriteNumber("forwarderRetries", _dnsWebService.DnsServer.ForwarderRetries);
  400. jsonWriter.WriteNumber("forwarderTimeout", _dnsWebService.DnsServer.ForwarderTimeout);
  401. jsonWriter.WriteNumber("forwarderConcurrency", _dnsWebService.DnsServer.ForwarderConcurrency);
  402. //logging
  403. jsonWriter.WriteBoolean("enableLogging", _dnsWebService._log.EnableLogging);
  404. jsonWriter.WriteBoolean("ignoreResolverLogs", _dnsWebService.DnsServer.ResolverLogManager == null);
  405. jsonWriter.WriteBoolean("logQueries", _dnsWebService.DnsServer.QueryLogManager != null);
  406. jsonWriter.WriteBoolean("useLocalTime", _dnsWebService._log.UseLocalTime);
  407. jsonWriter.WriteString("logFolder", _dnsWebService._log.LogFolder);
  408. jsonWriter.WriteNumber("maxLogFileDays", _dnsWebService._log.MaxLogFileDays);
  409. jsonWriter.WriteBoolean("enableInMemoryStats", _dnsWebService.DnsServer.StatsManager.EnableInMemoryStats);
  410. jsonWriter.WriteNumber("maxStatFileDays", _dnsWebService.DnsServer.StatsManager.MaxStatFileDays);
  411. }
  412. private static List<NetworkAddress> ParseNetworkAddresses(string networkAddresses)
  413. {
  414. if ((networkAddresses.Length == 0) || networkAddresses.Equals("false", StringComparison.OrdinalIgnoreCase))
  415. return null;
  416. string[] addresses = networkAddresses.Split(_commaSeparator, StringSplitOptions.RemoveEmptyEntries);
  417. List<NetworkAddress> networks = new List<NetworkAddress>(addresses.Length);
  418. foreach (string address in addresses)
  419. {
  420. if (NetworkAddress.TryParse(address, out NetworkAddress networkAddress))
  421. networks.Add(networkAddress);
  422. }
  423. return networks;
  424. }
  425. #endregion
  426. #region public
  427. public void GetDnsSettings(HttpContext context)
  428. {
  429. UserSession session = context.GetCurrentSession();
  430. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Settings, session.User, PermissionFlag.View))
  431. throw new DnsWebServiceException("Access was denied.");
  432. Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
  433. WriteDnsSettings(jsonWriter);
  434. }
  435. public void SetDnsSettings(HttpContext context)
  436. {
  437. UserSession session = context.GetCurrentSession();
  438. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Settings, session.User, PermissionFlag.Modify))
  439. throw new DnsWebServiceException("Access was denied.");
  440. bool serverDomainChanged = false;
  441. bool restartDnsService = false;
  442. bool restartWebService = false;
  443. bool blockListUrlsUpdated = false;
  444. IReadOnlyList<IPAddress> oldWebServiceLocalAddresses = _dnsWebService._webServiceLocalAddresses;
  445. int oldWebServiceHttpPort = _dnsWebService._webServiceHttpPort;
  446. int oldWebServiceTlsPort = _dnsWebService._webServiceTlsPort;
  447. bool _webServiceEnablingTls = false;
  448. HttpRequest request = context.Request;
  449. //general
  450. if (request.TryGetQueryOrForm("dnsServerDomain", out string dnsServerDomain))
  451. {
  452. dnsServerDomain = dnsServerDomain.TrimEnd('.');
  453. if (!_dnsWebService.DnsServer.ServerDomain.Equals(dnsServerDomain, StringComparison.OrdinalIgnoreCase))
  454. {
  455. _dnsWebService.DnsServer.ServerDomain = dnsServerDomain;
  456. serverDomainChanged = true;
  457. }
  458. }
  459. string dnsServerLocalEndPoints = request.QueryOrForm("dnsServerLocalEndPoints");
  460. if (dnsServerLocalEndPoints is not null)
  461. {
  462. if (dnsServerLocalEndPoints.Length == 0)
  463. dnsServerLocalEndPoints = "0.0.0.0:53,[::]:53";
  464. IPEndPoint[] localEndPoints = dnsServerLocalEndPoints.Split(IPEndPoint.Parse, ',');
  465. if (localEndPoints.Length > 0)
  466. {
  467. foreach (IPEndPoint localEndPoint in localEndPoints)
  468. {
  469. if (localEndPoint.Port == 0)
  470. localEndPoint.Port = 53;
  471. }
  472. if (_dnsWebService.DnsServer.LocalEndPoints.Count != localEndPoints.Length)
  473. {
  474. restartDnsService = true;
  475. }
  476. else
  477. {
  478. foreach (IPEndPoint currentLocalEP in _dnsWebService.DnsServer.LocalEndPoints)
  479. {
  480. if (!localEndPoints.Contains(currentLocalEP))
  481. {
  482. restartDnsService = true;
  483. break;
  484. }
  485. }
  486. }
  487. _dnsWebService.DnsServer.LocalEndPoints = localEndPoints;
  488. }
  489. }
  490. string dnsServerIPv4SourceAddresses = request.QueryOrForm("dnsServerIPv4SourceAddresses");
  491. if (dnsServerIPv4SourceAddresses is not null)
  492. DnsClientConnection.IPv4SourceAddresses = ParseNetworkAddresses(dnsServerIPv4SourceAddresses);
  493. string dnsServerIPv6SourceAddresses = request.QueryOrForm("dnsServerIPv6SourceAddresses");
  494. if (dnsServerIPv6SourceAddresses is not null)
  495. DnsClientConnection.IPv6SourceAddresses = ParseNetworkAddresses(dnsServerIPv6SourceAddresses);
  496. if (request.TryGetQueryOrForm("defaultRecordTtl", uint.Parse, out uint defaultRecordTtl))
  497. _dnsWebService._zonesApi.DefaultRecordTtl = defaultRecordTtl;
  498. string defaultResponsiblePerson = request.QueryOrForm("defaultResponsiblePerson");
  499. if (defaultResponsiblePerson is not null)
  500. {
  501. if (defaultResponsiblePerson.Length == 0)
  502. _dnsWebService.DnsServer.ResponsiblePersonInternal = null;
  503. else if (defaultResponsiblePerson.Length > 255)
  504. throw new ArgumentException("Default responsible person email address length cannot exceed 255 characters.", "defaultResponsiblePerson");
  505. else
  506. _dnsWebService.DnsServer.ResponsiblePersonInternal = new MailAddress(defaultResponsiblePerson);
  507. }
  508. if (request.TryGetQueryOrForm("useSoaSerialDateScheme", bool.Parse, out bool useSoaSerialDateScheme))
  509. _dnsWebService.DnsServer.AuthZoneManager.UseSoaSerialDateScheme = useSoaSerialDateScheme;
  510. string zoneTransferAllowedNetworks = request.QueryOrForm("zoneTransferAllowedNetworks");
  511. if (zoneTransferAllowedNetworks is not null)
  512. _dnsWebService.DnsServer.ZoneTransferAllowedNetworks = ParseNetworkAddresses(zoneTransferAllowedNetworks);
  513. string notifyAllowedNetworks = request.QueryOrForm("notifyAllowedNetworks");
  514. if (notifyAllowedNetworks is not null)
  515. _dnsWebService.DnsServer.NotifyAllowedNetworks = ParseNetworkAddresses(notifyAllowedNetworks);
  516. if (request.TryGetQueryOrForm("dnsAppsEnableAutomaticUpdate", bool.Parse, out bool dnsAppsEnableAutomaticUpdate))
  517. _dnsWebService._appsApi.EnableAutomaticUpdate = dnsAppsEnableAutomaticUpdate;
  518. if (request.TryGetQueryOrForm("preferIPv6", bool.Parse, out bool preferIPv6))
  519. _dnsWebService.DnsServer.PreferIPv6 = preferIPv6;
  520. if (request.TryGetQueryOrForm("udpPayloadSize", ushort.Parse, out ushort udpPayloadSize))
  521. _dnsWebService.DnsServer.UdpPayloadSize = udpPayloadSize;
  522. if (request.TryGetQueryOrForm("dnssecValidation", bool.Parse, out bool dnssecValidation))
  523. _dnsWebService.DnsServer.DnssecValidation = dnssecValidation;
  524. if (request.TryGetQueryOrForm("eDnsClientSubnet", bool.Parse, out bool eDnsClientSubnet))
  525. _dnsWebService.DnsServer.EDnsClientSubnet = eDnsClientSubnet;
  526. if (request.TryGetQueryOrForm("eDnsClientSubnetIPv4PrefixLength", byte.Parse, out byte eDnsClientSubnetIPv4PrefixLength))
  527. _dnsWebService.DnsServer.EDnsClientSubnetIPv4PrefixLength = eDnsClientSubnetIPv4PrefixLength;
  528. if (request.TryGetQueryOrForm("eDnsClientSubnetIPv6PrefixLength", byte.Parse, out byte eDnsClientSubnetIPv6PrefixLength))
  529. _dnsWebService.DnsServer.EDnsClientSubnetIPv6PrefixLength = eDnsClientSubnetIPv6PrefixLength;
  530. string eDnsClientSubnetIpv4Override = request.QueryOrForm("eDnsClientSubnetIpv4Override");
  531. if (eDnsClientSubnetIpv4Override is not null)
  532. {
  533. if (eDnsClientSubnetIpv4Override.Length == 0)
  534. _dnsWebService.DnsServer.EDnsClientSubnetIpv4Override = null;
  535. else
  536. _dnsWebService.DnsServer.EDnsClientSubnetIpv4Override = NetworkAddress.Parse(eDnsClientSubnetIpv4Override);
  537. }
  538. string eDnsClientSubnetIpv6Override = request.QueryOrForm("eDnsClientSubnetIpv6Override");
  539. if (eDnsClientSubnetIpv6Override is not null)
  540. {
  541. if (eDnsClientSubnetIpv6Override.Length == 0)
  542. _dnsWebService.DnsServer.EDnsClientSubnetIpv6Override = null;
  543. else
  544. _dnsWebService.DnsServer.EDnsClientSubnetIpv6Override = NetworkAddress.Parse(eDnsClientSubnetIpv6Override);
  545. }
  546. if (request.TryGetQueryOrForm("qpmLimitRequests", int.Parse, out int qpmLimitRequests))
  547. _dnsWebService.DnsServer.QpmLimitRequests = qpmLimitRequests;
  548. if (request.TryGetQueryOrForm("qpmLimitErrors", int.Parse, out int qpmLimitErrors))
  549. _dnsWebService.DnsServer.QpmLimitErrors = qpmLimitErrors;
  550. if (request.TryGetQueryOrForm("qpmLimitSampleMinutes", int.Parse, out int qpmLimitSampleMinutes))
  551. _dnsWebService.DnsServer.QpmLimitSampleMinutes = qpmLimitSampleMinutes;
  552. if (request.TryGetQueryOrForm("qpmLimitIPv4PrefixLength", int.Parse, out int qpmLimitIPv4PrefixLength))
  553. _dnsWebService.DnsServer.QpmLimitIPv4PrefixLength = qpmLimitIPv4PrefixLength;
  554. if (request.TryGetQueryOrForm("qpmLimitIPv6PrefixLength", int.Parse, out int qpmLimitIPv6PrefixLength))
  555. _dnsWebService.DnsServer.QpmLimitIPv6PrefixLength = qpmLimitIPv6PrefixLength;
  556. string qpmLimitBypassList = request.QueryOrForm("qpmLimitBypassList");
  557. if (qpmLimitBypassList is not null)
  558. _dnsWebService.DnsServer.QpmLimitBypassList = ParseNetworkAddresses(qpmLimitBypassList);
  559. if (request.TryGetQueryOrForm("clientTimeout", int.Parse, out int clientTimeout))
  560. _dnsWebService.DnsServer.ClientTimeout = clientTimeout;
  561. if (request.TryGetQueryOrForm("tcpSendTimeout", int.Parse, out int tcpSendTimeout))
  562. _dnsWebService.DnsServer.TcpSendTimeout = tcpSendTimeout;
  563. if (request.TryGetQueryOrForm("tcpReceiveTimeout", int.Parse, out int tcpReceiveTimeout))
  564. _dnsWebService.DnsServer.TcpReceiveTimeout = tcpReceiveTimeout;
  565. if (request.TryGetQueryOrForm("quicIdleTimeout", int.Parse, out int quicIdleTimeout))
  566. _dnsWebService.DnsServer.QuicIdleTimeout = quicIdleTimeout;
  567. if (request.TryGetQueryOrForm("quicMaxInboundStreams", int.Parse, out int quicMaxInboundStreams))
  568. _dnsWebService.DnsServer.QuicMaxInboundStreams = quicMaxInboundStreams;
  569. if (request.TryGetQueryOrForm("listenBacklog", int.Parse, out int listenBacklog))
  570. _dnsWebService.DnsServer.ListenBacklog = listenBacklog;
  571. //web service
  572. string webServiceLocalAddresses = request.QueryOrForm("webServiceLocalAddresses");
  573. if (webServiceLocalAddresses is not null)
  574. {
  575. if (webServiceLocalAddresses.Length == 0)
  576. webServiceLocalAddresses = "0.0.0.0,[::]";
  577. IPAddress[] localAddresses = webServiceLocalAddresses.Split(IPAddress.Parse, ',');
  578. if (localAddresses.Length > 0)
  579. {
  580. if (_dnsWebService._webServiceLocalAddresses.Count != localAddresses.Length)
  581. {
  582. restartWebService = true;
  583. }
  584. else
  585. {
  586. foreach (IPAddress currentlocalAddress in _dnsWebService._webServiceLocalAddresses)
  587. {
  588. if (!localAddresses.Contains(currentlocalAddress))
  589. {
  590. restartWebService = true;
  591. break;
  592. }
  593. }
  594. }
  595. _dnsWebService._webServiceLocalAddresses = DnsServer.GetValidKestralLocalAddresses(localAddresses);
  596. }
  597. }
  598. if (request.TryGetQueryOrForm("webServiceHttpPort", int.Parse, out int webServiceHttpPort))
  599. {
  600. if (_dnsWebService._webServiceHttpPort != webServiceHttpPort)
  601. {
  602. _dnsWebService._webServiceHttpPort = webServiceHttpPort;
  603. restartWebService = true;
  604. }
  605. }
  606. if (request.TryGetQueryOrForm("webServiceEnableTls", bool.Parse, out bool webServiceEnableTls))
  607. {
  608. if (_dnsWebService._webServiceEnableTls != webServiceEnableTls)
  609. {
  610. _dnsWebService._webServiceEnableTls = webServiceEnableTls;
  611. _webServiceEnablingTls = webServiceEnableTls;
  612. restartWebService = true;
  613. }
  614. }
  615. if (request.TryGetQueryOrForm("webServiceEnableHttp3", bool.Parse, out bool webServiceEnableHttp3))
  616. {
  617. if (_dnsWebService._webServiceEnableHttp3 != webServiceEnableHttp3)
  618. {
  619. if (webServiceEnableHttp3)
  620. DnsWebService.ValidateQuicSupport("HTTP/3");
  621. _dnsWebService._webServiceEnableHttp3 = webServiceEnableHttp3;
  622. restartWebService = true;
  623. }
  624. }
  625. if (request.TryGetQueryOrForm("webServiceHttpToTlsRedirect", bool.Parse, out bool webServiceHttpToTlsRedirect))
  626. {
  627. if (_dnsWebService._webServiceHttpToTlsRedirect != webServiceHttpToTlsRedirect)
  628. {
  629. _dnsWebService._webServiceHttpToTlsRedirect = webServiceHttpToTlsRedirect;
  630. restartWebService = true;
  631. }
  632. }
  633. if (request.TryGetQueryOrForm("webServiceUseSelfSignedTlsCertificate", bool.Parse, out bool webServiceUseSelfSignedTlsCertificate))
  634. _dnsWebService._webServiceUseSelfSignedTlsCertificate = webServiceUseSelfSignedTlsCertificate;
  635. if (request.TryGetQueryOrForm("webServiceTlsPort", int.Parse, out int webServiceTlsPort))
  636. {
  637. if (_dnsWebService._webServiceTlsPort != webServiceTlsPort)
  638. {
  639. _dnsWebService._webServiceTlsPort = webServiceTlsPort;
  640. restartWebService = true;
  641. }
  642. }
  643. string webServiceTlsCertificatePath = request.QueryOrForm("webServiceTlsCertificatePath");
  644. if (webServiceTlsCertificatePath is not null)
  645. {
  646. if (webServiceTlsCertificatePath.Length == 0)
  647. {
  648. _dnsWebService._webServiceTlsCertificatePath = null;
  649. _dnsWebService._webServiceTlsCertificatePassword = "";
  650. }
  651. else
  652. {
  653. string webServiceTlsCertificatePassword = request.QueryOrForm("webServiceTlsCertificatePassword");
  654. if ((webServiceTlsCertificatePassword is null) || (webServiceTlsCertificatePassword == "************"))
  655. webServiceTlsCertificatePassword = _dnsWebService._webServiceTlsCertificatePassword;
  656. if ((webServiceTlsCertificatePath != _dnsWebService._webServiceTlsCertificatePath) || (webServiceTlsCertificatePassword != _dnsWebService._webServiceTlsCertificatePassword))
  657. {
  658. if (webServiceTlsCertificatePath.Length > 255)
  659. throw new ArgumentException("Web service TLS certificate path length cannot exceed 255 characters.", "webServiceTlsCertificatePath");
  660. if (webServiceTlsCertificatePassword?.Length > 255)
  661. throw new ArgumentException("Web service TLS certificate password length cannot exceed 255 characters.", "webServiceTlsCertificatePassword");
  662. _dnsWebService.LoadWebServiceTlsCertificate(_dnsWebService.ConvertToAbsolutePath(webServiceTlsCertificatePath), webServiceTlsCertificatePassword);
  663. _dnsWebService._webServiceTlsCertificatePath = _dnsWebService.ConvertToRelativePath(webServiceTlsCertificatePath);
  664. _dnsWebService._webServiceTlsCertificatePassword = webServiceTlsCertificatePassword;
  665. _dnsWebService.StartTlsCertificateUpdateTimer();
  666. }
  667. }
  668. }
  669. if (request.TryGetQueryOrForm("webServiceRealIpHeader", out string webServiceRealIpHeader))
  670. {
  671. if (webServiceRealIpHeader.Length > 255)
  672. throw new ArgumentException("Web service Real IP header name cannot exceed 255 characters.", "webServiceRealIpHeader");
  673. if (webServiceRealIpHeader.Contains(' '))
  674. throw new ArgumentException("Web service Real IP header name cannot contain invalid characters.", "webServiceRealIpHeader");
  675. _dnsWebService._webServiceRealIpHeader = webServiceRealIpHeader;
  676. }
  677. //optional protocols
  678. if (request.TryGetQueryOrForm("enableDnsOverUdpProxy", bool.Parse, out bool enableDnsOverUdpProxy))
  679. {
  680. if (_dnsWebService.DnsServer.EnableDnsOverUdpProxy != enableDnsOverUdpProxy)
  681. {
  682. _dnsWebService.DnsServer.EnableDnsOverUdpProxy = enableDnsOverUdpProxy;
  683. restartDnsService = true;
  684. }
  685. }
  686. if (request.TryGetQueryOrForm("enableDnsOverTcpProxy", bool.Parse, out bool enableDnsOverTcpProxy))
  687. {
  688. if (_dnsWebService.DnsServer.EnableDnsOverTcpProxy != enableDnsOverTcpProxy)
  689. {
  690. _dnsWebService.DnsServer.EnableDnsOverTcpProxy = enableDnsOverTcpProxy;
  691. restartDnsService = true;
  692. }
  693. }
  694. if (request.TryGetQueryOrForm("enableDnsOverHttp", bool.Parse, out bool enableDnsOverHttp))
  695. {
  696. if (_dnsWebService.DnsServer.EnableDnsOverHttp != enableDnsOverHttp)
  697. {
  698. _dnsWebService.DnsServer.EnableDnsOverHttp = enableDnsOverHttp;
  699. restartDnsService = true;
  700. }
  701. }
  702. if (request.TryGetQueryOrForm("enableDnsOverTls", bool.Parse, out bool enableDnsOverTls))
  703. {
  704. if (_dnsWebService.DnsServer.EnableDnsOverTls != enableDnsOverTls)
  705. {
  706. _dnsWebService.DnsServer.EnableDnsOverTls = enableDnsOverTls;
  707. restartDnsService = true;
  708. }
  709. }
  710. if (request.TryGetQueryOrForm("enableDnsOverHttps", bool.Parse, out bool enableDnsOverHttps))
  711. {
  712. if (_dnsWebService.DnsServer.EnableDnsOverHttps != enableDnsOverHttps)
  713. {
  714. _dnsWebService.DnsServer.EnableDnsOverHttps = enableDnsOverHttps;
  715. restartDnsService = true;
  716. }
  717. }
  718. if (request.TryGetQueryOrForm("enableDnsOverHttp3", bool.Parse, out bool enableDnsOverHttp3))
  719. {
  720. if (_dnsWebService.DnsServer.EnableDnsOverHttp3 != enableDnsOverHttp3)
  721. {
  722. if (enableDnsOverHttp3)
  723. DnsWebService.ValidateQuicSupport("DNS-over-HTTP/3");
  724. _dnsWebService.DnsServer.EnableDnsOverHttp3 = enableDnsOverHttp3;
  725. restartDnsService = true;
  726. }
  727. }
  728. if (request.TryGetQueryOrForm("enableDnsOverQuic", bool.Parse, out bool enableDnsOverQuic))
  729. {
  730. if (_dnsWebService.DnsServer.EnableDnsOverQuic != enableDnsOverQuic)
  731. {
  732. if (enableDnsOverQuic)
  733. DnsWebService.ValidateQuicSupport();
  734. _dnsWebService.DnsServer.EnableDnsOverQuic = enableDnsOverQuic;
  735. restartDnsService = true;
  736. }
  737. }
  738. if (request.TryGetQueryOrForm("dnsOverUdpProxyPort", int.Parse, out int dnsOverUdpProxyPort))
  739. {
  740. if (_dnsWebService.DnsServer.DnsOverUdpProxyPort != dnsOverUdpProxyPort)
  741. {
  742. _dnsWebService.DnsServer.DnsOverUdpProxyPort = dnsOverUdpProxyPort;
  743. restartDnsService = true;
  744. }
  745. }
  746. if (request.TryGetQueryOrForm("dnsOverTcpProxyPort", int.Parse, out int dnsOverTcpProxyPort))
  747. {
  748. if (_dnsWebService.DnsServer.DnsOverTcpProxyPort != dnsOverTcpProxyPort)
  749. {
  750. _dnsWebService.DnsServer.DnsOverTcpProxyPort = dnsOverTcpProxyPort;
  751. restartDnsService = true;
  752. }
  753. }
  754. if (request.TryGetQueryOrForm("dnsOverHttpPort", int.Parse, out int dnsOverHttpPort))
  755. {
  756. if (_dnsWebService.DnsServer.DnsOverHttpPort != dnsOverHttpPort)
  757. {
  758. _dnsWebService.DnsServer.DnsOverHttpPort = dnsOverHttpPort;
  759. restartDnsService = true;
  760. }
  761. }
  762. if (request.TryGetQueryOrForm("dnsOverTlsPort", int.Parse, out int dnsOverTlsPort))
  763. {
  764. if (_dnsWebService.DnsServer.DnsOverTlsPort != dnsOverTlsPort)
  765. {
  766. _dnsWebService.DnsServer.DnsOverTlsPort = dnsOverTlsPort;
  767. restartDnsService = true;
  768. }
  769. }
  770. if (request.TryGetQueryOrForm("dnsOverHttpsPort", int.Parse, out int dnsOverHttpsPort))
  771. {
  772. if (_dnsWebService.DnsServer.DnsOverHttpsPort != dnsOverHttpsPort)
  773. {
  774. _dnsWebService.DnsServer.DnsOverHttpsPort = dnsOverHttpsPort;
  775. restartDnsService = true;
  776. }
  777. }
  778. if (request.TryGetQueryOrForm("dnsOverQuicPort", int.Parse, out int dnsOverQuicPort))
  779. {
  780. if (_dnsWebService.DnsServer.DnsOverQuicPort != dnsOverQuicPort)
  781. {
  782. _dnsWebService.DnsServer.DnsOverQuicPort = dnsOverQuicPort;
  783. restartDnsService = true;
  784. }
  785. }
  786. string dnsTlsCertificatePath = request.QueryOrForm("dnsTlsCertificatePath");
  787. if (dnsTlsCertificatePath is not null)
  788. {
  789. if (dnsTlsCertificatePath.Length == 0)
  790. {
  791. if (!string.IsNullOrEmpty(_dnsWebService._dnsTlsCertificatePath) && (_dnsWebService.DnsServer.EnableDnsOverTls || _dnsWebService.DnsServer.EnableDnsOverHttps || _dnsWebService.DnsServer.EnableDnsOverQuic))
  792. restartDnsService = true;
  793. _dnsWebService.DnsServer.CertificateCollection = null;
  794. _dnsWebService._dnsTlsCertificatePath = null;
  795. _dnsWebService._dnsTlsCertificatePassword = "";
  796. }
  797. else
  798. {
  799. string dnsTlsCertificatePassword = request.QueryOrForm("dnsTlsCertificatePassword");
  800. if ((dnsTlsCertificatePassword is null) || (dnsTlsCertificatePassword == "************"))
  801. dnsTlsCertificatePassword = _dnsWebService._dnsTlsCertificatePassword;
  802. if ((dnsTlsCertificatePath != _dnsWebService._dnsTlsCertificatePath) || (dnsTlsCertificatePassword != _dnsWebService._dnsTlsCertificatePassword))
  803. {
  804. if (dnsTlsCertificatePath.Length > 255)
  805. throw new ArgumentException("DNS optional protocols TLS certificate path length cannot exceed 255 characters.", "dnsTlsCertificatePath");
  806. if (dnsTlsCertificatePassword?.Length > 255)
  807. throw new ArgumentException("DNS optional protocols TLS certificate password length cannot exceed 255 characters.", "dnsTlsCertificatePassword");
  808. _dnsWebService.LoadDnsTlsCertificate(_dnsWebService.ConvertToAbsolutePath(dnsTlsCertificatePath), dnsTlsCertificatePassword);
  809. if (string.IsNullOrEmpty(_dnsWebService._dnsTlsCertificatePath) && (_dnsWebService.DnsServer.EnableDnsOverTls || _dnsWebService.DnsServer.EnableDnsOverHttps || _dnsWebService.DnsServer.EnableDnsOverQuic))
  810. restartDnsService = true;
  811. _dnsWebService._dnsTlsCertificatePath = _dnsWebService.ConvertToRelativePath(dnsTlsCertificatePath);
  812. _dnsWebService._dnsTlsCertificatePassword = dnsTlsCertificatePassword;
  813. _dnsWebService.StartTlsCertificateUpdateTimer();
  814. }
  815. }
  816. }
  817. if (request.TryGetQueryOrForm("dnsOverHttpRealIpHeader", out string dnsOverHttpRealIpHeader))
  818. _dnsWebService.DnsServer.DnsOverHttpRealIpHeader = dnsOverHttpRealIpHeader;
  819. //tsig
  820. string strTsigKeys = request.QueryOrForm("tsigKeys");
  821. if (strTsigKeys is not null)
  822. {
  823. if ((strTsigKeys.Length == 0) || strTsigKeys.Equals("false", StringComparison.OrdinalIgnoreCase))
  824. {
  825. _dnsWebService.DnsServer.TsigKeys = null;
  826. }
  827. else
  828. {
  829. string[] strTsigKeyParts = strTsigKeys.Split('|');
  830. Dictionary<string, TsigKey> tsigKeys = new Dictionary<string, TsigKey>(strTsigKeyParts.Length);
  831. for (int i = 0; i < strTsigKeyParts.Length; i += 3)
  832. {
  833. string keyName = strTsigKeyParts[i + 0].TrimEnd('.').ToLowerInvariant();
  834. string sharedSecret = strTsigKeyParts[i + 1];
  835. string algorithmName = strTsigKeyParts[i + 2];
  836. if (DnsClient.IsDomainNameUnicode(keyName))
  837. keyName = DnsClient.ConvertDomainNameToAscii(keyName);
  838. DnsClient.IsDomainNameValid(keyName, true);
  839. if (sharedSecret.Length == 0)
  840. tsigKeys.Add(keyName, new TsigKey(keyName, algorithmName));
  841. else
  842. tsigKeys.Add(keyName, new TsigKey(keyName, sharedSecret, algorithmName));
  843. }
  844. _dnsWebService.DnsServer.TsigKeys = tsigKeys;
  845. }
  846. }
  847. //recursion
  848. if (request.TryGetQueryOrFormEnum("recursion", out DnsServerRecursion recursion))
  849. _dnsWebService.DnsServer.Recursion = recursion;
  850. string recursionNetworkACL = request.QueryOrForm("recursionNetworkACL");
  851. if (recursionNetworkACL is not null)
  852. {
  853. if ((recursionNetworkACL.Length == 0) || recursionNetworkACL.Equals("false", StringComparison.OrdinalIgnoreCase))
  854. _dnsWebService.DnsServer.RecursionNetworkACL = null;
  855. else
  856. _dnsWebService.DnsServer.RecursionNetworkACL = recursionNetworkACL.Split(NetworkAccessControl.Parse, ',');
  857. }
  858. if (request.TryGetQueryOrForm("randomizeName", bool.Parse, out bool randomizeName))
  859. _dnsWebService.DnsServer.RandomizeName = randomizeName;
  860. if (request.TryGetQueryOrForm("qnameMinimization", bool.Parse, out bool qnameMinimization))
  861. _dnsWebService.DnsServer.QnameMinimization = qnameMinimization;
  862. if (request.TryGetQueryOrForm("nsRevalidation", bool.Parse, out bool nsRevalidation))
  863. _dnsWebService.DnsServer.NsRevalidation = nsRevalidation;
  864. if (request.TryGetQueryOrForm("resolverRetries", int.Parse, out int resolverRetries))
  865. _dnsWebService.DnsServer.ResolverRetries = resolverRetries;
  866. if (request.TryGetQueryOrForm("resolverTimeout", int.Parse, out int resolverTimeout))
  867. _dnsWebService.DnsServer.ResolverTimeout = resolverTimeout;
  868. if (request.TryGetQueryOrForm("resolverConcurrency", int.Parse, out int resolverConcurrency))
  869. _dnsWebService.DnsServer.ResolverConcurrency = resolverConcurrency;
  870. if (request.TryGetQueryOrForm("resolverMaxStackCount", int.Parse, out int resolverMaxStackCount))
  871. _dnsWebService.DnsServer.ResolverMaxStackCount = resolverMaxStackCount;
  872. //cache
  873. if (request.TryGetQueryOrForm("saveCache", bool.Parse, out bool saveCache))
  874. {
  875. if (!saveCache)
  876. _dnsWebService.DnsServer.CacheZoneManager.DeleteCacheZoneFile();
  877. _dnsWebService._saveCache = saveCache;
  878. }
  879. if (request.TryGetQueryOrForm("serveStale", bool.Parse, out bool serveStale))
  880. _dnsWebService.DnsServer.ServeStale = serveStale;
  881. if (request.TryGetQueryOrForm("serveStaleTtl", uint.Parse, out uint serveStaleTtl))
  882. _dnsWebService.DnsServer.CacheZoneManager.ServeStaleTtl = serveStaleTtl;
  883. if (request.TryGetQueryOrForm("serveStaleAnswerTtl", uint.Parse, out uint serveStaleAnswerTtl))
  884. _dnsWebService.DnsServer.CacheZoneManager.ServeStaleAnswerTtl = serveStaleAnswerTtl;
  885. if (request.TryGetQueryOrForm("serveStaleResetTtl", uint.Parse, out uint serveStaleResetTtl))
  886. _dnsWebService.DnsServer.CacheZoneManager.ServeStaleResetTtl = serveStaleResetTtl;
  887. if (request.TryGetQueryOrForm("serveStaleMaxWaitTime", int.Parse, out int serveStaleMaxWaitTime))
  888. _dnsWebService.DnsServer.ServeStaleMaxWaitTime = serveStaleMaxWaitTime;
  889. if (request.TryGetQueryOrForm("cacheMaximumEntries", long.Parse, out long cacheMaximumEntries))
  890. _dnsWebService.DnsServer.CacheZoneManager.MaximumEntries = cacheMaximumEntries;
  891. if (request.TryGetQueryOrForm("cacheMinimumRecordTtl", uint.Parse, out uint cacheMinimumRecordTtl))
  892. _dnsWebService.DnsServer.CacheZoneManager.MinimumRecordTtl = cacheMinimumRecordTtl;
  893. if (request.TryGetQueryOrForm("cacheMaximumRecordTtl", uint.Parse, out uint cacheMaximumRecordTtl))
  894. _dnsWebService.DnsServer.CacheZoneManager.MaximumRecordTtl = cacheMaximumRecordTtl;
  895. if (request.TryGetQueryOrForm("cacheNegativeRecordTtl", uint.Parse, out uint cacheNegativeRecordTtl))
  896. _dnsWebService.DnsServer.CacheZoneManager.NegativeRecordTtl = cacheNegativeRecordTtl;
  897. if (request.TryGetQueryOrForm("cacheFailureRecordTtl", uint.Parse, out uint cacheFailureRecordTtl))
  898. _dnsWebService.DnsServer.CacheZoneManager.FailureRecordTtl = cacheFailureRecordTtl;
  899. if (request.TryGetQueryOrForm("cachePrefetchEligibility", int.Parse, out int cachePrefetchEligibility))
  900. _dnsWebService.DnsServer.CachePrefetchEligibility = cachePrefetchEligibility;
  901. if (request.TryGetQueryOrForm("cachePrefetchTrigger", int.Parse, out int cachePrefetchTrigger))
  902. _dnsWebService.DnsServer.CachePrefetchTrigger = cachePrefetchTrigger;
  903. if (request.TryGetQueryOrForm("cachePrefetchSampleIntervalInMinutes", int.Parse, out int cachePrefetchSampleIntervalInMinutes))
  904. _dnsWebService.DnsServer.CachePrefetchSampleIntervalInMinutes = cachePrefetchSampleIntervalInMinutes;
  905. if (request.TryGetQueryOrForm("cachePrefetchSampleEligibilityHitsPerHour", int.Parse, out int cachePrefetchSampleEligibilityHitsPerHour))
  906. _dnsWebService.DnsServer.CachePrefetchSampleEligibilityHitsPerHour = cachePrefetchSampleEligibilityHitsPerHour;
  907. //blocking
  908. if (request.TryGetQueryOrForm("enableBlocking", bool.Parse, out bool enableBlocking))
  909. {
  910. _dnsWebService.DnsServer.EnableBlocking = enableBlocking;
  911. if (_dnsWebService.DnsServer.EnableBlocking)
  912. {
  913. if (_temporaryDisableBlockingTimer is not null)
  914. _temporaryDisableBlockingTimer.Dispose();
  915. }
  916. }
  917. if (request.TryGetQueryOrForm("allowTxtBlockingReport", bool.Parse, out bool allowTxtBlockingReport))
  918. _dnsWebService.DnsServer.AllowTxtBlockingReport = allowTxtBlockingReport;
  919. string blockingBypassList = request.QueryOrForm("blockingBypassList");
  920. if (blockingBypassList is not null)
  921. _dnsWebService.DnsServer.BlockingBypassList = ParseNetworkAddresses(blockingBypassList);
  922. if (request.TryGetQueryOrFormEnum("blockingType", out DnsServerBlockingType blockingType))
  923. _dnsWebService.DnsServer.BlockingType = blockingType;
  924. if (request.TryGetQueryOrForm("blockingAnswerTtl", uint.Parse, out uint blockingAnswerTtl))
  925. _dnsWebService.DnsServer.BlockingAnswerTtl = blockingAnswerTtl;
  926. string customBlockingAddresses = request.QueryOrForm("customBlockingAddresses");
  927. if (customBlockingAddresses is not null)
  928. {
  929. if ((customBlockingAddresses.Length == 0) || customBlockingAddresses.Equals("false", StringComparison.OrdinalIgnoreCase))
  930. {
  931. _dnsWebService.DnsServer.CustomBlockingARecords = null;
  932. _dnsWebService.DnsServer.CustomBlockingAAAARecords = null;
  933. }
  934. else
  935. {
  936. string[] strAddresses = customBlockingAddresses.Split(_commaSeparator, StringSplitOptions.RemoveEmptyEntries);
  937. List<DnsARecordData> dnsARecords = new List<DnsARecordData>();
  938. List<DnsAAAARecordData> dnsAAAARecords = new List<DnsAAAARecordData>();
  939. foreach (string strAddress in strAddresses)
  940. {
  941. if (IPAddress.TryParse(strAddress, out IPAddress customAddress))
  942. {
  943. switch (customAddress.AddressFamily)
  944. {
  945. case AddressFamily.InterNetwork:
  946. dnsARecords.Add(new DnsARecordData(customAddress));
  947. break;
  948. case AddressFamily.InterNetworkV6:
  949. dnsAAAARecords.Add(new DnsAAAARecordData(customAddress));
  950. break;
  951. }
  952. }
  953. }
  954. _dnsWebService.DnsServer.CustomBlockingARecords = dnsARecords;
  955. _dnsWebService.DnsServer.CustomBlockingAAAARecords = dnsAAAARecords;
  956. }
  957. }
  958. string blockListUrls = request.QueryOrForm("blockListUrls");
  959. if (blockListUrls is not null)
  960. {
  961. if ((blockListUrls.Length == 0) || blockListUrls.Equals("false", StringComparison.OrdinalIgnoreCase))
  962. {
  963. _dnsWebService.DnsServer.BlockListZoneManager.AllowListUrls.Clear();
  964. _dnsWebService.DnsServer.BlockListZoneManager.BlockListUrls.Clear();
  965. _dnsWebService.DnsServer.BlockListZoneManager.Flush();
  966. }
  967. else
  968. {
  969. string[] blockListUrlList = blockListUrls.Split(_commaSeparator, StringSplitOptions.RemoveEmptyEntries);
  970. if (oldWebServiceHttpPort != _dnsWebService._webServiceHttpPort)
  971. {
  972. for (int i = 0; i < blockListUrlList.Length; i++)
  973. {
  974. if (blockListUrlList[i].Contains("http://localhost:" + oldWebServiceHttpPort + "/blocklist.txt"))
  975. {
  976. blockListUrlList[i] = "http://localhost:" + _dnsWebService._webServiceHttpPort + "/blocklist.txt";
  977. blockListUrlsUpdated = true;
  978. break;
  979. }
  980. }
  981. }
  982. if (!blockListUrlsUpdated)
  983. {
  984. if (blockListUrlList.Length != (_dnsWebService.DnsServer.BlockListZoneManager.AllowListUrls.Count + _dnsWebService.DnsServer.BlockListZoneManager.BlockListUrls.Count))
  985. {
  986. blockListUrlsUpdated = true;
  987. }
  988. else
  989. {
  990. foreach (string strBlockListUrl in blockListUrlList)
  991. {
  992. if (strBlockListUrl.StartsWith('!'))
  993. {
  994. string strAllowListUrl = strBlockListUrl.Substring(1);
  995. if (!_dnsWebService.DnsServer.BlockListZoneManager.AllowListUrls.Contains(new Uri(strAllowListUrl)))
  996. {
  997. blockListUrlsUpdated = true;
  998. break;
  999. }
  1000. }
  1001. else
  1002. {
  1003. if (!_dnsWebService.DnsServer.BlockListZoneManager.BlockListUrls.Contains(new Uri(strBlockListUrl)))
  1004. {
  1005. blockListUrlsUpdated = true;
  1006. break;
  1007. }
  1008. }
  1009. }
  1010. }
  1011. }
  1012. if (blockListUrlsUpdated)
  1013. {
  1014. _dnsWebService.DnsServer.BlockListZoneManager.AllowListUrls.Clear();
  1015. _dnsWebService.DnsServer.BlockListZoneManager.BlockListUrls.Clear();
  1016. foreach (string strBlockListUrl in blockListUrlList)
  1017. {
  1018. if (strBlockListUrl.StartsWith('!'))
  1019. {
  1020. Uri allowListUrl = new Uri(strBlockListUrl.Substring(1));
  1021. if (allowListUrl.AbsoluteUri.Length > 255)
  1022. throw new ArgumentException("Allow list URL length cannot exceed 255 characters.", "blockListUrls");
  1023. if (!_dnsWebService.DnsServer.BlockListZoneManager.AllowListUrls.Contains(allowListUrl))
  1024. _dnsWebService.DnsServer.BlockListZoneManager.AllowListUrls.Add(allowListUrl);
  1025. }
  1026. else
  1027. {
  1028. Uri blockListUrl = new Uri(strBlockListUrl);
  1029. if (blockListUrl.AbsoluteUri.Length > 255)
  1030. throw new ArgumentException("Block list URL length cannot exceed 255 characters.", "blockListUrls");
  1031. if (!_dnsWebService.DnsServer.BlockListZoneManager.BlockListUrls.Contains(blockListUrl))
  1032. _dnsWebService.DnsServer.BlockListZoneManager.BlockListUrls.Add(blockListUrl);
  1033. }
  1034. }
  1035. }
  1036. }
  1037. }
  1038. if (request.TryGetQueryOrForm("blockListUpdateIntervalHours", int.Parse, out int blockListUpdateIntervalHours))
  1039. {
  1040. if ((blockListUpdateIntervalHours < 0) || (blockListUpdateIntervalHours > 168))
  1041. throw new DnsWebServiceException("Parameter `blockListUpdateIntervalHours` must be between 1 hour and 168 hours (7 days) or 0 to disable automatic update.");
  1042. _blockListUpdateIntervalHours = blockListUpdateIntervalHours;
  1043. }
  1044. //proxy & forwarders
  1045. if (request.TryGetQueryOrFormEnum("proxyType", out NetProxyType proxyType))
  1046. {
  1047. if (proxyType == NetProxyType.None)
  1048. {
  1049. _dnsWebService.DnsServer.Proxy = null;
  1050. }
  1051. else
  1052. {
  1053. NetworkCredential credential = null;
  1054. if (request.TryGetQueryOrForm("proxyUsername", out string proxyUsername))
  1055. {
  1056. if (proxyUsername.Length > 255)
  1057. throw new ArgumentException("Proxy username length cannot exceed 255 characters.", "proxyUsername");
  1058. string proxyPassword = request.QueryOrForm("proxyPassword");
  1059. if (proxyPassword?.Length > 255)
  1060. throw new ArgumentException("Proxy password length cannot exceed 255 characters.", "proxyPassword");
  1061. credential = new NetworkCredential(proxyUsername, proxyPassword);
  1062. }
  1063. _dnsWebService.DnsServer.Proxy = NetProxy.CreateProxy(proxyType, request.QueryOrForm("proxyAddress"), int.Parse(request.QueryOrForm("proxyPort")), credential);
  1064. if (request.TryGetQueryOrForm("proxyBypass", out string proxyBypass))
  1065. _dnsWebService.DnsServer.Proxy.BypassList = proxyBypass.Split(delegate (string value) { return new NetProxyBypassItem(value); }, ',');
  1066. }
  1067. }
  1068. string strForwarders = request.QueryOrForm("forwarders");
  1069. if (strForwarders is not null)
  1070. {
  1071. if ((strForwarders.Length == 0) || strForwarders.Equals("false", StringComparison.OrdinalIgnoreCase))
  1072. {
  1073. _dnsWebService.DnsServer.Forwarders = null;
  1074. }
  1075. else
  1076. {
  1077. DnsTransportProtocol forwarderProtocol = request.GetQueryOrFormEnum("forwarderProtocol", DnsTransportProtocol.Udp);
  1078. switch (forwarderProtocol)
  1079. {
  1080. case DnsTransportProtocol.Udp:
  1081. if (proxyType == NetProxyType.Http)
  1082. throw new DnsWebServiceException("HTTP proxy server can transport only DNS-over-TCP, DNS-over-TLS, or DNS-over-HTTPS forwarder protocols. Use SOCKS5 proxy server for DNS-over-UDP or DNS-over-QUIC forwarder protocols.");
  1083. break;
  1084. case DnsTransportProtocol.HttpsJson:
  1085. forwarderProtocol = DnsTransportProtocol.Https;
  1086. break;
  1087. case DnsTransportProtocol.Quic:
  1088. DnsWebService.ValidateQuicSupport();
  1089. if (proxyType == NetProxyType.Http)
  1090. throw new DnsWebServiceException("HTTP proxy server can transport only DNS-over-TCP, DNS-over-TLS, or DNS-over-HTTPS forwarder protocols. Use SOCKS5 proxy server for DNS-over-UDP or DNS-over-QUIC forwarder protocols.");
  1091. break;
  1092. }
  1093. NameServerAddress[] forwarders = strForwarders.Split(delegate (string value)
  1094. {
  1095. NameServerAddress forwarder = NameServerAddress.Parse(value);
  1096. if (forwarder.Protocol != forwarderProtocol)
  1097. forwarder = forwarder.ChangeProtocol(forwarderProtocol);
  1098. return forwarder;
  1099. }, ',');
  1100. if (!_dnsWebService.DnsServer.Forwarders.ListEquals(forwarders))
  1101. _dnsWebService.DnsServer.Forwarders = forwarders;
  1102. }
  1103. }
  1104. if (request.TryGetQueryOrForm("concurrentForwarding", bool.Parse, out bool concurrentForwarding))
  1105. _dnsWebService.DnsServer.ConcurrentForwarding = concurrentForwarding;
  1106. if (request.TryGetQueryOrForm("forwarderRetries", int.Parse, out int forwarderRetries))
  1107. _dnsWebService.DnsServer.ForwarderRetries = forwarderRetries;
  1108. if (request.TryGetQueryOrForm("forwarderTimeout", int.Parse, out int forwarderTimeout))
  1109. _dnsWebService.DnsServer.ForwarderTimeout = forwarderTimeout;
  1110. if (request.TryGetQueryOrForm("forwarderConcurrency", int.Parse, out int forwarderConcurrency))
  1111. _dnsWebService.DnsServer.ForwarderConcurrency = forwarderConcurrency;
  1112. //logging
  1113. if (request.TryGetQueryOrForm("enableLogging", bool.Parse, out bool enableLogging))
  1114. _dnsWebService._log.EnableLogging = enableLogging;
  1115. if (request.TryGetQueryOrForm("ignoreResolverLogs", bool.Parse, out bool ignoreResolverLogs))
  1116. _dnsWebService.DnsServer.ResolverLogManager = ignoreResolverLogs ? null : _dnsWebService._log;
  1117. if (request.TryGetQueryOrForm("logQueries", bool.Parse, out bool logQueries))
  1118. _dnsWebService.DnsServer.QueryLogManager = logQueries ? _dnsWebService._log : null;
  1119. if (request.TryGetQueryOrForm("useLocalTime", bool.Parse, out bool useLocalTime))
  1120. _dnsWebService._log.UseLocalTime = useLocalTime;
  1121. if (request.TryGetQueryOrForm("logFolder", out string logFolder))
  1122. _dnsWebService._log.LogFolder = logFolder;
  1123. if (request.TryGetQueryOrForm("maxLogFileDays", int.Parse, out int maxLogFileDays))
  1124. _dnsWebService._log.MaxLogFileDays = maxLogFileDays;
  1125. if (request.TryGetQueryOrForm("enableInMemoryStats", bool.Parse, out bool enableInMemoryStats))
  1126. _dnsWebService.DnsServer.StatsManager.EnableInMemoryStats = enableInMemoryStats;
  1127. if (request.TryGetQueryOrForm("maxStatFileDays", int.Parse, out int maxStatFileDays))
  1128. _dnsWebService.DnsServer.StatsManager.MaxStatFileDays = maxStatFileDays;
  1129. //TLS actions
  1130. if ((_dnsWebService._webServiceTlsCertificatePath is null) && (_dnsWebService._dnsTlsCertificatePath is null))
  1131. _dnsWebService.StopTlsCertificateUpdateTimer();
  1132. _dnsWebService.SelfSignedCertCheck(serverDomainChanged, true);
  1133. if (_dnsWebService._webServiceEnableTls && string.IsNullOrEmpty(_dnsWebService._webServiceTlsCertificatePath) && !_dnsWebService._webServiceUseSelfSignedTlsCertificate)
  1134. {
  1135. //disable TLS
  1136. _dnsWebService._webServiceEnableTls = false;
  1137. restartWebService = true;
  1138. }
  1139. //blocklist timers
  1140. if ((_blockListUpdateIntervalHours > 0) && ((_dnsWebService.DnsServer.BlockListZoneManager.AllowListUrls.Count + _dnsWebService.DnsServer.BlockListZoneManager.BlockListUrls.Count) > 0))
  1141. {
  1142. if (_blockListUpdateTimer is null)
  1143. StartBlockListUpdateTimer(blockListUrlsUpdated);
  1144. else if (blockListUrlsUpdated)
  1145. ForceUpdateBlockLists(true);
  1146. }
  1147. else
  1148. {
  1149. StopBlockListUpdateTimer();
  1150. }
  1151. //save config
  1152. _dnsWebService.SaveConfigFile();
  1153. _dnsWebService._log.SaveConfig();
  1154. _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] DNS Settings were updated successfully.");
  1155. Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
  1156. WriteDnsSettings(jsonWriter);
  1157. RestartService(restartDnsService, restartWebService, oldWebServiceLocalAddresses, oldWebServiceHttpPort, oldWebServiceTlsPort);
  1158. }
  1159. public void GetTsigKeyNames(HttpContext context)
  1160. {
  1161. UserSession session = context.GetCurrentSession();
  1162. if (
  1163. !_dnsWebService._authManager.IsPermitted(PermissionSection.Settings, session.User, PermissionFlag.View) &&
  1164. !_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify)
  1165. )
  1166. {
  1167. throw new DnsWebServiceException("Access was denied.");
  1168. }
  1169. Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
  1170. jsonWriter.WritePropertyName("tsigKeyNames");
  1171. {
  1172. jsonWriter.WriteStartArray();
  1173. if (_dnsWebService.DnsServer.TsigKeys is not null)
  1174. {
  1175. foreach (KeyValuePair<string, TsigKey> tsigKey in _dnsWebService.DnsServer.TsigKeys)
  1176. jsonWriter.WriteStringValue(tsigKey.Key);
  1177. }
  1178. jsonWriter.WriteEndArray();
  1179. }
  1180. }
  1181. public async Task BackupSettingsAsync(HttpContext context)
  1182. {
  1183. UserSession session = context.GetCurrentSession();
  1184. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Settings, session.User, PermissionFlag.Delete))
  1185. throw new DnsWebServiceException("Access was denied.");
  1186. HttpRequest request = context.Request;
  1187. bool blockLists = request.GetQueryOrForm("blockLists", bool.Parse, false);
  1188. bool logs = request.GetQueryOrForm("logs", bool.Parse, false);
  1189. bool scopes = request.GetQueryOrForm("scopes", bool.Parse, false);
  1190. bool apps = request.GetQueryOrForm("apps", bool.Parse, false);
  1191. bool stats = request.GetQueryOrForm("stats", bool.Parse, false);
  1192. bool zones = request.GetQueryOrForm("zones", bool.Parse, false);
  1193. bool allowedZones = request.GetQueryOrForm("allowedZones", bool.Parse, false);
  1194. bool blockedZones = request.GetQueryOrForm("blockedZones", bool.Parse, false);
  1195. bool dnsSettings = request.GetQueryOrForm("dnsSettings", bool.Parse, false);
  1196. bool authConfig = request.GetQueryOrForm("authConfig", bool.Parse, false);
  1197. bool logSettings = request.GetQueryOrForm("logSettings", bool.Parse, false);
  1198. string tmpFile = Path.GetTempFileName();
  1199. try
  1200. {
  1201. using (FileStream backupZipStream = new FileStream(tmpFile, FileMode.Create, FileAccess.ReadWrite))
  1202. {
  1203. //create backup zip
  1204. using (ZipArchive backupZip = new ZipArchive(backupZipStream, ZipArchiveMode.Create, true, Encoding.UTF8))
  1205. {
  1206. if (blockLists)
  1207. {
  1208. string[] blockListFiles = Directory.GetFiles(Path.Combine(_dnsWebService._configFolder, "blocklists"), "*", SearchOption.TopDirectoryOnly);
  1209. foreach (string blockListFile in blockListFiles)
  1210. {
  1211. string entryName = "blocklists/" + Path.GetFileName(blockListFile);
  1212. backupZip.CreateEntryFromFile(blockListFile, entryName);
  1213. }
  1214. }
  1215. if (logs)
  1216. {
  1217. string[] logFiles = Directory.GetFiles(_dnsWebService._log.LogFolderAbsolutePath, "*.log", SearchOption.TopDirectoryOnly);
  1218. foreach (string logFile in logFiles)
  1219. {
  1220. string entryName = "logs/" + Path.GetFileName(logFile);
  1221. if (logFile.Equals(_dnsWebService._log.CurrentLogFile, StringComparison.OrdinalIgnoreCase))
  1222. {
  1223. await CreateBackupEntryFromFileAsync(backupZip, logFile, entryName);
  1224. }
  1225. else
  1226. {
  1227. backupZip.CreateEntryFromFile(logFile, entryName);
  1228. }
  1229. }
  1230. }
  1231. if (scopes)
  1232. {
  1233. string[] scopeFiles = Directory.GetFiles(Path.Combine(_dnsWebService._configFolder, "scopes"), "*.scope", SearchOption.TopDirectoryOnly);
  1234. foreach (string scopeFile in scopeFiles)
  1235. {
  1236. string entryName = "scopes/" + Path.GetFileName(scopeFile);
  1237. backupZip.CreateEntryFromFile(scopeFile, entryName);
  1238. }
  1239. }
  1240. if (apps)
  1241. {
  1242. string[] appFiles = Directory.GetFiles(Path.Combine(_dnsWebService._configFolder, "apps"), "*", SearchOption.AllDirectories);
  1243. foreach (string appFile in appFiles)
  1244. {
  1245. string entryName = appFile.Substring(_dnsWebService._configFolder.Length);
  1246. if (Path.DirectorySeparatorChar != '/')
  1247. entryName = entryName.Replace(Path.DirectorySeparatorChar, '/');
  1248. entryName = entryName.TrimStart('/');
  1249. await CreateBackupEntryFromFileAsync(backupZip, appFile, entryName);
  1250. }
  1251. }
  1252. if (stats)
  1253. {
  1254. string[] hourlyStatsFiles = Directory.GetFiles(Path.Combine(_dnsWebService._configFolder, "stats"), "*.stat", SearchOption.TopDirectoryOnly);
  1255. foreach (string hourlyStatsFile in hourlyStatsFiles)
  1256. {
  1257. string entryName = "stats/" + Path.GetFileName(hourlyStatsFile);
  1258. backupZip.CreateEntryFromFile(hourlyStatsFile, entryName);
  1259. }
  1260. string[] dailyStatsFiles = Directory.GetFiles(Path.Combine(_dnsWebService._configFolder, "stats"), "*.dstat", SearchOption.TopDirectoryOnly);
  1261. foreach (string dailyStatsFile in dailyStatsFiles)
  1262. {
  1263. string entryName = "stats/" + Path.GetFileName(dailyStatsFile);
  1264. backupZip.CreateEntryFromFile(dailyStatsFile, entryName);
  1265. }
  1266. }
  1267. if (zones)
  1268. {
  1269. string[] zoneFiles = Directory.GetFiles(Path.Combine(_dnsWebService._configFolder, "zones"), "*.zone", SearchOption.TopDirectoryOnly);
  1270. foreach (string zoneFile in zoneFiles)
  1271. {
  1272. string entryName = "zones/" + Path.GetFileName(zoneFile);
  1273. backupZip.CreateEntryFromFile(zoneFile, entryName);
  1274. }
  1275. }
  1276. if (allowedZones)
  1277. {
  1278. string allowedZonesFile = Path.Combine(_dnsWebService._configFolder, "allowed.config");
  1279. if (File.Exists(allowedZonesFile))
  1280. backupZip.CreateEntryFromFile(allowedZonesFile, "allowed.config");
  1281. }
  1282. if (blockedZones)
  1283. {
  1284. string blockedZonesFile = Path.Combine(_dnsWebService._configFolder, "blocked.config");
  1285. if (File.Exists(blockedZonesFile))
  1286. backupZip.CreateEntryFromFile(blockedZonesFile, "blocked.config");
  1287. }
  1288. if (dnsSettings)
  1289. {
  1290. string dnsSettingsFile = Path.Combine(_dnsWebService._configFolder, "dns.config");
  1291. if (File.Exists(dnsSettingsFile))
  1292. backupZip.CreateEntryFromFile(dnsSettingsFile, "dns.config");
  1293. //backup web service cert
  1294. if (!string.IsNullOrEmpty(_dnsWebService._webServiceTlsCertificatePath))
  1295. {
  1296. string webServiceTlsCertificatePath = _dnsWebService.ConvertToAbsolutePath(_dnsWebService._webServiceTlsCertificatePath);
  1297. if (File.Exists(webServiceTlsCertificatePath) && webServiceTlsCertificatePath.StartsWith(_dnsWebService._configFolder, Environment.OSVersion.Platform == PlatformID.Win32NT ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal))
  1298. {
  1299. string entryName = _dnsWebService.ConvertToRelativePath(webServiceTlsCertificatePath).Replace('\\', '/');
  1300. backupZip.CreateEntryFromFile(webServiceTlsCertificatePath, entryName);
  1301. }
  1302. }
  1303. //backup optional protocols cert
  1304. if (!string.IsNullOrEmpty(_dnsWebService._dnsTlsCertificatePath))
  1305. {
  1306. string dnsTlsCertificatePath = _dnsWebService.ConvertToAbsolutePath(_dnsWebService._dnsTlsCertificatePath);
  1307. if (File.Exists(dnsTlsCertificatePath) && dnsTlsCertificatePath.StartsWith(_dnsWebService._configFolder, Environment.OSVersion.Platform == PlatformID.Win32NT ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal))
  1308. {
  1309. string entryName = _dnsWebService.ConvertToRelativePath(dnsTlsCertificatePath).Replace('\\', '/');
  1310. backupZip.CreateEntryFromFile(dnsTlsCertificatePath, entryName);
  1311. }
  1312. }
  1313. }
  1314. if (authConfig)
  1315. {
  1316. string authSettingsFile = Path.Combine(_dnsWebService._configFolder, "auth.config");
  1317. if (File.Exists(authSettingsFile))
  1318. backupZip.CreateEntryFromFile(authSettingsFile, "auth.config");
  1319. }
  1320. if (logSettings)
  1321. {
  1322. string logSettingsFile = Path.Combine(_dnsWebService._configFolder, "log.config");
  1323. if (File.Exists(logSettingsFile))
  1324. backupZip.CreateEntryFromFile(logSettingsFile, "log.config");
  1325. }
  1326. }
  1327. //send zip file
  1328. backupZipStream.Position = 0;
  1329. HttpResponse response = context.Response;
  1330. response.ContentType = "application/zip";
  1331. response.ContentLength = backupZipStream.Length;
  1332. response.Headers.ContentDisposition = "attachment;filename=" + _dnsWebService.DnsServer.ServerDomain + DateTime.UtcNow.ToString("_yyyy-MM-dd_HH-mm-ss") + "_backup.zip";
  1333. using (Stream output = response.Body)
  1334. {
  1335. await backupZipStream.CopyToAsync(output);
  1336. }
  1337. }
  1338. }
  1339. finally
  1340. {
  1341. try
  1342. {
  1343. File.Delete(tmpFile);
  1344. }
  1345. catch (Exception ex)
  1346. {
  1347. _dnsWebService._log.Write(ex);
  1348. }
  1349. }
  1350. _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Settings backup zip file was exported.");
  1351. }
  1352. public async Task RestoreSettingsAsync(HttpContext context)
  1353. {
  1354. UserSession session = context.GetCurrentSession();
  1355. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Settings, session.User, PermissionFlag.Delete))
  1356. throw new DnsWebServiceException("Access was denied.");
  1357. HttpRequest request = context.Request;
  1358. bool blockLists = request.GetQueryOrForm("blockLists", bool.Parse, false);
  1359. bool logs = request.GetQueryOrForm("logs", bool.Parse, false);
  1360. bool scopes = request.GetQueryOrForm("scopes", bool.Parse, false);
  1361. bool apps = request.GetQueryOrForm("apps", bool.Parse, false);
  1362. bool stats = request.GetQueryOrForm("stats", bool.Parse, false);
  1363. bool zones = request.GetQueryOrForm("zones", bool.Parse, false);
  1364. bool allowedZones = request.GetQueryOrForm("allowedZones", bool.Parse, false);
  1365. bool blockedZones = request.GetQueryOrForm("blockedZones", bool.Parse, false);
  1366. bool dnsSettings = request.GetQueryOrForm("dnsSettings", bool.Parse, false);
  1367. bool authConfig = request.GetQueryOrForm("authConfig", bool.Parse, false);
  1368. bool logSettings = request.GetQueryOrForm("logSettings", bool.Parse, false);
  1369. bool deleteExistingFiles = request.GetQueryOrForm("deleteExistingFiles", bool.Parse, false);
  1370. if (!request.HasFormContentType || (request.Form.Files.Count == 0))
  1371. throw new DnsWebServiceException("DNS backup zip file is missing.");
  1372. IReadOnlyList<IPAddress> oldWebServiceLocalAddresses = _dnsWebService._webServiceLocalAddresses;
  1373. int oldWebServiceHttpPort = _dnsWebService._webServiceHttpPort;
  1374. int oldWebServiceTlsPort = _dnsWebService._webServiceTlsPort;
  1375. //write to temp file
  1376. string tmpFile = Path.GetTempFileName();
  1377. try
  1378. {
  1379. using (FileStream fS = new FileStream(tmpFile, FileMode.Create, FileAccess.ReadWrite))
  1380. {
  1381. await request.Form.Files[0].CopyToAsync(fS);
  1382. fS.Position = 0;
  1383. using (ZipArchive backupZip = new ZipArchive(fS, ZipArchiveMode.Read, false, Encoding.UTF8))
  1384. {
  1385. if (logSettings || logs)
  1386. {
  1387. //stop logging
  1388. _dnsWebService._log.StopLogging();
  1389. }
  1390. try
  1391. {
  1392. if (logSettings)
  1393. {
  1394. ZipArchiveEntry entry = backupZip.GetEntry("log.config");
  1395. if (entry is not null)
  1396. entry.ExtractToFile(Path.Combine(_dnsWebService._configFolder, entry.Name), true);
  1397. //reload config
  1398. _dnsWebService._log.LoadConfig();
  1399. }
  1400. if (logs)
  1401. {
  1402. if (deleteExistingFiles)
  1403. {
  1404. //delete existing log files
  1405. string[] logFiles = Directory.GetFiles(_dnsWebService._log.LogFolderAbsolutePath, "*.log", SearchOption.TopDirectoryOnly);
  1406. foreach (string logFile in logFiles)
  1407. {
  1408. File.Delete(logFile);
  1409. }
  1410. }
  1411. //extract log files from backup
  1412. foreach (ZipArchiveEntry entry in backupZip.Entries)
  1413. {
  1414. if (entry.FullName.StartsWith("logs/"))
  1415. entry.ExtractToFile(Path.Combine(_dnsWebService._log.LogFolderAbsolutePath, entry.Name), true);
  1416. }
  1417. }
  1418. }
  1419. finally
  1420. {
  1421. if (logSettings || logs)
  1422. {
  1423. //start logging
  1424. if (_dnsWebService._log.EnableLogging)
  1425. _dnsWebService._log.StartLogging();
  1426. }
  1427. }
  1428. if (authConfig)
  1429. {
  1430. ZipArchiveEntry entry = backupZip.GetEntry("auth.config");
  1431. if (entry is not null)
  1432. entry.ExtractToFile(Path.Combine(_dnsWebService._configFolder, entry.Name), true);
  1433. //reload auth config
  1434. _dnsWebService._authManager.LoadConfigFile(session);
  1435. }
  1436. if (blockLists)
  1437. {
  1438. if (deleteExistingFiles)
  1439. {
  1440. //delete existing block list files
  1441. string[] blockListFiles = Directory.GetFiles(Path.Combine(_dnsWebService._configFolder, "blocklists"), "*", SearchOption.TopDirectoryOnly);
  1442. foreach (string blockListFile in blockListFiles)
  1443. {
  1444. File.Delete(blockListFile);
  1445. }
  1446. }
  1447. //extract block list files from backup
  1448. foreach (ZipArchiveEntry entry in backupZip.Entries)
  1449. {
  1450. if (entry.FullName.StartsWith("blocklists/"))
  1451. entry.ExtractToFile(Path.Combine(_dnsWebService._configFolder, "blocklists", entry.Name), true);
  1452. }
  1453. }
  1454. if (dnsSettings)
  1455. {
  1456. ZipArchiveEntry entry = backupZip.GetEntry("dns.config");
  1457. if (entry is not null)
  1458. entry.ExtractToFile(Path.Combine(_dnsWebService._configFolder, entry.Name), true);
  1459. //extract any certs
  1460. foreach (ZipArchiveEntry certEntry in backupZip.Entries)
  1461. {
  1462. if (certEntry.FullName.StartsWith("apps/"))
  1463. continue;
  1464. if (certEntry.FullName.EndsWith(".pfx", StringComparison.OrdinalIgnoreCase) || certEntry.FullName.EndsWith(".p12", StringComparison.OrdinalIgnoreCase))
  1465. {
  1466. string certFile = Path.Combine(_dnsWebService._configFolder, certEntry.FullName);
  1467. Directory.CreateDirectory(Path.GetDirectoryName(certFile));
  1468. certEntry.ExtractToFile(certFile, true);
  1469. }
  1470. }
  1471. //flush zones to avoid UpdateServerDomain task for old zones and old allowed/blocked zones
  1472. if (zones)
  1473. _dnsWebService.DnsServer.AuthZoneManager.Flush();
  1474. if (allowedZones)
  1475. _dnsWebService.DnsServer.AllowedZoneManager.Flush();
  1476. if (blockedZones)
  1477. _dnsWebService.DnsServer.BlockedZoneManager.Flush();
  1478. //reload settings and block list zone
  1479. _dnsWebService.LoadConfigFile();
  1480. if ((_dnsWebService.DnsServer.BlockListZoneManager.AllowListUrls.Count + _dnsWebService.DnsServer.BlockListZoneManager.BlockListUrls.Count) > 0)
  1481. {
  1482. ThreadPool.QueueUserWorkItem(delegate (object state)
  1483. {
  1484. try
  1485. {
  1486. _dnsWebService.DnsServer.BlockListZoneManager.LoadBlockLists();
  1487. }
  1488. catch (Exception ex)
  1489. {
  1490. _dnsWebService._log.Write(ex);
  1491. }
  1492. });
  1493. if (_blockListUpdateIntervalHours > 0)
  1494. StartBlockListUpdateTimer(false);
  1495. else
  1496. StopBlockListUpdateTimer();
  1497. }
  1498. else
  1499. {
  1500. _dnsWebService.DnsServer.BlockListZoneManager.Flush();
  1501. StopBlockListUpdateTimer();
  1502. }
  1503. }
  1504. if (apps)
  1505. {
  1506. //unload apps
  1507. _dnsWebService.DnsServer.DnsApplicationManager.UnloadAllApplications();
  1508. if (deleteExistingFiles)
  1509. {
  1510. //delete existing apps
  1511. string appFolder = Path.Combine(_dnsWebService._configFolder, "apps");
  1512. if (Directory.Exists(appFolder))
  1513. Directory.Delete(appFolder, true);
  1514. //create apps folder
  1515. Directory.CreateDirectory(appFolder);
  1516. }
  1517. //extract apps files from backup
  1518. foreach (ZipArchiveEntry entry in backupZip.Entries)
  1519. {
  1520. if (entry.FullName.StartsWith("apps/"))
  1521. {
  1522. string entryPath = entry.FullName;
  1523. if (Path.DirectorySeparatorChar != '/')
  1524. entryPath = entryPath.Replace('/', '\\');
  1525. string filePath = Path.Combine(_dnsWebService._configFolder, entryPath);
  1526. Directory.CreateDirectory(Path.GetDirectoryName(filePath));
  1527. entry.ExtractToFile(filePath, true);
  1528. }
  1529. }
  1530. //reload apps
  1531. _dnsWebService.DnsServer.DnsApplicationManager.LoadAllApplications();
  1532. }
  1533. if (zones)
  1534. {
  1535. if (deleteExistingFiles)
  1536. {
  1537. //delete existing zone files
  1538. string[] zoneFiles = Directory.GetFiles(Path.Combine(_dnsWebService._configFolder, "zones"), "*.zone", SearchOption.TopDirectoryOnly);
  1539. foreach (string zoneFile in zoneFiles)
  1540. {
  1541. File.Delete(zoneFile);
  1542. }
  1543. }
  1544. //extract zone files from backup
  1545. foreach (ZipArchiveEntry entry in backupZip.Entries)
  1546. {
  1547. if (entry.FullName.StartsWith("zones/"))
  1548. entry.ExtractToFile(Path.Combine(_dnsWebService._configFolder, "zones", entry.Name), true);
  1549. }
  1550. //reload zones
  1551. _dnsWebService.DnsServer.AuthZoneManager.LoadAllZoneFiles();
  1552. _dnsWebService.InspectAndFixZonePermissions();
  1553. }
  1554. if (allowedZones)
  1555. {
  1556. ZipArchiveEntry entry = backupZip.GetEntry("allowed.config");
  1557. if (entry == null)
  1558. {
  1559. string fileName = Path.Combine(_dnsWebService._configFolder, "allowed.config");
  1560. if (File.Exists(fileName))
  1561. File.Delete(fileName);
  1562. }
  1563. else
  1564. {
  1565. entry.ExtractToFile(Path.Combine(_dnsWebService._configFolder, entry.Name), true);
  1566. }
  1567. //reload
  1568. _dnsWebService.DnsServer.AllowedZoneManager.LoadAllowedZoneFile();
  1569. }
  1570. if (blockedZones)
  1571. {
  1572. ZipArchiveEntry entry = backupZip.GetEntry("blocked.config");
  1573. if (entry == null)
  1574. {
  1575. string fileName = Path.Combine(_dnsWebService._configFolder, "blocked.config");
  1576. if (File.Exists(fileName))
  1577. File.Delete(fileName);
  1578. }
  1579. else
  1580. {
  1581. entry.ExtractToFile(Path.Combine(_dnsWebService._configFolder, entry.Name), true);
  1582. }
  1583. //reload
  1584. _dnsWebService.DnsServer.BlockedZoneManager.LoadBlockedZoneFile();
  1585. }
  1586. if (scopes)
  1587. {
  1588. //stop dhcp server
  1589. _dnsWebService.DhcpServer.Stop();
  1590. try
  1591. {
  1592. if (deleteExistingFiles)
  1593. {
  1594. //delete existing scope files
  1595. string[] scopeFiles = Directory.GetFiles(Path.Combine(_dnsWebService._configFolder, "scopes"), "*.scope", SearchOption.TopDirectoryOnly);
  1596. foreach (string scopeFile in scopeFiles)
  1597. {
  1598. File.Delete(scopeFile);
  1599. }
  1600. }
  1601. //extract scope files from backup
  1602. foreach (ZipArchiveEntry entry in backupZip.Entries)
  1603. {
  1604. if (entry.FullName.StartsWith("scopes/"))
  1605. entry.ExtractToFile(Path.Combine(_dnsWebService._configFolder, "scopes", entry.Name), true);
  1606. }
  1607. }
  1608. finally
  1609. {
  1610. //start dhcp server
  1611. _dnsWebService.DhcpServer.Start();
  1612. }
  1613. }
  1614. if (stats)
  1615. {
  1616. if (deleteExistingFiles)
  1617. {
  1618. //delete existing stats files
  1619. string[] hourlyStatsFiles = Directory.GetFiles(Path.Combine(_dnsWebService._configFolder, "stats"), "*.stat", SearchOption.TopDirectoryOnly);
  1620. foreach (string hourlyStatsFile in hourlyStatsFiles)
  1621. {
  1622. File.Delete(hourlyStatsFile);
  1623. }
  1624. string[] dailyStatsFiles = Directory.GetFiles(Path.Combine(_dnsWebService._configFolder, "stats"), "*.dstat", SearchOption.TopDirectoryOnly);
  1625. foreach (string dailyStatsFile in dailyStatsFiles)
  1626. {
  1627. File.Delete(dailyStatsFile);
  1628. }
  1629. }
  1630. //extract stats files from backup
  1631. foreach (ZipArchiveEntry entry in backupZip.Entries)
  1632. {
  1633. if (entry.FullName.StartsWith("stats/"))
  1634. entry.ExtractToFile(Path.Combine(_dnsWebService._configFolder, "stats", entry.Name), true);
  1635. }
  1636. //reload stats
  1637. _dnsWebService.DnsServer.StatsManager.ReloadStats();
  1638. }
  1639. _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Settings backup zip file was restored.");
  1640. }
  1641. }
  1642. }
  1643. finally
  1644. {
  1645. try
  1646. {
  1647. File.Delete(tmpFile);
  1648. }
  1649. catch (Exception ex)
  1650. {
  1651. _dnsWebService._log.Write(ex);
  1652. }
  1653. }
  1654. Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
  1655. WriteDnsSettings(jsonWriter);
  1656. if (dnsSettings)
  1657. RestartService(true, true, oldWebServiceLocalAddresses, oldWebServiceHttpPort, oldWebServiceTlsPort);
  1658. }
  1659. public void ForceUpdateBlockLists(HttpContext context)
  1660. {
  1661. UserSession session = context.GetCurrentSession();
  1662. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Settings, session.User, PermissionFlag.Modify))
  1663. throw new DnsWebServiceException("Access was denied.");
  1664. ForceUpdateBlockLists(false);
  1665. _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Block list update was triggered.");
  1666. }
  1667. public void TemporaryDisableBlocking(HttpContext context)
  1668. {
  1669. UserSession session = context.GetCurrentSession();
  1670. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Settings, session.User, PermissionFlag.Modify))
  1671. throw new DnsWebServiceException("Access was denied.");
  1672. int minutes = context.Request.GetQueryOrForm("minutes", int.Parse);
  1673. Timer temporaryDisableBlockingTimer = _temporaryDisableBlockingTimer;
  1674. if (temporaryDisableBlockingTimer is not null)
  1675. temporaryDisableBlockingTimer.Dispose();
  1676. Timer newTemporaryDisableBlockingTimer = new Timer(delegate (object state)
  1677. {
  1678. try
  1679. {
  1680. _dnsWebService.DnsServer.EnableBlocking = true;
  1681. _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Blocking was enabled after " + minutes + " minute(s) being temporarily disabled.");
  1682. }
  1683. catch (Exception ex)
  1684. {
  1685. _dnsWebService._log.Write(ex);
  1686. }
  1687. });
  1688. Timer originalTimer = Interlocked.CompareExchange(ref _temporaryDisableBlockingTimer, newTemporaryDisableBlockingTimer, temporaryDisableBlockingTimer);
  1689. if (ReferenceEquals(originalTimer, temporaryDisableBlockingTimer))
  1690. {
  1691. newTemporaryDisableBlockingTimer.Change(minutes * 60 * 1000, Timeout.Infinite);
  1692. _dnsWebService.DnsServer.EnableBlocking = false;
  1693. _temporaryDisableBlockingTill = DateTime.UtcNow.AddMinutes(minutes);
  1694. _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Blocking was temporarily disabled for " + minutes + " minute(s).");
  1695. }
  1696. else
  1697. {
  1698. newTemporaryDisableBlockingTimer.Dispose();
  1699. }
  1700. Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
  1701. jsonWriter.WriteString("temporaryDisableBlockingTill", _temporaryDisableBlockingTill);
  1702. }
  1703. #endregion
  1704. #region properties
  1705. public DateTime BlockListLastUpdatedOn
  1706. {
  1707. get { return _blockListLastUpdatedOn; }
  1708. set { _blockListLastUpdatedOn = value; }
  1709. }
  1710. public int BlockListUpdateIntervalHours
  1711. {
  1712. get { return _blockListUpdateIntervalHours; }
  1713. set { _blockListUpdateIntervalHours = value; }
  1714. }
  1715. #endregion
  1716. }
  1717. }