WebServiceSettingsApi.cs 84 KB

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