DnsWebService.cs 199 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649
  1. /*
  2. Technitium DNS Server
  3. Copyright (C) 2022 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.Dhcp;
  16. using DnsServerCore.Dns;
  17. using DnsServerCore.Dns.ResourceRecords;
  18. using DnsServerCore.Dns.ZoneManagers;
  19. using DnsServerCore.Dns.Zones;
  20. using Newtonsoft.Json;
  21. using Newtonsoft.Json.Converters;
  22. using System;
  23. using System.Collections.Concurrent;
  24. using System.Collections.Generic;
  25. using System.IO;
  26. using System.IO.Compression;
  27. using System.Net;
  28. using System.Net.Http;
  29. using System.Net.Security;
  30. using System.Net.Sockets;
  31. using System.Reflection;
  32. using System.Security.Cryptography;
  33. using System.Security.Cryptography.X509Certificates;
  34. using System.Text;
  35. using System.Threading;
  36. using System.Threading.Tasks;
  37. using TechnitiumLibrary;
  38. using TechnitiumLibrary.IO;
  39. using TechnitiumLibrary.Net;
  40. using TechnitiumLibrary.Net.Dns;
  41. using TechnitiumLibrary.Net.Dns.ResourceRecords;
  42. using TechnitiumLibrary.Net.Http;
  43. using TechnitiumLibrary.Net.Proxy;
  44. namespace DnsServerCore
  45. {
  46. public sealed class DnsWebService : IDisposable
  47. {
  48. #region enum
  49. enum ServiceState
  50. {
  51. Stopped = 0,
  52. Starting = 1,
  53. Running = 2,
  54. Stopping = 3
  55. }
  56. #endregion
  57. #region variables
  58. readonly static RandomNumberGenerator _rng = RandomNumberGenerator.Create();
  59. readonly WebServiceDashboardApi _dashboardApi;
  60. readonly WebServiceZonesApi _zonesApi;
  61. readonly WebServiceOtherZonesApi _otherZonesApi;
  62. readonly WebServiceAppsApi _appsApi;
  63. readonly WebServiceDhcpApi _dhcpApi;
  64. readonly WebServiceLogsApi _logsApi;
  65. readonly Version _currentVersion;
  66. readonly string _appFolder;
  67. readonly string _configFolder;
  68. readonly Uri _updateCheckUri;
  69. readonly LogManager _log;
  70. DnsServer _dnsServer;
  71. DhcpServer _dhcpServer;
  72. IReadOnlyList<IPAddress> _webServiceLocalAddresses = new IPAddress[] { IPAddress.Any, IPAddress.IPv6Any };
  73. int _webServiceHttpPort = 5380;
  74. int _webServiceTlsPort = 53443;
  75. bool _webServiceEnableTls;
  76. bool _webServiceHttpToTlsRedirect;
  77. bool _webServiceUseSelfSignedTlsCertificate;
  78. string _webServiceTlsCertificatePath;
  79. string _webServiceTlsCertificatePassword;
  80. DateTime _webServiceTlsCertificateLastModifiedOn;
  81. HttpListener _webService;
  82. IReadOnlyList<Socket> _webServiceTlsListeners;
  83. X509Certificate2 _webServiceTlsCertificate;
  84. readonly IndependentTaskScheduler _webServiceTaskScheduler = new IndependentTaskScheduler(ThreadPriority.AboveNormal);
  85. string _webServiceHostname;
  86. IPEndPoint _webServiceHttpEP;
  87. string _dnsTlsCertificatePath;
  88. string _dnsTlsCertificatePassword;
  89. DateTime _dnsTlsCertificateLastModifiedOn;
  90. Timer _tlsCertificateUpdateTimer;
  91. const int TLS_CERTIFICATE_UPDATE_TIMER_INITIAL_INTERVAL = 60000;
  92. const int TLS_CERTIFICATE_UPDATE_TIMER_INTERVAL = 60000;
  93. const int MAX_LOGIN_ATTEMPTS = 5;
  94. const int BLOCK_ADDRESS_INTERVAL = 5 * 60 * 1000;
  95. readonly ConcurrentDictionary<IPAddress, int> _failedLoginAttempts = new ConcurrentDictionary<IPAddress, int>();
  96. readonly ConcurrentDictionary<IPAddress, DateTime> _blockedAddresses = new ConcurrentDictionary<IPAddress, DateTime>();
  97. readonly ConcurrentDictionary<string, string> _credentials = new ConcurrentDictionary<string, string>();
  98. readonly ConcurrentDictionary<string, UserSession> _sessions = new ConcurrentDictionary<string, UserSession>();
  99. volatile ServiceState _state = ServiceState.Stopped;
  100. Timer _blockListUpdateTimer;
  101. DateTime _blockListLastUpdatedOn;
  102. int _blockListUpdateIntervalHours = 24;
  103. const int BLOCK_LIST_UPDATE_TIMER_INITIAL_INTERVAL = 5000;
  104. const int BLOCK_LIST_UPDATE_TIMER_PERIODIC_INTERVAL = 900000;
  105. Timer _temporaryDisableBlockingTimer;
  106. DateTime _temporaryDisableBlockingTill;
  107. List<string> _configDisabledZones;
  108. #endregion
  109. #region constructor
  110. public DnsWebService(string configFolder = null, Uri updateCheckUri = null, Uri appStoreUri = null)
  111. {
  112. _dashboardApi = new WebServiceDashboardApi(this);
  113. _zonesApi = new WebServiceZonesApi(this);
  114. _otherZonesApi = new WebServiceOtherZonesApi(this);
  115. _appsApi = new WebServiceAppsApi(this, appStoreUri);
  116. _dhcpApi = new WebServiceDhcpApi(this);
  117. _logsApi = new WebServiceLogsApi(this);
  118. Assembly assembly = Assembly.GetExecutingAssembly();
  119. AssemblyName assemblyName = assembly.GetName();
  120. _currentVersion = assemblyName.Version;
  121. _appFolder = Path.GetDirectoryName(assembly.Location);
  122. if (configFolder == null)
  123. _configFolder = Path.Combine(_appFolder, "config");
  124. else
  125. _configFolder = configFolder;
  126. if (!Directory.Exists(_configFolder))
  127. Directory.CreateDirectory(_configFolder);
  128. _updateCheckUri = updateCheckUri;
  129. _log = new LogManager(_configFolder);
  130. string blockListsFolder = Path.Combine(_configFolder, "blocklists");
  131. if (!Directory.Exists(blockListsFolder))
  132. Directory.CreateDirectory(blockListsFolder);
  133. }
  134. #endregion
  135. #region IDisposable
  136. bool _disposed;
  137. public void Dispose()
  138. {
  139. if (_disposed)
  140. return;
  141. Stop();
  142. if (_webService != null)
  143. _webService.Close();
  144. if (_dnsServer != null)
  145. _dnsServer.Dispose();
  146. if (_dhcpServer != null)
  147. _dhcpServer.Dispose();
  148. if (_log != null)
  149. _log.Dispose();
  150. _disposed = true;
  151. }
  152. #endregion
  153. #region private
  154. #region web service
  155. private async Task AcceptWebRequestAsync()
  156. {
  157. try
  158. {
  159. while (true)
  160. {
  161. HttpListenerContext context = await _webService.GetContextAsync();
  162. if ((_webServiceTlsListeners != null) && (_webServiceTlsListeners.Count > 0) && _webServiceHttpToTlsRedirect)
  163. {
  164. IPEndPoint remoteEP = context.Request.RemoteEndPoint;
  165. if ((remoteEP != null) && !IPAddress.IsLoopback(remoteEP.Address))
  166. {
  167. string domain = _webServiceTlsCertificate.GetNameInfo(X509NameType.DnsName, false);
  168. string redirectUri = "https://" + domain + ":" + _webServiceTlsPort + context.Request.Url.PathAndQuery;
  169. context.Response.Redirect(redirectUri);
  170. context.Response.Close();
  171. continue;
  172. }
  173. }
  174. _ = ProcessRequestAsync(context.Request, context.Response);
  175. }
  176. }
  177. catch (HttpListenerException ex)
  178. {
  179. if (ex.ErrorCode == 995)
  180. return; //web service stopping
  181. _log.Write(ex);
  182. }
  183. catch (ObjectDisposedException)
  184. {
  185. //web service stopped
  186. }
  187. catch (Exception ex)
  188. {
  189. if ((_state == ServiceState.Stopping) || (_state == ServiceState.Stopped))
  190. return; //web service stopping
  191. _log.Write(ex);
  192. }
  193. }
  194. private async Task AcceptTlsWebRequestAsync(Socket tlsListener)
  195. {
  196. try
  197. {
  198. while (true)
  199. {
  200. Socket socket = await tlsListener.AcceptAsync();
  201. _ = TlsToHttpTunnelAsync(socket);
  202. }
  203. }
  204. catch (SocketException ex)
  205. {
  206. if (ex.SocketErrorCode == SocketError.OperationAborted)
  207. return; //web service stopping
  208. _log.Write(ex);
  209. }
  210. catch (ObjectDisposedException)
  211. {
  212. //web service stopped
  213. }
  214. catch (Exception ex)
  215. {
  216. if ((_state == ServiceState.Stopping) || (_state == ServiceState.Stopped))
  217. return; //web service stopping
  218. _log.Write(ex);
  219. }
  220. }
  221. private async Task TlsToHttpTunnelAsync(Socket socket)
  222. {
  223. Socket tunnel = null;
  224. try
  225. {
  226. if (_webServiceLocalAddresses.Count < 1)
  227. return;
  228. string remoteIP = (socket.RemoteEndPoint as IPEndPoint).Address.ToString();
  229. SslStream sslStream = new SslStream(new NetworkStream(socket, true));
  230. await sslStream.AuthenticateAsServerAsync(_webServiceTlsCertificate);
  231. tunnel = new Socket(_webServiceHttpEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  232. tunnel.Connect(_webServiceHttpEP);
  233. NetworkStream tunnelStream = new NetworkStream(tunnel, true);
  234. //copy tunnel to ssl
  235. _ = tunnelStream.CopyToAsync(sslStream).ContinueWith(delegate (Task prevTask) { sslStream.Dispose(); tunnelStream.Dispose(); });
  236. //copy ssl to tunnel
  237. try
  238. {
  239. while (true)
  240. {
  241. HttpRequest httpRequest = await HttpRequest.ReadRequestAsync(sslStream);
  242. if (httpRequest == null)
  243. return; //connection closed gracefully by client
  244. //inject X-Real-IP & host header
  245. httpRequest.Headers.Add("X-Real-IP", remoteIP);
  246. httpRequest.Headers[HttpRequestHeader.Host] = "localhost:" + _webServiceHttpPort.ToString();
  247. //relay request
  248. await tunnelStream.WriteAsync(Encoding.ASCII.GetBytes(httpRequest.HttpMethod + " " + httpRequest.RequestPathAndQuery + " " + httpRequest.Protocol + "\r\n"));
  249. await tunnelStream.WriteAsync(httpRequest.Headers.ToByteArray());
  250. if (httpRequest.InputStream != null)
  251. await httpRequest.InputStream.CopyToAsync(tunnelStream);
  252. await tunnelStream.FlushAsync();
  253. }
  254. }
  255. finally
  256. {
  257. sslStream.Dispose();
  258. tunnelStream.Dispose();
  259. }
  260. }
  261. catch (IOException)
  262. {
  263. //ignore
  264. }
  265. catch (Exception ex)
  266. {
  267. _log.Write(ex);
  268. }
  269. finally
  270. {
  271. socket.Dispose();
  272. if (tunnel != null)
  273. tunnel.Dispose();
  274. }
  275. }
  276. private async Task ProcessRequestAsync(HttpListenerRequest request, HttpListenerResponse response)
  277. {
  278. response.AddHeader("Server", "");
  279. response.AddHeader("X-Robots-Tag", "noindex, nofollow");
  280. try
  281. {
  282. Uri url = request.Url;
  283. string path = url.AbsolutePath;
  284. if (!path.StartsWith("/") || path.Contains("/../") || path.Contains("/.../"))
  285. {
  286. await SendErrorAsync(response, 404);
  287. return;
  288. }
  289. if (path.StartsWith("/api/"))
  290. {
  291. using (MemoryStream mS = new MemoryStream())
  292. {
  293. try
  294. {
  295. JsonTextWriter jsonWriter = new JsonTextWriter(new StreamWriter(mS));
  296. jsonWriter.WriteStartObject();
  297. switch (path)
  298. {
  299. case "/api/login":
  300. await LoginAsync(request, jsonWriter);
  301. break;
  302. case "/api/logout":
  303. Logout(request);
  304. break;
  305. default:
  306. if (!IsSessionValid(request))
  307. throw new InvalidTokenWebServiceException("Invalid token or session expired.");
  308. jsonWriter.WritePropertyName("response");
  309. jsonWriter.WriteStartObject();
  310. try
  311. {
  312. switch (path)
  313. {
  314. case "/api/changePassword":
  315. ChangePassword(request);
  316. break;
  317. case "/api/checkForUpdate":
  318. await CheckForUpdateAsync(request, jsonWriter);
  319. break;
  320. case "/api/getDnsSettings":
  321. GetDnsSettings(jsonWriter);
  322. break;
  323. case "/api/setDnsSettings":
  324. SetDnsSettings(request, jsonWriter);
  325. break;
  326. case "/api/forceUpdateBlockLists":
  327. ForceUpdateBlockLists(request);
  328. break;
  329. case "/api/temporaryDisableBlocking":
  330. TemporaryDisableBlocking(request, jsonWriter);
  331. break;
  332. case "/api/backupSettings":
  333. await BackupSettingsAsync(request, response);
  334. return;
  335. case "/api/restoreSettings":
  336. await RestoreSettingsAsync(request, jsonWriter);
  337. break;
  338. case "/api/getStats":
  339. await _dashboardApi.GetStats(request, jsonWriter);
  340. break;
  341. case "/api/getTopStats":
  342. await _dashboardApi.GetTopStats(request, jsonWriter);
  343. break;
  344. case "/api/flushDnsCache":
  345. _otherZonesApi.FlushCache(request);
  346. break;
  347. case "/api/listCachedZones":
  348. _otherZonesApi.ListCachedZones(request, jsonWriter);
  349. break;
  350. case "/api/deleteCachedZone":
  351. _otherZonesApi.DeleteCachedZone(request);
  352. break;
  353. case "/api/listAllowedZones":
  354. _otherZonesApi.ListAllowedZones(request, jsonWriter);
  355. break;
  356. case "/api/importAllowedZones":
  357. _otherZonesApi.ImportAllowedZones(request);
  358. break;
  359. case "/api/exportAllowedZones":
  360. _otherZonesApi.ExportAllowedZones(response);
  361. return;
  362. case "/api/deleteAllowedZone":
  363. _otherZonesApi.DeleteAllowedZone(request);
  364. break;
  365. case "/api/flushAllowedZone":
  366. _otherZonesApi.FlushAllowedZone(request);
  367. break;
  368. case "/api/allowZone":
  369. _otherZonesApi.AllowZone(request);
  370. break;
  371. case "/api/listBlockedZones":
  372. _otherZonesApi.ListBlockedZones(request, jsonWriter);
  373. break;
  374. case "/api/importBlockedZones":
  375. _otherZonesApi.ImportBlockedZones(request);
  376. break;
  377. case "/api/exportBlockedZones":
  378. _otherZonesApi.ExportBlockedZones(response);
  379. return;
  380. case "/api/deleteBlockedZone":
  381. _otherZonesApi.DeleteBlockedZone(request);
  382. break;
  383. case "/api/flushBlockedZone":
  384. _otherZonesApi.FlushBlockedZone(request);
  385. break;
  386. case "/api/blockZone":
  387. _otherZonesApi.BlockZone(request);
  388. break;
  389. case "/api/zone/list":
  390. case "/api/listZones":
  391. _zonesApi.ListZones(jsonWriter);
  392. break;
  393. case "/api/zone/create":
  394. case "/api/createZone":
  395. await _zonesApi.CreateZoneAsync(request, jsonWriter);
  396. break;
  397. case "/api/zone/dnssec/sign":
  398. _zonesApi.SignPrimaryZone(request);
  399. break;
  400. case "/api/zone/dnssec/unsign":
  401. _zonesApi.UnsignPrimaryZone(request);
  402. break;
  403. case "/api/zone/dnssec/getProperties":
  404. _zonesApi.GetPrimaryZoneDnssecProperties(request, jsonWriter);
  405. break;
  406. case "/api/zone/dnssec/convertToNSEC":
  407. _zonesApi.ConvertPrimaryZoneToNSEC(request);
  408. break;
  409. case "/api/zone/dnssec/convertToNSEC3":
  410. _zonesApi.ConvertPrimaryZoneToNSEC3(request);
  411. break;
  412. case "/api/zone/dnssec/updateNSEC3Params":
  413. _zonesApi.UpdatePrimaryZoneNSEC3Parameters(request);
  414. break;
  415. case "/api/zone/dnssec/updateDnsKeyTtl":
  416. _zonesApi.UpdatePrimaryZoneDnssecDnsKeyTtl(request);
  417. break;
  418. case "/api/zone/dnssec/generatePrivateKey":
  419. _zonesApi.GenerateAndAddPrimaryZoneDnssecPrivateKey(request);
  420. break;
  421. case "/api/zone/dnssec/updatePrivateKey":
  422. _zonesApi.UpdatePrimaryZoneDnssecPrivateKey(request);
  423. break;
  424. case "/api/zone/dnssec/deletePrivateKey":
  425. _zonesApi.DeletePrimaryZoneDnssecPrivateKey(request);
  426. break;
  427. case "/api/zone/dnssec/publishAllPrivateKeys":
  428. _zonesApi.PublishAllGeneratedPrimaryZoneDnssecPrivateKeys(request);
  429. break;
  430. case "/api/zone/dnssec/rolloverDnsKey":
  431. _zonesApi.RolloverPrimaryZoneDnsKey(request);
  432. break;
  433. case "/api/zone/dnssec/retireDnsKey":
  434. _zonesApi.RetirePrimaryZoneDnsKey(request);
  435. break;
  436. case "/api/zone/delete":
  437. case "/api/deleteZone":
  438. _zonesApi.DeleteZone(request);
  439. break;
  440. case "/api/zone/enable":
  441. case "/api/enableZone":
  442. _zonesApi.EnableZone(request);
  443. break;
  444. case "/api/zone/disable":
  445. case "/api/disableZone":
  446. _zonesApi.DisableZone(request);
  447. break;
  448. case "/api/zone/options/get":
  449. _zonesApi.GetZoneOptions(request, jsonWriter);
  450. break;
  451. case "/api/zone/options/set":
  452. _zonesApi.SetZoneOptions(request);
  453. break;
  454. case "/api/zone/resync":
  455. _zonesApi.ResyncZone(request);
  456. break;
  457. case "/api/zone/addRecord":
  458. case "/api/addRecord":
  459. _zonesApi.AddRecord(request);
  460. break;
  461. case "/api/zone/getRecords":
  462. case "/api/getRecords":
  463. _zonesApi.GetRecords(request, jsonWriter);
  464. break;
  465. case "/api/zone/deleteRecord":
  466. case "/api/deleteRecord":
  467. _zonesApi.DeleteRecord(request);
  468. break;
  469. case "/api/zone/updateRecord":
  470. case "/api/updateRecord":
  471. _zonesApi.UpdateRecord(request);
  472. break;
  473. case "/api/apps/list":
  474. await _appsApi.ListInstalledAppsAsync(jsonWriter);
  475. break;
  476. case "/api/apps/listStoreApps":
  477. await _appsApi.ListStoreApps(jsonWriter);
  478. break;
  479. case "/api/apps/downloadAndInstall":
  480. await _appsApi.DownloadAndInstallAppAsync(request);
  481. break;
  482. case "/api/apps/downloadAndUpdate":
  483. await _appsApi.DownloadAndUpdateAppAsync(request);
  484. break;
  485. case "/api/apps/install":
  486. await _appsApi.InstallAppAsync(request);
  487. break;
  488. case "/api/apps/update":
  489. await _appsApi.UpdateAppAsync(request);
  490. break;
  491. case "/api/apps/uninstall":
  492. _appsApi.UninstallApp(request);
  493. break;
  494. case "/api/apps/getConfig":
  495. await _appsApi.GetAppConfigAsync(request, jsonWriter);
  496. break;
  497. case "/api/apps/setConfig":
  498. await _appsApi.SetAppConfigAsync(request);
  499. break;
  500. case "/api/resolveQuery":
  501. await ResolveQuery(request, jsonWriter);
  502. break;
  503. case "/api/listLogs":
  504. _logsApi.ListLogs(jsonWriter);
  505. break;
  506. case "/api/deleteLog":
  507. _logsApi.DeleteLog(request);
  508. break;
  509. case "/api/deleteAllLogs":
  510. _logsApi.DeleteAllLogs(request);
  511. break;
  512. case "/api/deleteAllStats":
  513. _logsApi.DeleteAllStats(request);
  514. break;
  515. case "/api/queryLogs":
  516. await _logsApi.QueryLogsAsync(request, jsonWriter);
  517. break;
  518. case "/api/listDhcpScopes":
  519. _dhcpApi.ListDhcpScopes(jsonWriter);
  520. break;
  521. case "/api/listDhcpLeases":
  522. _dhcpApi.ListDhcpLeases(jsonWriter);
  523. break;
  524. case "/api/getDhcpScope":
  525. _dhcpApi.GetDhcpScope(request, jsonWriter);
  526. break;
  527. case "/api/setDhcpScope":
  528. await _dhcpApi.SetDhcpScopeAsync(request);
  529. break;
  530. case "/api/enableDhcpScope":
  531. await _dhcpApi.EnableDhcpScopeAsync(request);
  532. break;
  533. case "/api/disableDhcpScope":
  534. _dhcpApi.DisableDhcpScope(request);
  535. break;
  536. case "/api/deleteDhcpScope":
  537. _dhcpApi.DeleteDhcpScope(request);
  538. break;
  539. case "/api/removeDhcpLease":
  540. _dhcpApi.RemoveDhcpLease(request);
  541. break;
  542. case "/api/convertToReservedLease":
  543. _dhcpApi.ConvertToReservedLease(request);
  544. break;
  545. case "/api/convertToDynamicLease":
  546. _dhcpApi.ConvertToDynamicLease(request);
  547. break;
  548. default:
  549. await SendErrorAsync(response, 404);
  550. return;
  551. }
  552. }
  553. finally
  554. {
  555. jsonWriter.WriteEndObject();
  556. }
  557. break;
  558. }
  559. jsonWriter.WritePropertyName("status");
  560. jsonWriter.WriteValue("ok");
  561. jsonWriter.WriteEndObject();
  562. jsonWriter.Flush();
  563. }
  564. catch (InvalidTokenWebServiceException ex)
  565. {
  566. mS.SetLength(0);
  567. JsonTextWriter jsonWriter = new JsonTextWriter(new StreamWriter(mS));
  568. jsonWriter.WriteStartObject();
  569. jsonWriter.WritePropertyName("status");
  570. jsonWriter.WriteValue("invalid-token");
  571. jsonWriter.WritePropertyName("errorMessage");
  572. jsonWriter.WriteValue(ex.Message);
  573. jsonWriter.WriteEndObject();
  574. jsonWriter.Flush();
  575. }
  576. catch (Exception ex)
  577. {
  578. _log.Write(GetRequestRemoteEndPoint(request), ex);
  579. mS.SetLength(0);
  580. JsonTextWriter jsonWriter = new JsonTextWriter(new StreamWriter(mS));
  581. jsonWriter.WriteStartObject();
  582. jsonWriter.WritePropertyName("status");
  583. jsonWriter.WriteValue("error");
  584. jsonWriter.WritePropertyName("errorMessage");
  585. jsonWriter.WriteValue(ex.Message);
  586. jsonWriter.WritePropertyName("stackTrace");
  587. jsonWriter.WriteValue(ex.StackTrace);
  588. if (ex.InnerException != null)
  589. {
  590. jsonWriter.WritePropertyName("innerErrorMessage");
  591. jsonWriter.WriteValue(ex.InnerException.Message);
  592. }
  593. jsonWriter.WriteEndObject();
  594. jsonWriter.Flush();
  595. }
  596. response.ContentType = "application/json; charset=utf-8";
  597. response.ContentEncoding = Encoding.UTF8;
  598. response.ContentLength64 = mS.Length;
  599. mS.Position = 0;
  600. using (Stream stream = response.OutputStream)
  601. {
  602. await mS.CopyToAsync(stream);
  603. }
  604. }
  605. }
  606. else if (path.StartsWith("/log/"))
  607. {
  608. if (!IsSessionValid(request))
  609. {
  610. await SendErrorAsync(response, 403, "Invalid token or session expired.");
  611. return;
  612. }
  613. string[] pathParts = path.Split('/');
  614. string logFileName = pathParts[2];
  615. int limit = 0;
  616. string strLimit = request.QueryString["limit"];
  617. if (!string.IsNullOrEmpty(strLimit))
  618. limit = int.Parse(strLimit);
  619. await _log.DownloadLogAsync(request, response, logFileName, limit * 1024 * 1024);
  620. }
  621. else
  622. {
  623. if (path == "/")
  624. {
  625. path = "/index.html";
  626. }
  627. else if ((path == "/blocklist.txt") && !IPAddress.IsLoopback(GetRequestRemoteEndPoint(request).Address))
  628. {
  629. await SendErrorAsync(response, 403);
  630. return;
  631. }
  632. string wwwroot = Path.Combine(_appFolder, "www");
  633. path = Path.GetFullPath(wwwroot + path.Replace('/', Path.DirectorySeparatorChar));
  634. if (!path.StartsWith(wwwroot) || !File.Exists(path))
  635. {
  636. await SendErrorAsync(response, 404);
  637. return;
  638. }
  639. await SendFileAsync(request, response, path);
  640. }
  641. }
  642. catch (Exception ex)
  643. {
  644. if ((_state == ServiceState.Stopping) || (_state == ServiceState.Stopped))
  645. return; //web service stopping
  646. _log.Write(GetRequestRemoteEndPoint(request), ex);
  647. await SendError(response, ex);
  648. }
  649. }
  650. internal static IPEndPoint GetRequestRemoteEndPoint(HttpListenerRequest request)
  651. {
  652. try
  653. {
  654. if (request.RemoteEndPoint == null)
  655. return new IPEndPoint(IPAddress.Any, 0);
  656. if (NetUtilities.IsPrivateIP(request.RemoteEndPoint.Address))
  657. {
  658. string xRealIp = request.Headers["X-Real-IP"];
  659. if (IPAddress.TryParse(xRealIp, out IPAddress address))
  660. {
  661. //get the real IP address of the requesting client from X-Real-IP header set in nginx proxy_pass block
  662. return new IPEndPoint(address, 0);
  663. }
  664. }
  665. return request.RemoteEndPoint;
  666. }
  667. catch
  668. {
  669. return new IPEndPoint(IPAddress.Any, 0);
  670. }
  671. }
  672. public static Stream GetOutputStream(HttpListenerRequest request, HttpListenerResponse response)
  673. {
  674. string strAcceptEncoding = request.Headers["Accept-Encoding"];
  675. if (string.IsNullOrEmpty(strAcceptEncoding))
  676. {
  677. return response.OutputStream;
  678. }
  679. else
  680. {
  681. if (strAcceptEncoding.Contains("gzip"))
  682. {
  683. response.AddHeader("Content-Encoding", "gzip");
  684. return new GZipStream(response.OutputStream, CompressionMode.Compress);
  685. }
  686. else if (strAcceptEncoding.Contains("deflate"))
  687. {
  688. response.AddHeader("Content-Encoding", "deflate");
  689. return new DeflateStream(response.OutputStream, CompressionMode.Compress);
  690. }
  691. else
  692. {
  693. return response.OutputStream;
  694. }
  695. }
  696. }
  697. private static Task SendError(HttpListenerResponse response, Exception ex)
  698. {
  699. return SendErrorAsync(response, 500, ex.ToString());
  700. }
  701. private static async Task SendErrorAsync(HttpListenerResponse response, int statusCode, string message = null)
  702. {
  703. try
  704. {
  705. string statusString = statusCode + " " + DnsServer.GetHttpStatusString((HttpStatusCode)statusCode);
  706. byte[] buffer = Encoding.UTF8.GetBytes("<html><head><title>" + statusString + "</title></head><body><h1>" + statusString + "</h1>" + (message == null ? "" : "<p>" + message + "</p>") + "</body></html>");
  707. response.StatusCode = statusCode;
  708. response.ContentType = "text/html";
  709. response.ContentLength64 = buffer.Length;
  710. using (Stream stream = response.OutputStream)
  711. {
  712. await stream.WriteAsync(buffer);
  713. }
  714. }
  715. catch
  716. { }
  717. }
  718. private static async Task SendFileAsync(HttpListenerRequest request, HttpListenerResponse response, string filePath)
  719. {
  720. using (FileStream fS = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
  721. {
  722. response.ContentType = WebUtilities.GetContentType(filePath).MediaType;
  723. response.AddHeader("Cache-Control", "private, max-age=300");
  724. using (Stream stream = GetOutputStream(request, response))
  725. {
  726. try
  727. {
  728. await fS.CopyToAsync(stream);
  729. }
  730. catch (HttpListenerException)
  731. {
  732. //ignore this error
  733. }
  734. }
  735. }
  736. }
  737. #endregion
  738. #region user session
  739. private string CreateSession(string username)
  740. {
  741. string token = BinaryNumber.GenerateRandomNumber256().ToString();
  742. if (!_sessions.TryAdd(token, new UserSession(username)))
  743. throw new DnsWebServiceException("Error while creating session. Please try again.");
  744. return token;
  745. }
  746. private UserSession GetSession(string token)
  747. {
  748. if (_sessions.TryGetValue(token, out UserSession session))
  749. return session;
  750. return null;
  751. }
  752. internal UserSession GetSession(HttpListenerRequest request)
  753. {
  754. string strToken = request.QueryString["token"];
  755. if (string.IsNullOrEmpty(strToken))
  756. throw new DnsWebServiceException("Parameter 'token' missing.");
  757. return GetSession(strToken);
  758. }
  759. private UserSession DeleteSession(string token)
  760. {
  761. if (_sessions.TryRemove(token, out UserSession session))
  762. return session;
  763. return null;
  764. }
  765. private UserSession DeleteSession(HttpListenerRequest request)
  766. {
  767. string strToken = request.QueryString["token"];
  768. if (string.IsNullOrEmpty(strToken))
  769. throw new DnsWebServiceException("Parameter 'token' missing.");
  770. return DeleteSession(strToken);
  771. }
  772. private void FailedLoginAttempt(IPAddress address)
  773. {
  774. _failedLoginAttempts.AddOrUpdate(address, 1, delegate (IPAddress key, int attempts)
  775. {
  776. return attempts + 1;
  777. });
  778. }
  779. private bool LoginAttemptsExceedLimit(IPAddress address, int limit)
  780. {
  781. if (!_failedLoginAttempts.TryGetValue(address, out int attempts))
  782. return false;
  783. return attempts >= limit;
  784. }
  785. private void ResetFailedLoginAttempt(IPAddress address)
  786. {
  787. _failedLoginAttempts.TryRemove(address, out _);
  788. }
  789. private void BlockAddress(IPAddress address, int interval)
  790. {
  791. _blockedAddresses.TryAdd(address, DateTime.UtcNow.AddMilliseconds(interval));
  792. }
  793. private bool IsAddressBlocked(IPAddress address)
  794. {
  795. if (!_blockedAddresses.TryGetValue(address, out DateTime expiry))
  796. return false;
  797. if (expiry > DateTime.UtcNow)
  798. {
  799. return true;
  800. }
  801. else
  802. {
  803. UnblockAddress(address);
  804. ResetFailedLoginAttempt(address);
  805. return false;
  806. }
  807. }
  808. private void UnblockAddress(IPAddress address)
  809. {
  810. _blockedAddresses.TryRemove(address, out _);
  811. }
  812. #endregion
  813. #region auth api
  814. private async Task LoginAsync(HttpListenerRequest request, JsonTextWriter jsonWriter)
  815. {
  816. string strUsername = request.QueryString["user"];
  817. if (string.IsNullOrEmpty(strUsername))
  818. throw new DnsWebServiceException("Parameter 'user' missing.");
  819. string strPassword = request.QueryString["pass"];
  820. if (string.IsNullOrEmpty(strPassword))
  821. throw new DnsWebServiceException("Parameter 'pass' missing.");
  822. IPEndPoint remoteEP = GetRequestRemoteEndPoint(request);
  823. if (IsAddressBlocked(remoteEP.Address))
  824. throw new DnsWebServiceException("Max limit of " + MAX_LOGIN_ATTEMPTS + " attempts exceeded. Access blocked for " + (BLOCK_ADDRESS_INTERVAL / 1000) + " seconds.");
  825. strUsername = strUsername.Trim().ToLower();
  826. string strPasswordHash = GetPasswordHash(strUsername, strPassword);
  827. if (!_credentials.TryGetValue(strUsername, out string passwordHash) || (passwordHash != strPasswordHash))
  828. {
  829. if (strPassword != "admin") //exception for default password
  830. {
  831. FailedLoginAttempt(remoteEP.Address);
  832. if (LoginAttemptsExceedLimit(remoteEP.Address, MAX_LOGIN_ATTEMPTS))
  833. BlockAddress(remoteEP.Address, BLOCK_ADDRESS_INTERVAL);
  834. await Task.Delay(1000);
  835. }
  836. throw new DnsWebServiceException("Invalid username or password for user: " + strUsername);
  837. }
  838. ResetFailedLoginAttempt(remoteEP.Address);
  839. _log.Write(remoteEP, "[" + strUsername + "] User logged in.");
  840. string token = CreateSession(strUsername);
  841. jsonWriter.WritePropertyName("token");
  842. jsonWriter.WriteValue(token);
  843. }
  844. private bool IsSessionValid(HttpListenerRequest request)
  845. {
  846. UserSession session = GetSession(request);
  847. if (session == null)
  848. return false;
  849. if (session.HasExpired())
  850. {
  851. DeleteSession(request);
  852. return false;
  853. }
  854. session.UpdateLastSeen();
  855. return true;
  856. }
  857. private void ChangePassword(HttpListenerRequest request)
  858. {
  859. string strToken = request.QueryString["token"];
  860. if (string.IsNullOrEmpty(strToken))
  861. throw new DnsWebServiceException("Parameter 'token' missing.");
  862. string strPassword = request.QueryString["pass"];
  863. if (string.IsNullOrEmpty(strPassword))
  864. throw new DnsWebServiceException("Parameter 'pass' missing.");
  865. UserSession session = GetSession(strToken);
  866. if (session == null)
  867. throw new DnsWebServiceException("User session does not exists.");
  868. SetCredentials(session.Username, strPassword);
  869. SaveConfigFile();
  870. _log.Write(GetRequestRemoteEndPoint(request), "[" + session.Username + "] Password was changed for user.");
  871. }
  872. private void Logout(HttpListenerRequest request)
  873. {
  874. string strToken = request.QueryString["token"];
  875. if (string.IsNullOrEmpty(strToken))
  876. throw new DnsWebServiceException("Parameter 'token' missing.");
  877. UserSession session = DeleteSession(strToken);
  878. if (session != null)
  879. _log.Write(GetRequestRemoteEndPoint(request), "[" + session.Username + "] User logged out.");
  880. }
  881. #endregion
  882. #region update api
  883. private async Task CheckForUpdateAsync(HttpListenerRequest request, JsonTextWriter jsonWriter)
  884. {
  885. if (_updateCheckUri is null)
  886. {
  887. jsonWriter.WritePropertyName("updateAvailable");
  888. jsonWriter.WriteValue(false);
  889. return;
  890. }
  891. try
  892. {
  893. SocketsHttpHandler handler = new SocketsHttpHandler();
  894. handler.Proxy = _dnsServer.Proxy;
  895. using (HttpClient http = new HttpClient(handler))
  896. {
  897. string response = await http.GetStringAsync(_updateCheckUri);
  898. dynamic jsonResponse = JsonConvert.DeserializeObject(response);
  899. string updateVersion = jsonResponse.updateVersion.Value;
  900. string updateTitle = jsonResponse.updateTitle?.Value;
  901. string updateMessage = jsonResponse.updateMessage?.Value;
  902. string downloadLink = jsonResponse.downloadLink?.Value;
  903. string instructionsLink = jsonResponse.instructionsLink?.Value;
  904. string changeLogLink = jsonResponse.changeLogLink?.Value;
  905. bool updateAvailable = new Version(updateVersion) > _currentVersion;
  906. jsonWriter.WritePropertyName("updateAvailable");
  907. jsonWriter.WriteValue(updateAvailable);
  908. jsonWriter.WritePropertyName("updateVersion");
  909. jsonWriter.WriteValue(updateVersion);
  910. jsonWriter.WritePropertyName("currentVersion");
  911. jsonWriter.WriteValue(GetCleanVersion(_currentVersion));
  912. if (updateAvailable)
  913. {
  914. jsonWriter.WritePropertyName("updateTitle");
  915. jsonWriter.WriteValue(updateTitle);
  916. jsonWriter.WritePropertyName("updateMessage");
  917. jsonWriter.WriteValue(updateMessage);
  918. jsonWriter.WritePropertyName("downloadLink");
  919. jsonWriter.WriteValue(downloadLink);
  920. jsonWriter.WritePropertyName("instructionsLink");
  921. jsonWriter.WriteValue(instructionsLink);
  922. jsonWriter.WritePropertyName("changeLogLink");
  923. jsonWriter.WriteValue(changeLogLink);
  924. }
  925. string strLog = "Check for update was done {updateAvailable: " + updateAvailable + "; updateVersion: " + updateVersion + ";";
  926. if (!string.IsNullOrEmpty(updateTitle))
  927. strLog += " updateTitle: " + updateTitle + ";";
  928. if (!string.IsNullOrEmpty(updateMessage))
  929. strLog += " updateMessage: " + updateMessage + ";";
  930. if (!string.IsNullOrEmpty(downloadLink))
  931. strLog += " downloadLink: " + downloadLink + ";";
  932. if (!string.IsNullOrEmpty(instructionsLink))
  933. strLog += " instructionsLink: " + instructionsLink + ";";
  934. if (!string.IsNullOrEmpty(changeLogLink))
  935. strLog += " changeLogLink: " + changeLogLink + ";";
  936. strLog += "}";
  937. _log.Write(GetRequestRemoteEndPoint(request), strLog);
  938. }
  939. }
  940. catch (Exception ex)
  941. {
  942. _log.Write(GetRequestRemoteEndPoint(request), "Check for update was done {updateAvailable: False;}\r\n" + ex.ToString());
  943. jsonWriter.WritePropertyName("updateAvailable");
  944. jsonWriter.WriteValue(false);
  945. }
  946. }
  947. internal static string GetCleanVersion(Version version)
  948. {
  949. string strVersion = version.Major + "." + version.Minor;
  950. if (version.Build > 0)
  951. strVersion += "." + version.Build;
  952. if (version.Revision > 0)
  953. strVersion += "." + version.Revision;
  954. return strVersion;
  955. }
  956. #endregion
  957. #region settings api
  958. private void GetDnsSettings(JsonTextWriter jsonWriter)
  959. {
  960. jsonWriter.WritePropertyName("version");
  961. jsonWriter.WriteValue(GetCleanVersion(_currentVersion));
  962. jsonWriter.WritePropertyName("dnsServerDomain");
  963. jsonWriter.WriteValue(_dnsServer.ServerDomain);
  964. jsonWriter.WritePropertyName("dnsServerLocalEndPoints");
  965. jsonWriter.WriteStartArray();
  966. foreach (IPEndPoint localEP in _dnsServer.LocalEndPoints)
  967. jsonWriter.WriteValue(localEP.ToString());
  968. jsonWriter.WriteEndArray();
  969. jsonWriter.WritePropertyName("webServiceLocalAddresses");
  970. jsonWriter.WriteStartArray();
  971. foreach (IPAddress localAddress in _webServiceLocalAddresses)
  972. {
  973. if (localAddress.AddressFamily == AddressFamily.InterNetworkV6)
  974. jsonWriter.WriteValue("[" + localAddress.ToString() + "]");
  975. else
  976. jsonWriter.WriteValue(localAddress.ToString());
  977. }
  978. jsonWriter.WriteEndArray();
  979. jsonWriter.WritePropertyName("webServiceHttpPort");
  980. jsonWriter.WriteValue(_webServiceHttpPort);
  981. jsonWriter.WritePropertyName("webServiceEnableTls");
  982. jsonWriter.WriteValue(_webServiceEnableTls);
  983. jsonWriter.WritePropertyName("webServiceHttpToTlsRedirect");
  984. jsonWriter.WriteValue(_webServiceHttpToTlsRedirect);
  985. jsonWriter.WritePropertyName("webServiceTlsPort");
  986. jsonWriter.WriteValue(_webServiceTlsPort);
  987. jsonWriter.WritePropertyName("webServiceUseSelfSignedTlsCertificate");
  988. jsonWriter.WriteValue(_webServiceUseSelfSignedTlsCertificate);
  989. jsonWriter.WritePropertyName("webServiceTlsCertificatePath");
  990. jsonWriter.WriteValue(_webServiceTlsCertificatePath);
  991. jsonWriter.WritePropertyName("webServiceTlsCertificatePassword");
  992. jsonWriter.WriteValue("************");
  993. jsonWriter.WritePropertyName("enableDnsOverHttp");
  994. jsonWriter.WriteValue(_dnsServer.EnableDnsOverHttp);
  995. jsonWriter.WritePropertyName("enableDnsOverTls");
  996. jsonWriter.WriteValue(_dnsServer.EnableDnsOverTls);
  997. jsonWriter.WritePropertyName("enableDnsOverHttps");
  998. jsonWriter.WriteValue(_dnsServer.EnableDnsOverHttps);
  999. jsonWriter.WritePropertyName("dnsTlsCertificatePath");
  1000. jsonWriter.WriteValue(_dnsTlsCertificatePath);
  1001. jsonWriter.WritePropertyName("dnsTlsCertificatePassword");
  1002. jsonWriter.WriteValue("************");
  1003. jsonWriter.WritePropertyName("tsigKeys");
  1004. {
  1005. jsonWriter.WriteStartArray();
  1006. if (_dnsServer.TsigKeys is not null)
  1007. {
  1008. foreach (KeyValuePair<string, TsigKey> tsigKey in _dnsServer.TsigKeys)
  1009. {
  1010. jsonWriter.WriteStartObject();
  1011. jsonWriter.WritePropertyName("keyName");
  1012. jsonWriter.WriteValue(tsigKey.Key);
  1013. jsonWriter.WritePropertyName("sharedSecret");
  1014. jsonWriter.WriteValue(tsigKey.Value.SharedSecret);
  1015. jsonWriter.WritePropertyName("algorithmName");
  1016. jsonWriter.WriteValue(tsigKey.Value.AlgorithmName);
  1017. jsonWriter.WriteEndObject();
  1018. }
  1019. }
  1020. jsonWriter.WriteEndArray();
  1021. }
  1022. jsonWriter.WritePropertyName("defaultRecordTtl");
  1023. jsonWriter.WriteValue(_zonesApi.DefaultRecordTtl);
  1024. jsonWriter.WritePropertyName("preferIPv6");
  1025. jsonWriter.WriteValue(_dnsServer.PreferIPv6);
  1026. jsonWriter.WritePropertyName("udpPayloadSize");
  1027. jsonWriter.WriteValue(_dnsServer.UdpPayloadSize);
  1028. jsonWriter.WritePropertyName("dnssecValidation");
  1029. jsonWriter.WriteValue(_dnsServer.DnssecValidation);
  1030. jsonWriter.WritePropertyName("resolverRetries");
  1031. jsonWriter.WriteValue(_dnsServer.ResolverRetries);
  1032. jsonWriter.WritePropertyName("resolverTimeout");
  1033. jsonWriter.WriteValue(_dnsServer.ResolverTimeout);
  1034. jsonWriter.WritePropertyName("resolverMaxStackCount");
  1035. jsonWriter.WriteValue(_dnsServer.ResolverMaxStackCount);
  1036. jsonWriter.WritePropertyName("forwarderRetries");
  1037. jsonWriter.WriteValue(_dnsServer.ForwarderRetries);
  1038. jsonWriter.WritePropertyName("forwarderTimeout");
  1039. jsonWriter.WriteValue(_dnsServer.ForwarderTimeout);
  1040. jsonWriter.WritePropertyName("forwarderConcurrency");
  1041. jsonWriter.WriteValue(_dnsServer.ForwarderConcurrency);
  1042. jsonWriter.WritePropertyName("clientTimeout");
  1043. jsonWriter.WriteValue(_dnsServer.ClientTimeout);
  1044. jsonWriter.WritePropertyName("tcpSendTimeout");
  1045. jsonWriter.WriteValue(_dnsServer.TcpSendTimeout);
  1046. jsonWriter.WritePropertyName("tcpReceiveTimeout");
  1047. jsonWriter.WriteValue(_dnsServer.TcpReceiveTimeout);
  1048. jsonWriter.WritePropertyName("enableLogging");
  1049. jsonWriter.WriteValue(_log.EnableLogging);
  1050. jsonWriter.WritePropertyName("logQueries");
  1051. jsonWriter.WriteValue(_dnsServer.QueryLogManager != null);
  1052. jsonWriter.WritePropertyName("useLocalTime");
  1053. jsonWriter.WriteValue(_log.UseLocalTime);
  1054. jsonWriter.WritePropertyName("logFolder");
  1055. jsonWriter.WriteValue(_log.LogFolder);
  1056. jsonWriter.WritePropertyName("maxLogFileDays");
  1057. jsonWriter.WriteValue(_log.MaxLogFileDays);
  1058. jsonWriter.WritePropertyName("maxStatFileDays");
  1059. jsonWriter.WriteValue(_dnsServer.StatsManager.MaxStatFileDays);
  1060. jsonWriter.WritePropertyName("recursion");
  1061. jsonWriter.WriteValue(_dnsServer.Recursion.ToString());
  1062. jsonWriter.WritePropertyName("recursionDeniedNetworks");
  1063. {
  1064. jsonWriter.WriteStartArray();
  1065. if (_dnsServer.RecursionDeniedNetworks is not null)
  1066. {
  1067. foreach (NetworkAddress networkAddress in _dnsServer.RecursionDeniedNetworks)
  1068. jsonWriter.WriteValue(networkAddress.ToString());
  1069. }
  1070. jsonWriter.WriteEndArray();
  1071. }
  1072. jsonWriter.WritePropertyName("recursionAllowedNetworks");
  1073. {
  1074. jsonWriter.WriteStartArray();
  1075. if (_dnsServer.RecursionAllowedNetworks is not null)
  1076. {
  1077. foreach (NetworkAddress networkAddress in _dnsServer.RecursionAllowedNetworks)
  1078. jsonWriter.WriteValue(networkAddress.ToString());
  1079. }
  1080. jsonWriter.WriteEndArray();
  1081. }
  1082. jsonWriter.WritePropertyName("randomizeName");
  1083. jsonWriter.WriteValue(_dnsServer.RandomizeName);
  1084. jsonWriter.WritePropertyName("qnameMinimization");
  1085. jsonWriter.WriteValue(_dnsServer.QnameMinimization);
  1086. jsonWriter.WritePropertyName("nsRevalidation");
  1087. jsonWriter.WriteValue(_dnsServer.NsRevalidation);
  1088. jsonWriter.WritePropertyName("qpmLimitRequests");
  1089. jsonWriter.WriteValue(_dnsServer.QpmLimitRequests);
  1090. jsonWriter.WritePropertyName("qpmLimitErrors");
  1091. jsonWriter.WriteValue(_dnsServer.QpmLimitErrors);
  1092. jsonWriter.WritePropertyName("qpmLimitSampleMinutes");
  1093. jsonWriter.WriteValue(_dnsServer.QpmLimitSampleMinutes);
  1094. jsonWriter.WritePropertyName("qpmLimitIPv4PrefixLength");
  1095. jsonWriter.WriteValue(_dnsServer.QpmLimitIPv4PrefixLength);
  1096. jsonWriter.WritePropertyName("qpmLimitIPv6PrefixLength");
  1097. jsonWriter.WriteValue(_dnsServer.QpmLimitIPv6PrefixLength);
  1098. jsonWriter.WritePropertyName("serveStale");
  1099. jsonWriter.WriteValue(_dnsServer.ServeStale);
  1100. jsonWriter.WritePropertyName("serveStaleTtl");
  1101. jsonWriter.WriteValue(_dnsServer.CacheZoneManager.ServeStaleTtl);
  1102. jsonWriter.WritePropertyName("cacheMinimumRecordTtl");
  1103. jsonWriter.WriteValue(_dnsServer.CacheZoneManager.MinimumRecordTtl);
  1104. jsonWriter.WritePropertyName("cacheMaximumRecordTtl");
  1105. jsonWriter.WriteValue(_dnsServer.CacheZoneManager.MaximumRecordTtl);
  1106. jsonWriter.WritePropertyName("cacheNegativeRecordTtl");
  1107. jsonWriter.WriteValue(_dnsServer.CacheZoneManager.NegativeRecordTtl);
  1108. jsonWriter.WritePropertyName("cacheFailureRecordTtl");
  1109. jsonWriter.WriteValue(_dnsServer.CacheZoneManager.FailureRecordTtl);
  1110. jsonWriter.WritePropertyName("cachePrefetchEligibility");
  1111. jsonWriter.WriteValue(_dnsServer.CachePrefetchEligibility);
  1112. jsonWriter.WritePropertyName("cachePrefetchTrigger");
  1113. jsonWriter.WriteValue(_dnsServer.CachePrefetchTrigger);
  1114. jsonWriter.WritePropertyName("cachePrefetchSampleIntervalInMinutes");
  1115. jsonWriter.WriteValue(_dnsServer.CachePrefetchSampleIntervalInMinutes);
  1116. jsonWriter.WritePropertyName("cachePrefetchSampleEligibilityHitsPerHour");
  1117. jsonWriter.WriteValue(_dnsServer.CachePrefetchSampleEligibilityHitsPerHour);
  1118. jsonWriter.WritePropertyName("proxy");
  1119. if (_dnsServer.Proxy == null)
  1120. {
  1121. jsonWriter.WriteNull();
  1122. }
  1123. else
  1124. {
  1125. jsonWriter.WriteStartObject();
  1126. NetProxy proxy = _dnsServer.Proxy;
  1127. jsonWriter.WritePropertyName("type");
  1128. jsonWriter.WriteValue(proxy.Type.ToString());
  1129. jsonWriter.WritePropertyName("address");
  1130. jsonWriter.WriteValue(proxy.Address);
  1131. jsonWriter.WritePropertyName("port");
  1132. jsonWriter.WriteValue(proxy.Port);
  1133. NetworkCredential credential = proxy.Credential;
  1134. if (credential != null)
  1135. {
  1136. jsonWriter.WritePropertyName("username");
  1137. jsonWriter.WriteValue(credential.UserName);
  1138. jsonWriter.WritePropertyName("password");
  1139. jsonWriter.WriteValue(credential.Password);
  1140. }
  1141. jsonWriter.WritePropertyName("bypass");
  1142. jsonWriter.WriteStartArray();
  1143. foreach (NetProxyBypassItem item in proxy.BypassList)
  1144. jsonWriter.WriteValue(item.Value);
  1145. jsonWriter.WriteEndArray();
  1146. jsonWriter.WriteEndObject();
  1147. }
  1148. jsonWriter.WritePropertyName("forwarders");
  1149. DnsTransportProtocol forwarderProtocol = DnsTransportProtocol.Udp;
  1150. if (_dnsServer.Forwarders == null)
  1151. {
  1152. jsonWriter.WriteNull();
  1153. }
  1154. else
  1155. {
  1156. forwarderProtocol = _dnsServer.Forwarders[0].Protocol;
  1157. jsonWriter.WriteStartArray();
  1158. foreach (NameServerAddress forwarder in _dnsServer.Forwarders)
  1159. jsonWriter.WriteValue(forwarder.OriginalAddress);
  1160. jsonWriter.WriteEndArray();
  1161. }
  1162. jsonWriter.WritePropertyName("forwarderProtocol");
  1163. jsonWriter.WriteValue(forwarderProtocol.ToString());
  1164. jsonWriter.WritePropertyName("enableBlocking");
  1165. jsonWriter.WriteValue(_dnsServer.EnableBlocking);
  1166. jsonWriter.WritePropertyName("allowTxtBlockingReport");
  1167. jsonWriter.WriteValue(_dnsServer.AllowTxtBlockingReport);
  1168. if (!_dnsServer.EnableBlocking && (DateTime.UtcNow < _temporaryDisableBlockingTill))
  1169. {
  1170. jsonWriter.WritePropertyName("temporaryDisableBlockingTill");
  1171. jsonWriter.WriteValue(_temporaryDisableBlockingTill);
  1172. }
  1173. jsonWriter.WritePropertyName("blockingType");
  1174. jsonWriter.WriteValue(_dnsServer.BlockingType.ToString());
  1175. jsonWriter.WritePropertyName("customBlockingAddresses");
  1176. jsonWriter.WriteStartArray();
  1177. foreach (DnsARecordData record in _dnsServer.CustomBlockingARecords)
  1178. jsonWriter.WriteValue(record.Address.ToString());
  1179. foreach (DnsAAAARecordData record in _dnsServer.CustomBlockingAAAARecords)
  1180. jsonWriter.WriteValue(record.Address.ToString());
  1181. jsonWriter.WriteEndArray();
  1182. jsonWriter.WritePropertyName("blockListUrls");
  1183. if ((_dnsServer.BlockListZoneManager.AllowListUrls.Count == 0) && (_dnsServer.BlockListZoneManager.BlockListUrls.Count == 0))
  1184. {
  1185. jsonWriter.WriteNull();
  1186. }
  1187. else
  1188. {
  1189. jsonWriter.WriteStartArray();
  1190. foreach (Uri allowListUrl in _dnsServer.BlockListZoneManager.AllowListUrls)
  1191. jsonWriter.WriteValue("!" + allowListUrl.AbsoluteUri);
  1192. foreach (Uri blockListUrl in _dnsServer.BlockListZoneManager.BlockListUrls)
  1193. jsonWriter.WriteValue(blockListUrl.AbsoluteUri);
  1194. jsonWriter.WriteEndArray();
  1195. }
  1196. jsonWriter.WritePropertyName("blockListUpdateIntervalHours");
  1197. jsonWriter.WriteValue(_blockListUpdateIntervalHours);
  1198. if (_blockListUpdateTimer is not null)
  1199. {
  1200. DateTime blockListNextUpdatedOn = _blockListLastUpdatedOn.AddHours(_blockListUpdateIntervalHours);
  1201. jsonWriter.WritePropertyName("blockListNextUpdatedOn");
  1202. jsonWriter.WriteValue(blockListNextUpdatedOn);
  1203. }
  1204. }
  1205. private void SetDnsSettings(HttpListenerRequest request, JsonTextWriter jsonWriter)
  1206. {
  1207. bool restartDnsService = false;
  1208. bool restartWebService = false;
  1209. string strDnsServerDomain = request.QueryString["dnsServerDomain"];
  1210. if (!string.IsNullOrEmpty(strDnsServerDomain))
  1211. _dnsServer.ServerDomain = strDnsServerDomain;
  1212. string strDnsServerLocalEndPoints = request.QueryString["dnsServerLocalEndPoints"];
  1213. if (strDnsServerLocalEndPoints != null)
  1214. {
  1215. if (string.IsNullOrEmpty(strDnsServerLocalEndPoints))
  1216. strDnsServerLocalEndPoints = "0.0.0.0:53,[::]:53";
  1217. string[] strLocalEndPoints = strDnsServerLocalEndPoints.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  1218. List<IPEndPoint> localEndPoints = new List<IPEndPoint>(strLocalEndPoints.Length);
  1219. for (int i = 0; i < strLocalEndPoints.Length; i++)
  1220. {
  1221. NameServerAddress nameServer = new NameServerAddress(strLocalEndPoints[i]);
  1222. if (nameServer.IPEndPoint != null)
  1223. localEndPoints.Add(nameServer.IPEndPoint);
  1224. }
  1225. if (localEndPoints.Count > 0)
  1226. {
  1227. if (_dnsServer.LocalEndPoints.Count != localEndPoints.Count)
  1228. {
  1229. restartDnsService = true;
  1230. }
  1231. else
  1232. {
  1233. foreach (IPEndPoint currentLocalEP in _dnsServer.LocalEndPoints)
  1234. {
  1235. if (!localEndPoints.Contains(currentLocalEP))
  1236. {
  1237. restartDnsService = true;
  1238. break;
  1239. }
  1240. }
  1241. }
  1242. _dnsServer.LocalEndPoints = localEndPoints;
  1243. }
  1244. }
  1245. string strWebServiceLocalAddresses = request.QueryString["webServiceLocalAddresses"];
  1246. if (strWebServiceLocalAddresses != null)
  1247. {
  1248. if (string.IsNullOrEmpty(strWebServiceLocalAddresses))
  1249. strWebServiceLocalAddresses = "0.0.0.0,[::]";
  1250. string[] strLocalAddresses = strWebServiceLocalAddresses.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  1251. List<IPAddress> localAddresses = new List<IPAddress>(strLocalAddresses.Length);
  1252. for (int i = 0; i < strLocalAddresses.Length; i++)
  1253. {
  1254. if (IPAddress.TryParse(strLocalAddresses[i], out IPAddress localAddress))
  1255. localAddresses.Add(localAddress);
  1256. }
  1257. if (localAddresses.Count > 0)
  1258. {
  1259. if (_webServiceLocalAddresses.Count != localAddresses.Count)
  1260. {
  1261. restartWebService = true;
  1262. }
  1263. else
  1264. {
  1265. foreach (IPAddress currentlocalAddress in _webServiceLocalAddresses)
  1266. {
  1267. if (!localAddresses.Contains(currentlocalAddress))
  1268. {
  1269. restartWebService = true;
  1270. break;
  1271. }
  1272. }
  1273. }
  1274. _webServiceLocalAddresses = localAddresses;
  1275. }
  1276. }
  1277. int oldWebServiceHttpPort = _webServiceHttpPort;
  1278. string strWebServiceHttpPort = request.QueryString["webServiceHttpPort"];
  1279. if (!string.IsNullOrEmpty(strWebServiceHttpPort))
  1280. {
  1281. _webServiceHttpPort = int.Parse(strWebServiceHttpPort);
  1282. if (oldWebServiceHttpPort != _webServiceHttpPort)
  1283. restartWebService = true;
  1284. }
  1285. string strWebServiceEnableTls = request.QueryString["webServiceEnableTls"];
  1286. if (!string.IsNullOrEmpty(strWebServiceEnableTls))
  1287. {
  1288. bool oldWebServiceEnableTls = _webServiceEnableTls;
  1289. _webServiceEnableTls = bool.Parse(strWebServiceEnableTls);
  1290. if (oldWebServiceEnableTls != _webServiceEnableTls)
  1291. restartWebService = true;
  1292. }
  1293. string strWebServiceHttpToTlsRedirect = request.QueryString["webServiceHttpToTlsRedirect"];
  1294. if (!string.IsNullOrEmpty(strWebServiceHttpToTlsRedirect))
  1295. _webServiceHttpToTlsRedirect = bool.Parse(strWebServiceHttpToTlsRedirect);
  1296. string strWebServiceTlsPort = request.QueryString["webServiceTlsPort"];
  1297. if (!string.IsNullOrEmpty(strWebServiceTlsPort))
  1298. {
  1299. int oldWebServiceTlsPort = _webServiceTlsPort;
  1300. _webServiceTlsPort = int.Parse(strWebServiceTlsPort);
  1301. if (oldWebServiceTlsPort != _webServiceTlsPort)
  1302. restartWebService = true;
  1303. }
  1304. string strWebServiceUseSelfSignedTlsCertificate = request.QueryString["webServiceUseSelfSignedTlsCertificate"];
  1305. if (!string.IsNullOrEmpty(strWebServiceUseSelfSignedTlsCertificate))
  1306. _webServiceUseSelfSignedTlsCertificate = bool.Parse(strWebServiceUseSelfSignedTlsCertificate);
  1307. string strWebServiceTlsCertificatePath = request.QueryString["webServiceTlsCertificatePath"];
  1308. string strWebServiceTlsCertificatePassword = request.QueryString["webServiceTlsCertificatePassword"];
  1309. if (string.IsNullOrEmpty(strWebServiceTlsCertificatePath))
  1310. {
  1311. _webServiceTlsCertificatePath = null;
  1312. _webServiceTlsCertificatePassword = "";
  1313. }
  1314. else
  1315. {
  1316. if (strWebServiceTlsCertificatePassword == "************")
  1317. strWebServiceTlsCertificatePassword = _webServiceTlsCertificatePassword;
  1318. if ((strWebServiceTlsCertificatePath != _webServiceTlsCertificatePath) || (strWebServiceTlsCertificatePassword != _webServiceTlsCertificatePassword))
  1319. {
  1320. LoadWebServiceTlsCertificate(strWebServiceTlsCertificatePath, strWebServiceTlsCertificatePassword);
  1321. _webServiceTlsCertificatePath = strWebServiceTlsCertificatePath;
  1322. _webServiceTlsCertificatePassword = strWebServiceTlsCertificatePassword;
  1323. StartTlsCertificateUpdateTimer();
  1324. }
  1325. }
  1326. string enableDnsOverHttp = request.QueryString["enableDnsOverHttp"];
  1327. if (!string.IsNullOrEmpty(enableDnsOverHttp))
  1328. {
  1329. bool oldEnableDnsOverHttp = _dnsServer.EnableDnsOverHttp;
  1330. _dnsServer.EnableDnsOverHttp = bool.Parse(enableDnsOverHttp);
  1331. if (oldEnableDnsOverHttp != _dnsServer.EnableDnsOverHttp)
  1332. restartDnsService = true;
  1333. }
  1334. string strEnableDnsOverTls = request.QueryString["enableDnsOverTls"];
  1335. if (!string.IsNullOrEmpty(strEnableDnsOverTls))
  1336. {
  1337. bool oldEnableDnsOverTls = _dnsServer.EnableDnsOverTls;
  1338. _dnsServer.EnableDnsOverTls = bool.Parse(strEnableDnsOverTls);
  1339. if (oldEnableDnsOverTls != _dnsServer.EnableDnsOverTls)
  1340. restartDnsService = true;
  1341. }
  1342. string strEnableDnsOverHttps = request.QueryString["enableDnsOverHttps"];
  1343. if (!string.IsNullOrEmpty(strEnableDnsOverHttps))
  1344. {
  1345. bool oldEnableDnsOverHttps = _dnsServer.EnableDnsOverHttps;
  1346. _dnsServer.EnableDnsOverHttps = bool.Parse(strEnableDnsOverHttps);
  1347. if (oldEnableDnsOverHttps != _dnsServer.EnableDnsOverHttps)
  1348. restartDnsService = true;
  1349. }
  1350. string strDnsTlsCertificatePath = request.QueryString["dnsTlsCertificatePath"];
  1351. string strDnsTlsCertificatePassword = request.QueryString["dnsTlsCertificatePassword"];
  1352. if (string.IsNullOrEmpty(strDnsTlsCertificatePath))
  1353. {
  1354. _dnsTlsCertificatePath = null;
  1355. _dnsTlsCertificatePassword = "";
  1356. }
  1357. else
  1358. {
  1359. if (strDnsTlsCertificatePassword == "************")
  1360. strDnsTlsCertificatePassword = _dnsTlsCertificatePassword;
  1361. if ((strDnsTlsCertificatePath != _dnsTlsCertificatePath) || (strDnsTlsCertificatePassword != _dnsTlsCertificatePassword))
  1362. {
  1363. LoadDnsTlsCertificate(strDnsTlsCertificatePath, strDnsTlsCertificatePassword);
  1364. _dnsTlsCertificatePath = strDnsTlsCertificatePath;
  1365. _dnsTlsCertificatePassword = strDnsTlsCertificatePassword;
  1366. StartTlsCertificateUpdateTimer();
  1367. }
  1368. }
  1369. string strTsigKeys = request.QueryString["tsigKeys"];
  1370. if (!string.IsNullOrEmpty(strTsigKeys))
  1371. {
  1372. if (strTsigKeys == "false")
  1373. {
  1374. _dnsServer.TsigKeys = null;
  1375. }
  1376. else
  1377. {
  1378. string[] strTsigKeyParts = strTsigKeys.Split('|');
  1379. Dictionary<string, TsigKey> tsigKeys = new Dictionary<string, TsigKey>(strTsigKeyParts.Length);
  1380. for (int i = 0; i < strTsigKeyParts.Length; i += 3)
  1381. {
  1382. string keyName = strTsigKeyParts[i + 0].ToLower();
  1383. string sharedSecret = strTsigKeyParts[i + 1];
  1384. string algorithmName = strTsigKeyParts[i + 2];
  1385. if (sharedSecret.Length == 0)
  1386. {
  1387. byte[] key = new byte[32];
  1388. _rng.GetBytes(key);
  1389. tsigKeys.Add(keyName, new TsigKey(keyName, Convert.ToBase64String(key), algorithmName));
  1390. }
  1391. else
  1392. {
  1393. tsigKeys.Add(keyName, new TsigKey(keyName, sharedSecret, algorithmName));
  1394. }
  1395. }
  1396. _dnsServer.TsigKeys = tsigKeys;
  1397. }
  1398. }
  1399. string strDefaultRecordTtl = request.QueryString["defaultRecordTtl"];
  1400. if (!string.IsNullOrEmpty(strDefaultRecordTtl))
  1401. _zonesApi.DefaultRecordTtl = uint.Parse(strDefaultRecordTtl);
  1402. string strPreferIPv6 = request.QueryString["preferIPv6"];
  1403. if (!string.IsNullOrEmpty(strPreferIPv6))
  1404. _dnsServer.PreferIPv6 = bool.Parse(strPreferIPv6);
  1405. string strUdpPayloadSize = request.QueryString["udpPayloadSize"];
  1406. if (!string.IsNullOrEmpty(strUdpPayloadSize))
  1407. _dnsServer.UdpPayloadSize = ushort.Parse(strUdpPayloadSize);
  1408. string strDnssecValidation = request.QueryString["dnssecValidation"];
  1409. if (!string.IsNullOrEmpty(strDnssecValidation))
  1410. _dnsServer.DnssecValidation = bool.Parse(strDnssecValidation);
  1411. string strResolverRetries = request.QueryString["resolverRetries"];
  1412. if (!string.IsNullOrEmpty(strResolverRetries))
  1413. _dnsServer.ResolverRetries = int.Parse(strResolverRetries);
  1414. string strResolverTimeout = request.QueryString["resolverTimeout"];
  1415. if (!string.IsNullOrEmpty(strResolverTimeout))
  1416. _dnsServer.ResolverTimeout = int.Parse(strResolverTimeout);
  1417. string strResolverMaxStackCount = request.QueryString["resolverMaxStackCount"];
  1418. if (!string.IsNullOrEmpty(strResolverMaxStackCount))
  1419. _dnsServer.ResolverMaxStackCount = int.Parse(strResolverMaxStackCount);
  1420. string strForwarderRetries = request.QueryString["forwarderRetries"];
  1421. if (!string.IsNullOrEmpty(strForwarderRetries))
  1422. _dnsServer.ForwarderRetries = int.Parse(strForwarderRetries);
  1423. string strForwarderTimeout = request.QueryString["forwarderTimeout"];
  1424. if (!string.IsNullOrEmpty(strForwarderTimeout))
  1425. _dnsServer.ForwarderTimeout = int.Parse(strForwarderTimeout);
  1426. string strForwarderConcurrency = request.QueryString["forwarderConcurrency"];
  1427. if (!string.IsNullOrEmpty(strForwarderConcurrency))
  1428. _dnsServer.ForwarderConcurrency = int.Parse(strForwarderConcurrency);
  1429. string strClientTimeout = request.QueryString["clientTimeout"];
  1430. if (!string.IsNullOrEmpty(strClientTimeout))
  1431. _dnsServer.ClientTimeout = int.Parse(strClientTimeout);
  1432. string strTcpSendTimeout = request.QueryString["tcpSendTimeout"];
  1433. if (!string.IsNullOrEmpty(strTcpSendTimeout))
  1434. _dnsServer.TcpSendTimeout = int.Parse(strTcpSendTimeout);
  1435. string strTcpReceiveTimeout = request.QueryString["tcpReceiveTimeout"];
  1436. if (!string.IsNullOrEmpty(strTcpReceiveTimeout))
  1437. _dnsServer.TcpReceiveTimeout = int.Parse(strTcpReceiveTimeout);
  1438. string strEnableLogging = request.QueryString["enableLogging"];
  1439. if (!string.IsNullOrEmpty(strEnableLogging))
  1440. _log.EnableLogging = bool.Parse(strEnableLogging);
  1441. string strLogQueries = request.QueryString["logQueries"];
  1442. if (!string.IsNullOrEmpty(strLogQueries))
  1443. {
  1444. if (bool.Parse(strLogQueries))
  1445. _dnsServer.QueryLogManager = _log;
  1446. else
  1447. _dnsServer.QueryLogManager = null;
  1448. }
  1449. string strUseLocalTime = request.QueryString["useLocalTime"];
  1450. if (!string.IsNullOrEmpty(strUseLocalTime))
  1451. _log.UseLocalTime = bool.Parse(strUseLocalTime);
  1452. string strLogFolder = request.QueryString["logFolder"];
  1453. if (!string.IsNullOrEmpty(strLogFolder))
  1454. _log.LogFolder = strLogFolder;
  1455. string strMaxLogFileDays = request.QueryString["maxLogFileDays"];
  1456. if (!string.IsNullOrEmpty(strMaxLogFileDays))
  1457. _log.MaxLogFileDays = int.Parse(strMaxLogFileDays);
  1458. string strMaxStatFileDays = request.QueryString["maxStatFileDays"];
  1459. if (!string.IsNullOrEmpty(strMaxStatFileDays))
  1460. _dnsServer.StatsManager.MaxStatFileDays = int.Parse(strMaxStatFileDays);
  1461. string strRecursion = request.QueryString["recursion"];
  1462. if (!string.IsNullOrEmpty(strRecursion))
  1463. _dnsServer.Recursion = Enum.Parse<DnsServerRecursion>(strRecursion, true);
  1464. string strRecursionDeniedNetworks = request.QueryString["recursionDeniedNetworks"];
  1465. if (!string.IsNullOrEmpty(strRecursionDeniedNetworks))
  1466. {
  1467. if (strRecursionDeniedNetworks == "false")
  1468. {
  1469. _dnsServer.RecursionDeniedNetworks = null;
  1470. }
  1471. else
  1472. {
  1473. string[] strNetworks = strRecursionDeniedNetworks.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  1474. NetworkAddress[] networks = new NetworkAddress[strNetworks.Length];
  1475. for (int i = 0; i < networks.Length; i++)
  1476. networks[i] = NetworkAddress.Parse(strNetworks[i]);
  1477. _dnsServer.RecursionDeniedNetworks = networks;
  1478. }
  1479. }
  1480. string strRecursionAllowedNetworks = request.QueryString["recursionAllowedNetworks"];
  1481. if (!string.IsNullOrEmpty(strRecursionAllowedNetworks))
  1482. {
  1483. if (strRecursionAllowedNetworks == "false")
  1484. {
  1485. _dnsServer.RecursionAllowedNetworks = null;
  1486. }
  1487. else
  1488. {
  1489. string[] strNetworks = strRecursionAllowedNetworks.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  1490. NetworkAddress[] networks = new NetworkAddress[strNetworks.Length];
  1491. for (int i = 0; i < networks.Length; i++)
  1492. networks[i] = NetworkAddress.Parse(strNetworks[i]);
  1493. _dnsServer.RecursionAllowedNetworks = networks;
  1494. }
  1495. }
  1496. string strRandomizeName = request.QueryString["randomizeName"];
  1497. if (!string.IsNullOrEmpty(strRandomizeName))
  1498. _dnsServer.RandomizeName = bool.Parse(strRandomizeName);
  1499. string strQnameMinimization = request.QueryString["qnameMinimization"];
  1500. if (!string.IsNullOrEmpty(strQnameMinimization))
  1501. _dnsServer.QnameMinimization = bool.Parse(strQnameMinimization);
  1502. string strNsRevalidation = request.QueryString["nsRevalidation"];
  1503. if (!string.IsNullOrEmpty(strNsRevalidation))
  1504. _dnsServer.NsRevalidation = bool.Parse(strNsRevalidation);
  1505. string strQpmLimitRequests = request.QueryString["qpmLimitRequests"];
  1506. if (!string.IsNullOrEmpty(strQpmLimitRequests))
  1507. _dnsServer.QpmLimitRequests = int.Parse(strQpmLimitRequests);
  1508. string strQpmLimitErrors = request.QueryString["qpmLimitErrors"];
  1509. if (!string.IsNullOrEmpty(strQpmLimitErrors))
  1510. _dnsServer.QpmLimitErrors = int.Parse(strQpmLimitErrors);
  1511. string strQpmLimitSampleMinutes = request.QueryString["qpmLimitSampleMinutes"];
  1512. if (!string.IsNullOrEmpty(strQpmLimitSampleMinutes))
  1513. _dnsServer.QpmLimitSampleMinutes = int.Parse(strQpmLimitSampleMinutes);
  1514. string strQpmLimitIPv4PrefixLength = request.QueryString["qpmLimitIPv4PrefixLength"];
  1515. if (!string.IsNullOrEmpty(strQpmLimitIPv4PrefixLength))
  1516. _dnsServer.QpmLimitIPv4PrefixLength = int.Parse(strQpmLimitIPv4PrefixLength);
  1517. string strQpmLimitIPv6PrefixLength = request.QueryString["qpmLimitIPv6PrefixLength"];
  1518. if (!string.IsNullOrEmpty(strQpmLimitIPv6PrefixLength))
  1519. _dnsServer.QpmLimitIPv6PrefixLength = int.Parse(strQpmLimitIPv6PrefixLength);
  1520. string strServeStale = request.QueryString["serveStale"];
  1521. if (!string.IsNullOrEmpty(strServeStale))
  1522. _dnsServer.ServeStale = bool.Parse(strServeStale);
  1523. string strServeStaleTtl = request.QueryString["serveStaleTtl"];
  1524. if (!string.IsNullOrEmpty(strServeStaleTtl))
  1525. _dnsServer.CacheZoneManager.ServeStaleTtl = uint.Parse(strServeStaleTtl);
  1526. string strCacheMinimumRecordTtl = request.QueryString["cacheMinimumRecordTtl"];
  1527. if (!string.IsNullOrEmpty(strCacheMinimumRecordTtl))
  1528. _dnsServer.CacheZoneManager.MinimumRecordTtl = uint.Parse(strCacheMinimumRecordTtl);
  1529. string strCacheMaximumRecordTtl = request.QueryString["cacheMaximumRecordTtl"];
  1530. if (!string.IsNullOrEmpty(strCacheMaximumRecordTtl))
  1531. _dnsServer.CacheZoneManager.MaximumRecordTtl = uint.Parse(strCacheMaximumRecordTtl);
  1532. string strCacheNegativeRecordTtl = request.QueryString["cacheNegativeRecordTtl"];
  1533. if (!string.IsNullOrEmpty(strCacheNegativeRecordTtl))
  1534. _dnsServer.CacheZoneManager.NegativeRecordTtl = uint.Parse(strCacheNegativeRecordTtl);
  1535. string strCacheFailureRecordTtl = request.QueryString["cacheFailureRecordTtl"];
  1536. if (!string.IsNullOrEmpty(strCacheFailureRecordTtl))
  1537. _dnsServer.CacheZoneManager.FailureRecordTtl = uint.Parse(strCacheFailureRecordTtl);
  1538. string strCachePrefetchEligibility = request.QueryString["cachePrefetchEligibility"];
  1539. if (!string.IsNullOrEmpty(strCachePrefetchEligibility))
  1540. _dnsServer.CachePrefetchEligibility = int.Parse(strCachePrefetchEligibility);
  1541. string strCachePrefetchTrigger = request.QueryString["cachePrefetchTrigger"];
  1542. if (!string.IsNullOrEmpty(strCachePrefetchTrigger))
  1543. _dnsServer.CachePrefetchTrigger = int.Parse(strCachePrefetchTrigger);
  1544. string strCachePrefetchSampleIntervalInMinutes = request.QueryString["cachePrefetchSampleIntervalInMinutes"];
  1545. if (!string.IsNullOrEmpty(strCachePrefetchSampleIntervalInMinutes))
  1546. _dnsServer.CachePrefetchSampleIntervalInMinutes = int.Parse(strCachePrefetchSampleIntervalInMinutes);
  1547. string strCachePrefetchSampleEligibilityHitsPerHour = request.QueryString["cachePrefetchSampleEligibilityHitsPerHour"];
  1548. if (!string.IsNullOrEmpty(strCachePrefetchSampleEligibilityHitsPerHour))
  1549. _dnsServer.CachePrefetchSampleEligibilityHitsPerHour = int.Parse(strCachePrefetchSampleEligibilityHitsPerHour);
  1550. string strProxyType = request.QueryString["proxyType"];
  1551. if (!string.IsNullOrEmpty(strProxyType))
  1552. {
  1553. NetProxyType proxyType = Enum.Parse<NetProxyType>(strProxyType, true);
  1554. if (proxyType == NetProxyType.None)
  1555. {
  1556. _dnsServer.Proxy = null;
  1557. }
  1558. else
  1559. {
  1560. NetworkCredential credential = null;
  1561. string strUsername = request.QueryString["proxyUsername"];
  1562. if (!string.IsNullOrEmpty(strUsername))
  1563. credential = new NetworkCredential(strUsername, request.QueryString["proxyPassword"]);
  1564. _dnsServer.Proxy = NetProxy.CreateProxy(proxyType, request.QueryString["proxyAddress"], int.Parse(request.QueryString["proxyPort"]), credential);
  1565. string strProxyBypass = request.QueryString["proxyBypass"];
  1566. if (!string.IsNullOrEmpty(strProxyBypass))
  1567. {
  1568. string[] strBypassList = strProxyBypass.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  1569. List<NetProxyBypassItem> bypassList = new List<NetProxyBypassItem>(strBypassList.Length);
  1570. for (int i = 0; i < strBypassList.Length; i++)
  1571. bypassList.Add(new NetProxyBypassItem(strBypassList[i]));
  1572. _dnsServer.Proxy.BypassList = bypassList;
  1573. }
  1574. }
  1575. }
  1576. DnsTransportProtocol forwarderProtocol = DnsTransportProtocol.Udp;
  1577. string strForwarderProtocol = request.QueryString["forwarderProtocol"];
  1578. if (!string.IsNullOrEmpty(strForwarderProtocol))
  1579. forwarderProtocol = Enum.Parse<DnsTransportProtocol>(strForwarderProtocol, true);
  1580. string strForwarders = request.QueryString["forwarders"];
  1581. if (!string.IsNullOrEmpty(strForwarders))
  1582. {
  1583. if (strForwarders == "false")
  1584. {
  1585. _dnsServer.Forwarders = null;
  1586. }
  1587. else
  1588. {
  1589. string[] strForwardersList = strForwarders.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  1590. NameServerAddress[] forwarders = new NameServerAddress[strForwardersList.Length];
  1591. for (int i = 0; i < strForwardersList.Length; i++)
  1592. {
  1593. NameServerAddress forwarder = new NameServerAddress(strForwardersList[i]);
  1594. if (forwarder.Protocol != forwarderProtocol)
  1595. forwarder = forwarder.ChangeProtocol(forwarderProtocol);
  1596. forwarders[i] = forwarder;
  1597. }
  1598. _dnsServer.Forwarders = forwarders;
  1599. }
  1600. }
  1601. string strEnableBlocking = request.QueryString["enableBlocking"];
  1602. if (!string.IsNullOrEmpty(strEnableBlocking))
  1603. {
  1604. _dnsServer.EnableBlocking = bool.Parse(strEnableBlocking);
  1605. if (_dnsServer.EnableBlocking)
  1606. {
  1607. if (_temporaryDisableBlockingTimer is not null)
  1608. _temporaryDisableBlockingTimer.Dispose();
  1609. }
  1610. }
  1611. string strAllowTxtBlockingReport = request.QueryString["allowTxtBlockingReport"];
  1612. if (!string.IsNullOrEmpty(strAllowTxtBlockingReport))
  1613. _dnsServer.AllowTxtBlockingReport = bool.Parse(strAllowTxtBlockingReport);
  1614. string strBlockingType = request.QueryString["blockingType"];
  1615. if (!string.IsNullOrEmpty(strBlockingType))
  1616. _dnsServer.BlockingType = Enum.Parse<DnsServerBlockingType>(strBlockingType, true);
  1617. string strCustomBlockingAddresses = request.QueryString["customBlockingAddresses"];
  1618. if (!string.IsNullOrEmpty(strCustomBlockingAddresses))
  1619. {
  1620. if (strCustomBlockingAddresses == "false")
  1621. {
  1622. _dnsServer.CustomBlockingARecords = null;
  1623. _dnsServer.CustomBlockingAAAARecords = null;
  1624. }
  1625. else
  1626. {
  1627. string[] strAddresses = strCustomBlockingAddresses.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  1628. List<DnsARecordData> dnsARecords = new List<DnsARecordData>();
  1629. List<DnsAAAARecordData> dnsAAAARecords = new List<DnsAAAARecordData>();
  1630. foreach (string strAddress in strAddresses)
  1631. {
  1632. if (IPAddress.TryParse(strAddress, out IPAddress customAddress))
  1633. {
  1634. switch (customAddress.AddressFamily)
  1635. {
  1636. case AddressFamily.InterNetwork:
  1637. dnsARecords.Add(new DnsARecordData(customAddress));
  1638. break;
  1639. case AddressFamily.InterNetworkV6:
  1640. dnsAAAARecords.Add(new DnsAAAARecordData(customAddress));
  1641. break;
  1642. }
  1643. }
  1644. }
  1645. _dnsServer.CustomBlockingARecords = dnsARecords;
  1646. _dnsServer.CustomBlockingAAAARecords = dnsAAAARecords;
  1647. }
  1648. }
  1649. string strBlockListUrls = request.QueryString["blockListUrls"];
  1650. if (!string.IsNullOrEmpty(strBlockListUrls))
  1651. {
  1652. if (strBlockListUrls == "false")
  1653. {
  1654. StopBlockListUpdateTimer();
  1655. _dnsServer.BlockListZoneManager.AllowListUrls.Clear();
  1656. _dnsServer.BlockListZoneManager.BlockListUrls.Clear();
  1657. _dnsServer.BlockListZoneManager.Flush();
  1658. }
  1659. else
  1660. {
  1661. bool updated = false;
  1662. string[] strBlockListUrlList = strBlockListUrls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  1663. if (oldWebServiceHttpPort != _webServiceHttpPort)
  1664. {
  1665. for (int i = 0; i < strBlockListUrlList.Length; i++)
  1666. {
  1667. if (strBlockListUrlList[i].Contains("http://localhost:" + oldWebServiceHttpPort + "/blocklist.txt"))
  1668. {
  1669. strBlockListUrlList[i] = "http://localhost:" + _webServiceHttpPort + "/blocklist.txt";
  1670. updated = true;
  1671. break;
  1672. }
  1673. }
  1674. }
  1675. if (!updated)
  1676. {
  1677. if (strBlockListUrlList.Length != (_dnsServer.BlockListZoneManager.AllowListUrls.Count + _dnsServer.BlockListZoneManager.BlockListUrls.Count))
  1678. {
  1679. updated = true;
  1680. }
  1681. else
  1682. {
  1683. foreach (string strBlockListUrl in strBlockListUrlList)
  1684. {
  1685. if (strBlockListUrl.StartsWith("!"))
  1686. {
  1687. string strAllowListUrl = strBlockListUrl.Substring(1);
  1688. if (!_dnsServer.BlockListZoneManager.AllowListUrls.Contains(new Uri(strAllowListUrl)))
  1689. {
  1690. updated = true;
  1691. break;
  1692. }
  1693. }
  1694. else
  1695. {
  1696. if (!_dnsServer.BlockListZoneManager.BlockListUrls.Contains(new Uri(strBlockListUrl)))
  1697. {
  1698. updated = true;
  1699. break;
  1700. }
  1701. }
  1702. }
  1703. }
  1704. }
  1705. if (updated)
  1706. {
  1707. _dnsServer.BlockListZoneManager.AllowListUrls.Clear();
  1708. _dnsServer.BlockListZoneManager.BlockListUrls.Clear();
  1709. foreach (string strBlockListUrl in strBlockListUrlList)
  1710. {
  1711. if (strBlockListUrl.StartsWith("!"))
  1712. {
  1713. Uri allowListUrl = new Uri(strBlockListUrl.Substring(1));
  1714. if (!_dnsServer.BlockListZoneManager.AllowListUrls.Contains(allowListUrl))
  1715. _dnsServer.BlockListZoneManager.AllowListUrls.Add(allowListUrl);
  1716. }
  1717. else
  1718. {
  1719. Uri blockListUrl = new Uri(strBlockListUrl);
  1720. if (!_dnsServer.BlockListZoneManager.BlockListUrls.Contains(blockListUrl))
  1721. _dnsServer.BlockListZoneManager.BlockListUrls.Add(blockListUrl);
  1722. }
  1723. }
  1724. ForceUpdateBlockLists();
  1725. }
  1726. }
  1727. }
  1728. string strBlockListUpdateIntervalHours = request.QueryString["blockListUpdateIntervalHours"];
  1729. if (!string.IsNullOrEmpty(strBlockListUpdateIntervalHours))
  1730. {
  1731. int blockListUpdateIntervalHours = int.Parse(strBlockListUpdateIntervalHours);
  1732. if ((blockListUpdateIntervalHours < 1) || (blockListUpdateIntervalHours > 168))
  1733. throw new DnsWebServiceException("Parameter `blockListUpdateIntervalHours` must be between 1 hour and 168 hours (7 days).");
  1734. _blockListUpdateIntervalHours = blockListUpdateIntervalHours;
  1735. }
  1736. if ((_webServiceTlsCertificatePath == null) && (_dnsTlsCertificatePath == null))
  1737. StopTlsCertificateUpdateTimer();
  1738. SelfSignedCertCheck(true);
  1739. if (_webServiceEnableTls && string.IsNullOrEmpty(_webServiceTlsCertificatePath) && !_webServiceUseSelfSignedTlsCertificate)
  1740. {
  1741. //disable TLS
  1742. _webServiceEnableTls = false;
  1743. restartWebService = true;
  1744. }
  1745. SaveConfigFile();
  1746. _log.Save();
  1747. _log.Write(GetRequestRemoteEndPoint(request), "[" + GetSession(request).Username + "] DNS Settings were updated {dnsServerDomain: " + _dnsServer.ServerDomain + "; dnsServerLocalEndPoints: " + strDnsServerLocalEndPoints + "; webServiceLocalAddresses: " + strWebServiceLocalAddresses + "; webServiceHttpPort: " + _webServiceHttpPort + "; webServiceEnableTls: " + strWebServiceEnableTls + "; webServiceHttpToTlsRedirect: " + strWebServiceHttpToTlsRedirect + "; webServiceTlsPort: " + strWebServiceTlsPort + "; webServiceUseSelfSignedTlsCertificate: " + _webServiceUseSelfSignedTlsCertificate + "; webServiceTlsCertificatePath: " + strWebServiceTlsCertificatePath + "; enableDnsOverHttp: " + _dnsServer.EnableDnsOverHttp + "; enableDnsOverTls: " + _dnsServer.EnableDnsOverTls + "; enableDnsOverHttps: " + _dnsServer.EnableDnsOverHttps + "; dnsTlsCertificatePath: " + _dnsTlsCertificatePath + "; defaultRecordTtl: " + _zonesApi.DefaultRecordTtl + "; preferIPv6: " + _dnsServer.PreferIPv6 + "; enableLogging: " + strEnableLogging + "; logQueries: " + (_dnsServer.QueryLogManager != null) + "; useLocalTime: " + strUseLocalTime + "; logFolder: " + strLogFolder + "; maxLogFileDays: " + strMaxLogFileDays + "; recursion: " + _dnsServer.Recursion.ToString() + "; randomizeName: " + strRandomizeName + "; qnameMinimization: " + strQnameMinimization + "; serveStale: " + strServeStale + "; serveStaleTtl: " + strServeStaleTtl + "; cachePrefetchEligibility: " + strCachePrefetchEligibility + "; cachePrefetchTrigger: " + strCachePrefetchTrigger + "; cachePrefetchSampleIntervalInMinutes: " + strCachePrefetchSampleIntervalInMinutes + "; cachePrefetchSampleEligibilityHitsPerHour: " + strCachePrefetchSampleEligibilityHitsPerHour + "; proxyType: " + strProxyType + "; forwarders: " + strForwarders + "; forwarderProtocol: " + strForwarderProtocol + "; enableBlocking: " + _dnsServer.EnableBlocking + "; allowTxtBlockingReport: " + _dnsServer.AllowTxtBlockingReport + "; blockingType: " + _dnsServer.BlockingType.ToString() + "; blockListUrl: " + strBlockListUrls + "; blockListUpdateIntervalHours: " + strBlockListUpdateIntervalHours + ";}");
  1748. GetDnsSettings(jsonWriter);
  1749. RestartService(restartDnsService, restartWebService);
  1750. }
  1751. private void SelfSignedCertCheck(bool throwException)
  1752. {
  1753. string selfSignedCertificateFilePath = Path.Combine(_configFolder, "cert.pfx");
  1754. if (_webServiceUseSelfSignedTlsCertificate)
  1755. {
  1756. if (!File.Exists(selfSignedCertificateFilePath))
  1757. {
  1758. RSA rsa = RSA.Create(2048);
  1759. CertificateRequest req = new CertificateRequest("cn=" + _dnsServer.ServerDomain, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
  1760. X509Certificate2 cert = req.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(5));
  1761. File.WriteAllBytes(selfSignedCertificateFilePath, cert.Export(X509ContentType.Pkcs12, null as string));
  1762. }
  1763. if (_webServiceEnableTls && string.IsNullOrEmpty(_webServiceTlsCertificatePath))
  1764. {
  1765. try
  1766. {
  1767. LoadWebServiceTlsCertificate(selfSignedCertificateFilePath, null);
  1768. }
  1769. catch (Exception ex)
  1770. {
  1771. _log.Write("DNS Server encountered an error while loading self signed Web Service TLS certificate: " + selfSignedCertificateFilePath + "\r\n" + ex.ToString());
  1772. if (throwException)
  1773. throw;
  1774. }
  1775. }
  1776. }
  1777. else
  1778. {
  1779. File.Delete(selfSignedCertificateFilePath);
  1780. }
  1781. }
  1782. private void RestartService(bool restartDnsService, bool restartWebService)
  1783. {
  1784. if (restartDnsService)
  1785. {
  1786. _ = Task.Run(delegate ()
  1787. {
  1788. _log.Write("Attempting to restart DNS service.");
  1789. try
  1790. {
  1791. _dnsServer.Stop();
  1792. _dnsServer.Start();
  1793. _log.Write("DNS service was restarted successfully.");
  1794. }
  1795. catch (Exception ex)
  1796. {
  1797. _log.Write("Failed to restart DNS service.");
  1798. _log.Write(ex);
  1799. }
  1800. });
  1801. }
  1802. if (restartWebService)
  1803. {
  1804. _ = Task.Run(async delegate ()
  1805. {
  1806. await Task.Delay(2000); //wait for this HTTP response to be delivered before stopping web server
  1807. _log.Write("Attempting to restart web service.");
  1808. try
  1809. {
  1810. StopDnsWebService();
  1811. StartDnsWebService();
  1812. _log.Write("Web service was restarted successfully.");
  1813. }
  1814. catch (Exception ex)
  1815. {
  1816. _log.Write("Failed to restart web service.");
  1817. _log.Write(ex);
  1818. }
  1819. });
  1820. }
  1821. }
  1822. private async Task BackupSettingsAsync(HttpListenerRequest request, HttpListenerResponse response)
  1823. {
  1824. bool blockLists = false;
  1825. bool logs = false;
  1826. bool scopes = false;
  1827. bool apps = false;
  1828. bool stats = false;
  1829. bool zones = false;
  1830. bool allowedZones = false;
  1831. bool blockedZones = false;
  1832. bool dnsSettings = false;
  1833. bool logSettings = false;
  1834. string strBlockLists = request.QueryString["blockLists"];
  1835. if (!string.IsNullOrEmpty(strBlockLists))
  1836. blockLists = bool.Parse(strBlockLists);
  1837. string strLogs = request.QueryString["logs"];
  1838. if (!string.IsNullOrEmpty(strLogs))
  1839. logs = bool.Parse(strLogs);
  1840. string strScopes = request.QueryString["scopes"];
  1841. if (!string.IsNullOrEmpty(strScopes))
  1842. scopes = bool.Parse(strScopes);
  1843. string strApps = request.QueryString["apps"];
  1844. if (!string.IsNullOrEmpty(strApps))
  1845. apps = bool.Parse(strApps);
  1846. string strStats = request.QueryString["stats"];
  1847. if (!string.IsNullOrEmpty(strStats))
  1848. stats = bool.Parse(strStats);
  1849. string strZones = request.QueryString["zones"];
  1850. if (!string.IsNullOrEmpty(strZones))
  1851. zones = bool.Parse(strZones);
  1852. string strAllowedZones = request.QueryString["allowedZones"];
  1853. if (!string.IsNullOrEmpty(strAllowedZones))
  1854. allowedZones = bool.Parse(strAllowedZones);
  1855. string strBlockedZones = request.QueryString["blockedZones"];
  1856. if (!string.IsNullOrEmpty(strBlockedZones))
  1857. blockedZones = bool.Parse(strBlockedZones);
  1858. string strDnsSettings = request.QueryString["dnsSettings"];
  1859. if (!string.IsNullOrEmpty(strDnsSettings))
  1860. dnsSettings = bool.Parse(strDnsSettings);
  1861. string strLogSettings = request.QueryString["logSettings"];
  1862. if (!string.IsNullOrEmpty(strLogSettings))
  1863. logSettings = bool.Parse(strLogSettings);
  1864. string tmpFile = Path.GetTempFileName();
  1865. try
  1866. {
  1867. using (FileStream backupZipStream = new FileStream(tmpFile, FileMode.Create, FileAccess.ReadWrite))
  1868. {
  1869. //create backup zip
  1870. using (ZipArchive backupZip = new ZipArchive(backupZipStream, ZipArchiveMode.Create, true, Encoding.UTF8))
  1871. {
  1872. if (blockLists)
  1873. {
  1874. string[] blockListFiles = Directory.GetFiles(Path.Combine(_configFolder, "blocklists"), "*", SearchOption.TopDirectoryOnly);
  1875. foreach (string blockListFile in blockListFiles)
  1876. {
  1877. string entryName = "blocklists/" + Path.GetFileName(blockListFile);
  1878. backupZip.CreateEntryFromFile(blockListFile, entryName);
  1879. }
  1880. }
  1881. if (logs)
  1882. {
  1883. string[] logFiles = Directory.GetFiles(_log.LogFolderAbsolutePath, "*.log", SearchOption.TopDirectoryOnly);
  1884. foreach (string logFile in logFiles)
  1885. {
  1886. string entryName = "logs/" + Path.GetFileName(logFile);
  1887. if (logFile.Equals(_log.CurrentLogFile, StringComparison.OrdinalIgnoreCase))
  1888. {
  1889. using (FileStream fS = new FileStream(logFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
  1890. {
  1891. ZipArchiveEntry entry = backupZip.CreateEntry(entryName);
  1892. using (Stream s = entry.Open())
  1893. {
  1894. await fS.CopyToAsync(s);
  1895. }
  1896. }
  1897. }
  1898. else
  1899. {
  1900. backupZip.CreateEntryFromFile(logFile, entryName);
  1901. }
  1902. }
  1903. }
  1904. if (scopes)
  1905. {
  1906. string[] scopeFiles = Directory.GetFiles(Path.Combine(_configFolder, "scopes"), "*.scope", SearchOption.TopDirectoryOnly);
  1907. foreach (string scopeFile in scopeFiles)
  1908. {
  1909. string entryName = "scopes/" + Path.GetFileName(scopeFile);
  1910. backupZip.CreateEntryFromFile(scopeFile, entryName);
  1911. }
  1912. }
  1913. if (apps)
  1914. {
  1915. string[] appFiles = Directory.GetFiles(Path.Combine(_configFolder, "apps"), "*", SearchOption.AllDirectories);
  1916. foreach (string appFile in appFiles)
  1917. {
  1918. string entryName = appFile.Substring(_configFolder.Length);
  1919. if (Path.DirectorySeparatorChar != '/')
  1920. entryName = entryName.Replace(Path.DirectorySeparatorChar, '/');
  1921. entryName = entryName.TrimStart('/');
  1922. backupZip.CreateEntryFromFile(appFile, entryName);
  1923. }
  1924. }
  1925. if (stats)
  1926. {
  1927. string[] hourlyStatsFiles = Directory.GetFiles(Path.Combine(_configFolder, "stats"), "*.stat", SearchOption.TopDirectoryOnly);
  1928. foreach (string hourlyStatsFile in hourlyStatsFiles)
  1929. {
  1930. string entryName = "stats/" + Path.GetFileName(hourlyStatsFile);
  1931. backupZip.CreateEntryFromFile(hourlyStatsFile, entryName);
  1932. }
  1933. string[] dailyStatsFiles = Directory.GetFiles(Path.Combine(_configFolder, "stats"), "*.dstat", SearchOption.TopDirectoryOnly);
  1934. foreach (string dailyStatsFile in dailyStatsFiles)
  1935. {
  1936. string entryName = "stats/" + Path.GetFileName(dailyStatsFile);
  1937. backupZip.CreateEntryFromFile(dailyStatsFile, entryName);
  1938. }
  1939. }
  1940. if (zones)
  1941. {
  1942. string[] zoneFiles = Directory.GetFiles(Path.Combine(_configFolder, "zones"), "*.zone", SearchOption.TopDirectoryOnly);
  1943. foreach (string zoneFile in zoneFiles)
  1944. {
  1945. string entryName = "zones/" + Path.GetFileName(zoneFile);
  1946. backupZip.CreateEntryFromFile(zoneFile, entryName);
  1947. }
  1948. }
  1949. if (allowedZones)
  1950. {
  1951. string allowedZonesFile = Path.Combine(_configFolder, "allowed.config");
  1952. if (File.Exists(allowedZonesFile))
  1953. backupZip.CreateEntryFromFile(allowedZonesFile, "allowed.config");
  1954. }
  1955. if (blockedZones)
  1956. {
  1957. string blockedZonesFile = Path.Combine(_configFolder, "blocked.config");
  1958. if (File.Exists(blockedZonesFile))
  1959. backupZip.CreateEntryFromFile(blockedZonesFile, "blocked.config");
  1960. }
  1961. if (dnsSettings)
  1962. {
  1963. string dnsSettingsFile = Path.Combine(_configFolder, "dns.config");
  1964. if (File.Exists(dnsSettingsFile))
  1965. backupZip.CreateEntryFromFile(dnsSettingsFile, "dns.config");
  1966. }
  1967. if (logSettings)
  1968. {
  1969. string logSettingsFile = Path.Combine(_configFolder, "log.config");
  1970. if (File.Exists(logSettingsFile))
  1971. backupZip.CreateEntryFromFile(logSettingsFile, "log.config");
  1972. }
  1973. }
  1974. //send zip file
  1975. backupZipStream.Position = 0;
  1976. response.ContentType = "application/zip";
  1977. response.ContentLength64 = backupZipStream.Length;
  1978. response.AddHeader("Content-Disposition", "attachment;filename=DnsServerBackup.zip");
  1979. using (Stream output = response.OutputStream)
  1980. {
  1981. await backupZipStream.CopyToAsync(output);
  1982. }
  1983. }
  1984. }
  1985. finally
  1986. {
  1987. try
  1988. {
  1989. File.Delete(tmpFile);
  1990. }
  1991. catch (Exception ex)
  1992. {
  1993. _log.Write(ex);
  1994. }
  1995. }
  1996. _log.Write(GetRequestRemoteEndPoint(request), "[" + GetSession(request).Username + "] Settings backup zip file was exported.");
  1997. }
  1998. private async Task RestoreSettingsAsync(HttpListenerRequest request, JsonTextWriter jsonWriter)
  1999. {
  2000. bool blockLists = false;
  2001. bool logs = false;
  2002. bool scopes = false;
  2003. bool apps = false;
  2004. bool stats = false;
  2005. bool zones = false;
  2006. bool allowedZones = false;
  2007. bool blockedZones = false;
  2008. bool dnsSettings = false;
  2009. bool logSettings = false;
  2010. bool deleteExistingFiles = false;
  2011. string strBlockLists = request.QueryString["blockLists"];
  2012. if (!string.IsNullOrEmpty(strBlockLists))
  2013. blockLists = bool.Parse(strBlockLists);
  2014. string strLogs = request.QueryString["logs"];
  2015. if (!string.IsNullOrEmpty(strLogs))
  2016. logs = bool.Parse(strLogs);
  2017. string strScopes = request.QueryString["scopes"];
  2018. if (!string.IsNullOrEmpty(strScopes))
  2019. scopes = bool.Parse(strScopes);
  2020. string strApps = request.QueryString["apps"];
  2021. if (!string.IsNullOrEmpty(strApps))
  2022. apps = bool.Parse(strApps);
  2023. string strStats = request.QueryString["stats"];
  2024. if (!string.IsNullOrEmpty(strStats))
  2025. stats = bool.Parse(strStats);
  2026. string strZones = request.QueryString["zones"];
  2027. if (!string.IsNullOrEmpty(strZones))
  2028. zones = bool.Parse(strZones);
  2029. string strAllowedZones = request.QueryString["allowedZones"];
  2030. if (!string.IsNullOrEmpty(strAllowedZones))
  2031. allowedZones = bool.Parse(strAllowedZones);
  2032. string strBlockedZones = request.QueryString["blockedZones"];
  2033. if (!string.IsNullOrEmpty(strBlockedZones))
  2034. blockedZones = bool.Parse(strBlockedZones);
  2035. string strDnsSettings = request.QueryString["dnsSettings"];
  2036. if (!string.IsNullOrEmpty(strDnsSettings))
  2037. dnsSettings = bool.Parse(strDnsSettings);
  2038. string strLogSettings = request.QueryString["logSettings"];
  2039. if (!string.IsNullOrEmpty(strLogSettings))
  2040. logSettings = bool.Parse(strLogSettings);
  2041. string strDeleteExistingFiles = request.QueryString["deleteExistingFiles"];
  2042. if (!string.IsNullOrEmpty(strDeleteExistingFiles))
  2043. deleteExistingFiles = bool.Parse(strDeleteExistingFiles);
  2044. #region skip to content
  2045. int crlfCount = 0;
  2046. int byteRead;
  2047. while (crlfCount != 4)
  2048. {
  2049. byteRead = request.InputStream.ReadByte();
  2050. switch (byteRead)
  2051. {
  2052. case -1:
  2053. throw new EndOfStreamException();
  2054. case 13: //CR
  2055. case 10: //LF
  2056. crlfCount++;
  2057. break;
  2058. default:
  2059. crlfCount = 0;
  2060. break;
  2061. }
  2062. }
  2063. #endregion
  2064. //write to temp file
  2065. string tmpFile = Path.GetTempFileName();
  2066. try
  2067. {
  2068. using (FileStream fS = new FileStream(tmpFile, FileMode.Create, FileAccess.ReadWrite))
  2069. {
  2070. await request.InputStream.CopyToAsync(fS);
  2071. fS.Position = 0;
  2072. using (ZipArchive backupZip = new ZipArchive(fS, ZipArchiveMode.Read, false, Encoding.UTF8))
  2073. {
  2074. if (logSettings || logs)
  2075. {
  2076. //stop logging
  2077. _log.StopLogging();
  2078. }
  2079. try
  2080. {
  2081. if (logSettings)
  2082. {
  2083. ZipArchiveEntry entry = backupZip.GetEntry("log.config");
  2084. if (entry != null)
  2085. entry.ExtractToFile(Path.Combine(_configFolder, entry.Name), true);
  2086. //reload config
  2087. _log.LoadConfig();
  2088. }
  2089. if (logs)
  2090. {
  2091. if (deleteExistingFiles)
  2092. {
  2093. //delete existing log files
  2094. string[] logFiles = Directory.GetFiles(_log.LogFolderAbsolutePath, "*.log", SearchOption.TopDirectoryOnly);
  2095. foreach (string logFile in logFiles)
  2096. {
  2097. File.Delete(logFile);
  2098. }
  2099. }
  2100. //extract log files from backup
  2101. foreach (ZipArchiveEntry entry in backupZip.Entries)
  2102. {
  2103. if (entry.FullName.StartsWith("logs/"))
  2104. entry.ExtractToFile(Path.Combine(_log.LogFolderAbsolutePath, entry.Name), true);
  2105. }
  2106. }
  2107. }
  2108. finally
  2109. {
  2110. if (logSettings || logs)
  2111. {
  2112. //start logging
  2113. if (_log.EnableLogging)
  2114. _log.StartLogging();
  2115. }
  2116. }
  2117. if (blockLists)
  2118. {
  2119. if (deleteExistingFiles)
  2120. {
  2121. //delete existing block list files
  2122. string[] blockListFiles = Directory.GetFiles(Path.Combine(_configFolder, "blocklists"), "*", SearchOption.TopDirectoryOnly);
  2123. foreach (string blockListFile in blockListFiles)
  2124. {
  2125. File.Delete(blockListFile);
  2126. }
  2127. }
  2128. //extract block list files from backup
  2129. foreach (ZipArchiveEntry entry in backupZip.Entries)
  2130. {
  2131. if (entry.FullName.StartsWith("blocklists/"))
  2132. entry.ExtractToFile(Path.Combine(_configFolder, "blocklists", entry.Name), true);
  2133. }
  2134. }
  2135. if (scopes)
  2136. {
  2137. //stop dhcp server
  2138. _dhcpServer.Stop();
  2139. try
  2140. {
  2141. if (deleteExistingFiles)
  2142. {
  2143. //delete existing scope files
  2144. string[] scopeFiles = Directory.GetFiles(Path.Combine(_configFolder, "scopes"), "*.scope", SearchOption.TopDirectoryOnly);
  2145. foreach (string scopeFile in scopeFiles)
  2146. {
  2147. File.Delete(scopeFile);
  2148. }
  2149. }
  2150. //extract scope files from backup
  2151. foreach (ZipArchiveEntry entry in backupZip.Entries)
  2152. {
  2153. if (entry.FullName.StartsWith("scopes/"))
  2154. entry.ExtractToFile(Path.Combine(_configFolder, "scopes", entry.Name), true);
  2155. }
  2156. }
  2157. finally
  2158. {
  2159. //start dhcp server
  2160. _dhcpServer.Start();
  2161. }
  2162. }
  2163. if (apps)
  2164. {
  2165. //unload apps
  2166. _dnsServer.DnsApplicationManager.UnloadAllApplications();
  2167. if (deleteExistingFiles)
  2168. {
  2169. //delete existing apps
  2170. string appFolder = Path.Combine(_configFolder, "apps");
  2171. if (Directory.Exists(appFolder))
  2172. Directory.Delete(appFolder, true);
  2173. //create apps folder
  2174. Directory.CreateDirectory(appFolder);
  2175. }
  2176. //extract apps files from backup
  2177. foreach (ZipArchiveEntry entry in backupZip.Entries)
  2178. {
  2179. if (entry.FullName.StartsWith("apps/"))
  2180. {
  2181. string entryPath = entry.FullName;
  2182. if (Path.DirectorySeparatorChar != '/')
  2183. entryPath = entryPath.Replace('/', '\\');
  2184. string filePath = Path.Combine(_configFolder, entryPath);
  2185. Directory.CreateDirectory(Path.GetDirectoryName(filePath));
  2186. entry.ExtractToFile(filePath, true);
  2187. }
  2188. }
  2189. //reload apps
  2190. _dnsServer.DnsApplicationManager.LoadAllApplications();
  2191. }
  2192. if (stats)
  2193. {
  2194. if (deleteExistingFiles)
  2195. {
  2196. //delete existing stats files
  2197. string[] hourlyStatsFiles = Directory.GetFiles(Path.Combine(_configFolder, "stats"), "*.stat", SearchOption.TopDirectoryOnly);
  2198. foreach (string hourlyStatsFile in hourlyStatsFiles)
  2199. {
  2200. File.Delete(hourlyStatsFile);
  2201. }
  2202. string[] dailyStatsFiles = Directory.GetFiles(Path.Combine(_configFolder, "stats"), "*.dstat", SearchOption.TopDirectoryOnly);
  2203. foreach (string dailyStatsFile in dailyStatsFiles)
  2204. {
  2205. File.Delete(dailyStatsFile);
  2206. }
  2207. }
  2208. //extract stats files from backup
  2209. foreach (ZipArchiveEntry entry in backupZip.Entries)
  2210. {
  2211. if (entry.FullName.StartsWith("stats/"))
  2212. entry.ExtractToFile(Path.Combine(_configFolder, "stats", entry.Name), true);
  2213. }
  2214. //reload stats
  2215. _dnsServer.StatsManager.ReloadStats();
  2216. }
  2217. if (zones)
  2218. {
  2219. if (deleteExistingFiles)
  2220. {
  2221. //delete existing zone files
  2222. string[] zoneFiles = Directory.GetFiles(Path.Combine(_configFolder, "zones"), "*.zone", SearchOption.TopDirectoryOnly);
  2223. foreach (string zoneFile in zoneFiles)
  2224. {
  2225. File.Delete(zoneFile);
  2226. }
  2227. }
  2228. //extract zone files from backup
  2229. foreach (ZipArchiveEntry entry in backupZip.Entries)
  2230. {
  2231. if (entry.FullName.StartsWith("zones/"))
  2232. entry.ExtractToFile(Path.Combine(_configFolder, "zones", entry.Name), true);
  2233. }
  2234. //reload zones
  2235. _dnsServer.AuthZoneManager.LoadAllZoneFiles();
  2236. }
  2237. if (allowedZones)
  2238. {
  2239. ZipArchiveEntry entry = backupZip.GetEntry("allowed.config");
  2240. if (entry == null)
  2241. {
  2242. string fileName = Path.Combine(_configFolder, "allowed.config");
  2243. if (File.Exists(fileName))
  2244. File.Delete(fileName);
  2245. }
  2246. else
  2247. {
  2248. entry.ExtractToFile(Path.Combine(_configFolder, entry.Name), true);
  2249. }
  2250. //reload
  2251. _dnsServer.AllowedZoneManager.LoadAllowedZoneFile();
  2252. }
  2253. if (blockedZones)
  2254. {
  2255. ZipArchiveEntry entry = backupZip.GetEntry("blocked.config");
  2256. if (entry == null)
  2257. {
  2258. string fileName = Path.Combine(_configFolder, "allowed.config");
  2259. if (File.Exists(fileName))
  2260. File.Delete(fileName);
  2261. }
  2262. else
  2263. {
  2264. entry.ExtractToFile(Path.Combine(_configFolder, entry.Name), true);
  2265. }
  2266. //reload
  2267. _dnsServer.BlockedZoneManager.LoadBlockedZoneFile();
  2268. }
  2269. if (dnsSettings)
  2270. {
  2271. ZipArchiveEntry entry = backupZip.GetEntry("dns.config");
  2272. if (entry != null)
  2273. entry.ExtractToFile(Path.Combine(_configFolder, entry.Name), true);
  2274. //reload settings and block list zone
  2275. LoadConfigFile();
  2276. _dnsServer.BlockListZoneManager.LoadBlockLists();
  2277. }
  2278. _log.Write(GetRequestRemoteEndPoint(request), "[" + GetSession(request).Username + "] Settings backup zip file was restored.");
  2279. }
  2280. }
  2281. }
  2282. finally
  2283. {
  2284. try
  2285. {
  2286. File.Delete(tmpFile);
  2287. }
  2288. catch (Exception ex)
  2289. {
  2290. _log.Write(ex);
  2291. }
  2292. }
  2293. if (dnsSettings)
  2294. RestartService(true, true);
  2295. GetDnsSettings(jsonWriter);
  2296. }
  2297. private void ForceUpdateBlockLists(HttpListenerRequest request)
  2298. {
  2299. if (ForceUpdateBlockLists())
  2300. _log.Write(GetRequestRemoteEndPoint(request), "[" + GetSession(request).Username + "] Block list update was triggered.");
  2301. }
  2302. private void TemporaryDisableBlocking(HttpListenerRequest request, JsonTextWriter jsonWriter)
  2303. {
  2304. string strMinutes = request.QueryString["minutes"];
  2305. if (string.IsNullOrEmpty(strMinutes))
  2306. throw new DnsWebServiceException("Parameter 'minutes' missing.");
  2307. int minutes = int.Parse(strMinutes);
  2308. Timer temporaryDisableBlockingTimer = _temporaryDisableBlockingTimer;
  2309. if (temporaryDisableBlockingTimer is not null)
  2310. temporaryDisableBlockingTimer.Dispose();
  2311. Timer newTemporaryDisableBlockingTimer = new Timer(delegate (object state)
  2312. {
  2313. try
  2314. {
  2315. _dnsServer.EnableBlocking = true;
  2316. _log.Write(GetRequestRemoteEndPoint(request), "[" + GetSession(request).Username + "] Blocking was enabled after " + minutes + " minute(s) being temporarily disabled.");
  2317. }
  2318. catch (Exception ex)
  2319. {
  2320. _log.Write(ex);
  2321. }
  2322. });
  2323. Timer originalTimer = Interlocked.CompareExchange(ref _temporaryDisableBlockingTimer, newTemporaryDisableBlockingTimer, temporaryDisableBlockingTimer);
  2324. if (ReferenceEquals(originalTimer, temporaryDisableBlockingTimer))
  2325. {
  2326. newTemporaryDisableBlockingTimer.Change(minutes * 60 * 1000, Timeout.Infinite);
  2327. _dnsServer.EnableBlocking = false;
  2328. _temporaryDisableBlockingTill = DateTime.UtcNow.AddMinutes(minutes);
  2329. _log.Write(GetRequestRemoteEndPoint(request), "[" + GetSession(request).Username + "] Blocking was temporarily disabled for " + minutes + " minute(s).");
  2330. }
  2331. else
  2332. {
  2333. newTemporaryDisableBlockingTimer.Dispose();
  2334. }
  2335. jsonWriter.WritePropertyName("temporaryDisableBlockingTill");
  2336. jsonWriter.WriteValue(_temporaryDisableBlockingTill);
  2337. }
  2338. #endregion
  2339. #region dns client api
  2340. private async Task ResolveQuery(HttpListenerRequest request, JsonTextWriter jsonWriter)
  2341. {
  2342. string server = request.QueryString["server"];
  2343. if (string.IsNullOrEmpty(server))
  2344. throw new DnsWebServiceException("Parameter 'server' missing.");
  2345. string domain = request.QueryString["domain"];
  2346. if (string.IsNullOrEmpty(domain))
  2347. throw new DnsWebServiceException("Parameter 'domain' missing.");
  2348. domain = domain.Trim(new char[] { '\t', ' ', '.' });
  2349. string strType = request.QueryString["type"];
  2350. if (string.IsNullOrEmpty(strType))
  2351. throw new DnsWebServiceException("Parameter 'type' missing.");
  2352. DnsResourceRecordType type = (DnsResourceRecordType)Enum.Parse(typeof(DnsResourceRecordType), strType);
  2353. string strProtocol = request.QueryString["protocol"];
  2354. if (string.IsNullOrEmpty(strProtocol))
  2355. strProtocol = "Udp";
  2356. bool dnssecValidation = false;
  2357. string strDnssecValidation = request.QueryString["dnssec"];
  2358. if (!string.IsNullOrEmpty(strDnssecValidation))
  2359. dnssecValidation = bool.Parse(strDnssecValidation);
  2360. bool importResponse = false;
  2361. string strImport = request.QueryString["import"];
  2362. if (!string.IsNullOrEmpty(strImport))
  2363. importResponse = bool.Parse(strImport);
  2364. NetProxy proxy = _dnsServer.Proxy;
  2365. bool preferIPv6 = _dnsServer.PreferIPv6;
  2366. ushort udpPayloadSize = _dnsServer.UdpPayloadSize;
  2367. bool randomizeName = false;
  2368. bool qnameMinimization = _dnsServer.QnameMinimization;
  2369. DnsTransportProtocol protocol = Enum.Parse<DnsTransportProtocol>(strProtocol, true);
  2370. const int RETRIES = 1;
  2371. const int TIMEOUT = 10000;
  2372. DnsDatagram dnsResponse;
  2373. string dnssecErrorMessage = null;
  2374. if (server.Equals("recursive-resolver", StringComparison.OrdinalIgnoreCase))
  2375. {
  2376. if (type == DnsResourceRecordType.AXFR)
  2377. throw new DnsServerException("Cannot do zone transfer (AXFR) for 'recursive-resolver'.");
  2378. DnsQuestionRecord question;
  2379. if ((type == DnsResourceRecordType.PTR) && IPAddress.TryParse(domain, out IPAddress address))
  2380. question = new DnsQuestionRecord(address, DnsClass.IN);
  2381. else
  2382. question = new DnsQuestionRecord(domain, type, DnsClass.IN);
  2383. DnsCache dnsCache = new DnsCache();
  2384. dnsCache.MinimumRecordTtl = 0;
  2385. dnsCache.MaximumRecordTtl = 7 * 24 * 60 * 60;
  2386. try
  2387. {
  2388. dnsResponse = await DnsClient.RecursiveResolveAsync(question, dnsCache, proxy, preferIPv6, udpPayloadSize, randomizeName, qnameMinimization, false, dnssecValidation, RETRIES, TIMEOUT);
  2389. }
  2390. catch (DnsClientResponseDnssecValidationException ex)
  2391. {
  2392. dnsResponse = ex.Response;
  2393. dnssecErrorMessage = ex.Message;
  2394. importResponse = false;
  2395. }
  2396. }
  2397. else
  2398. {
  2399. if ((type == DnsResourceRecordType.AXFR) && (protocol == DnsTransportProtocol.Udp))
  2400. protocol = DnsTransportProtocol.Tcp;
  2401. NameServerAddress nameServer;
  2402. if (server.Equals("this-server", StringComparison.OrdinalIgnoreCase))
  2403. {
  2404. switch (protocol)
  2405. {
  2406. case DnsTransportProtocol.Udp:
  2407. nameServer = _dnsServer.ThisServer;
  2408. break;
  2409. case DnsTransportProtocol.Tcp:
  2410. nameServer = _dnsServer.ThisServer.ChangeProtocol(DnsTransportProtocol.Tcp);
  2411. break;
  2412. case DnsTransportProtocol.Tls:
  2413. throw new DnsServerException("Cannot use DNS-over-TLS protocol for 'this-server'. Please use the TLS certificate domain name as the server.");
  2414. case DnsTransportProtocol.Https:
  2415. throw new DnsServerException("Cannot use DNS-over-HTTPS protocol for 'this-server'. Please use the TLS certificate domain name with a url as the server.");
  2416. case DnsTransportProtocol.HttpsJson:
  2417. throw new DnsServerException("Cannot use DNS-over-HTTPS (JSON) protocol for 'this-server'. Please use the TLS certificate domain name with a url as the server.");
  2418. default:
  2419. throw new InvalidOperationException();
  2420. }
  2421. proxy = null; //no proxy required for this server
  2422. }
  2423. else
  2424. {
  2425. nameServer = new NameServerAddress(server);
  2426. if (nameServer.Protocol != protocol)
  2427. nameServer = nameServer.ChangeProtocol(protocol);
  2428. if (nameServer.IsIPEndPointStale)
  2429. {
  2430. if (proxy is null)
  2431. await nameServer.ResolveIPAddressAsync(_dnsServer, _dnsServer.PreferIPv6);
  2432. }
  2433. else if (protocol != DnsTransportProtocol.Tls)
  2434. {
  2435. try
  2436. {
  2437. await nameServer.ResolveDomainNameAsync(_dnsServer);
  2438. }
  2439. catch
  2440. { }
  2441. }
  2442. }
  2443. DnsClient dnsClient = new DnsClient(nameServer);
  2444. dnsClient.Proxy = proxy;
  2445. dnsClient.PreferIPv6 = preferIPv6;
  2446. dnsClient.RandomizeName = randomizeName;
  2447. dnsClient.Retries = RETRIES;
  2448. dnsClient.Timeout = TIMEOUT;
  2449. dnsClient.UdpPayloadSize = udpPayloadSize;
  2450. dnsClient.DnssecValidation = dnssecValidation;
  2451. if (dnssecValidation)
  2452. {
  2453. //load trust anchors into dns client if domain is locally hosted
  2454. _dnsServer.AuthZoneManager.LoadTrustAnchorsTo(dnsClient, domain, type);
  2455. }
  2456. try
  2457. {
  2458. dnsResponse = await dnsClient.ResolveAsync(domain, type);
  2459. }
  2460. catch (DnsClientResponseDnssecValidationException ex)
  2461. {
  2462. dnsResponse = ex.Response;
  2463. dnssecErrorMessage = ex.Message;
  2464. importResponse = false;
  2465. }
  2466. if (type == DnsResourceRecordType.AXFR)
  2467. dnsResponse = dnsResponse.Join();
  2468. }
  2469. if (importResponse)
  2470. {
  2471. AuthZoneInfo zoneInfo = _dnsServer.AuthZoneManager.FindAuthZoneInfo(domain);
  2472. if ((zoneInfo is null) || ((zoneInfo.Type == AuthZoneType.Secondary) && !zoneInfo.Name.Equals(domain, StringComparison.OrdinalIgnoreCase)))
  2473. {
  2474. zoneInfo = _dnsServer.AuthZoneManager.CreatePrimaryZone(domain, _dnsServer.ServerDomain, false);
  2475. if (zoneInfo is null)
  2476. throw new DnsServerException("Cannot import records: failed to create primary zone.");
  2477. }
  2478. else
  2479. {
  2480. switch (zoneInfo.Type)
  2481. {
  2482. case AuthZoneType.Primary:
  2483. break;
  2484. case AuthZoneType.Forwarder:
  2485. if (type == DnsResourceRecordType.AXFR)
  2486. throw new DnsServerException("Cannot import records via zone transfer: import zone must be of primary type.");
  2487. break;
  2488. default:
  2489. throw new DnsServerException("Cannot import records: import zone must be of primary or forwarder type.");
  2490. }
  2491. }
  2492. if (type == DnsResourceRecordType.AXFR)
  2493. {
  2494. _dnsServer.AuthZoneManager.SyncZoneTransferRecords(zoneInfo.Name, dnsResponse.Answer);
  2495. }
  2496. else
  2497. {
  2498. List<DnsResourceRecord> importRecords = new List<DnsResourceRecord>(dnsResponse.Answer.Count + dnsResponse.Authority.Count);
  2499. foreach (DnsResourceRecord record in dnsResponse.Answer)
  2500. {
  2501. if (record.Name.Equals(zoneInfo.Name, StringComparison.OrdinalIgnoreCase) || record.Name.EndsWith("." + zoneInfo.Name, StringComparison.OrdinalIgnoreCase) || (zoneInfo.Name.Length == 0))
  2502. {
  2503. record.RemoveExpiry();
  2504. importRecords.Add(record);
  2505. if (record.Type == DnsResourceRecordType.NS)
  2506. record.SyncGlueRecords(dnsResponse.Additional);
  2507. }
  2508. }
  2509. foreach (DnsResourceRecord record in dnsResponse.Authority)
  2510. {
  2511. if (record.Name.Equals(zoneInfo.Name, StringComparison.OrdinalIgnoreCase) || record.Name.EndsWith("." + zoneInfo.Name, StringComparison.OrdinalIgnoreCase) || (zoneInfo.Name.Length == 0))
  2512. {
  2513. record.RemoveExpiry();
  2514. importRecords.Add(record);
  2515. if (record.Type == DnsResourceRecordType.NS)
  2516. record.SyncGlueRecords(dnsResponse.Additional);
  2517. }
  2518. }
  2519. _dnsServer.AuthZoneManager.ImportRecords(zoneInfo.Name, importRecords);
  2520. }
  2521. _log.Write(GetRequestRemoteEndPoint(request), "[" + GetSession(request).Username + "] DNS Client imported record(s) for authoritative zone {server: " + server + "; zone: " + zoneInfo.Name + "; type: " + type + ";}");
  2522. _dnsServer.AuthZoneManager.SaveZoneFile(zoneInfo.Name);
  2523. }
  2524. if (dnssecErrorMessage is not null)
  2525. {
  2526. jsonWriter.WritePropertyName("warningMessage");
  2527. jsonWriter.WriteValue(dnssecErrorMessage);
  2528. }
  2529. jsonWriter.WritePropertyName("result");
  2530. jsonWriter.WriteRawValue(JsonConvert.SerializeObject(dnsResponse, new StringEnumConverter()));
  2531. }
  2532. #endregion
  2533. #region auth
  2534. private void SetCredentials(string username, string password)
  2535. {
  2536. username = username.ToLower();
  2537. string passwordHash = GetPasswordHash(username, password);
  2538. _credentials[username] = passwordHash;
  2539. }
  2540. private void LoadCredentials(string username, string passwordHash)
  2541. {
  2542. username = username.ToLower();
  2543. _credentials[username] = passwordHash;
  2544. }
  2545. private static string GetPasswordHash(string username, string password)
  2546. {
  2547. using (HMAC hmac = new HMACSHA256(Encoding.UTF8.GetBytes(password)))
  2548. {
  2549. return Convert.ToHexString(hmac.ComputeHash(Encoding.UTF8.GetBytes(username))).ToLower();
  2550. }
  2551. }
  2552. #endregion
  2553. #region block list
  2554. private bool ForceUpdateBlockLists()
  2555. {
  2556. if ((_dnsServer.BlockListZoneManager.AllowListUrls.Count + _dnsServer.BlockListZoneManager.BlockListUrls.Count) > 0)
  2557. {
  2558. _blockListLastUpdatedOn = new DateTime();
  2559. StopBlockListUpdateTimer();
  2560. StartBlockListUpdateTimer();
  2561. return true;
  2562. }
  2563. return false;
  2564. }
  2565. private void StartBlockListUpdateTimer()
  2566. {
  2567. if (_blockListUpdateTimer == null)
  2568. {
  2569. _blockListUpdateTimer = new Timer(async delegate (object state)
  2570. {
  2571. try
  2572. {
  2573. if (DateTime.UtcNow > _blockListLastUpdatedOn.AddHours(_blockListUpdateIntervalHours))
  2574. {
  2575. if (await _dnsServer.BlockListZoneManager.UpdateBlockListsAsync())
  2576. {
  2577. //block lists were updated
  2578. //save last updated on time
  2579. _blockListLastUpdatedOn = DateTime.UtcNow;
  2580. SaveConfigFile();
  2581. }
  2582. }
  2583. }
  2584. catch (Exception ex)
  2585. {
  2586. _log.Write("DNS Server encountered an error while updating block lists.\r\n" + ex.ToString());
  2587. }
  2588. }, null, BLOCK_LIST_UPDATE_TIMER_INITIAL_INTERVAL, BLOCK_LIST_UPDATE_TIMER_PERIODIC_INTERVAL);
  2589. }
  2590. }
  2591. private void StopBlockListUpdateTimer()
  2592. {
  2593. if (_blockListUpdateTimer != null)
  2594. {
  2595. _blockListUpdateTimer.Dispose();
  2596. _blockListUpdateTimer = null;
  2597. }
  2598. }
  2599. #endregion
  2600. #region tls
  2601. private void StartTlsCertificateUpdateTimer()
  2602. {
  2603. if (_tlsCertificateUpdateTimer == null)
  2604. {
  2605. _tlsCertificateUpdateTimer = new Timer(delegate (object state)
  2606. {
  2607. if (!string.IsNullOrEmpty(_webServiceTlsCertificatePath))
  2608. {
  2609. try
  2610. {
  2611. FileInfo fileInfo = new FileInfo(_webServiceTlsCertificatePath);
  2612. if (fileInfo.Exists && (fileInfo.LastWriteTimeUtc != _webServiceTlsCertificateLastModifiedOn))
  2613. LoadWebServiceTlsCertificate(_webServiceTlsCertificatePath, _webServiceTlsCertificatePassword);
  2614. }
  2615. catch (Exception ex)
  2616. {
  2617. _log.Write("DNS Server encountered an error while updating Web Service TLS Certificate: " + _webServiceTlsCertificatePath + "\r\n" + ex.ToString());
  2618. }
  2619. }
  2620. if (!string.IsNullOrEmpty(_dnsTlsCertificatePath))
  2621. {
  2622. try
  2623. {
  2624. FileInfo fileInfo = new FileInfo(_dnsTlsCertificatePath);
  2625. if (fileInfo.Exists && (fileInfo.LastWriteTimeUtc != _dnsTlsCertificateLastModifiedOn))
  2626. LoadDnsTlsCertificate(_dnsTlsCertificatePath, _dnsTlsCertificatePassword);
  2627. }
  2628. catch (Exception ex)
  2629. {
  2630. _log.Write("DNS Server encountered an error while updating DNS Server TLS Certificate: " + _dnsTlsCertificatePath + "\r\n" + ex.ToString());
  2631. }
  2632. }
  2633. }, null, TLS_CERTIFICATE_UPDATE_TIMER_INITIAL_INTERVAL, TLS_CERTIFICATE_UPDATE_TIMER_INTERVAL);
  2634. }
  2635. }
  2636. private void StopTlsCertificateUpdateTimer()
  2637. {
  2638. if (_tlsCertificateUpdateTimer != null)
  2639. {
  2640. _tlsCertificateUpdateTimer.Dispose();
  2641. _tlsCertificateUpdateTimer = null;
  2642. }
  2643. }
  2644. private void LoadWebServiceTlsCertificate(string tlsCertificatePath, string tlsCertificatePassword)
  2645. {
  2646. FileInfo fileInfo = new FileInfo(tlsCertificatePath);
  2647. if (!fileInfo.Exists)
  2648. throw new ArgumentException("Web Service TLS certificate file does not exists: " + tlsCertificatePath);
  2649. if (Path.GetExtension(tlsCertificatePath) != ".pfx")
  2650. throw new ArgumentException("Web Service TLS certificate file must be PKCS #12 formatted with .pfx extension: " + tlsCertificatePath);
  2651. X509Certificate2 certificate = new X509Certificate2(tlsCertificatePath, tlsCertificatePassword);
  2652. _webServiceTlsCertificate = certificate;
  2653. _webServiceTlsCertificateLastModifiedOn = fileInfo.LastWriteTimeUtc;
  2654. _log.Write("Web Service TLS certificate was loaded: " + tlsCertificatePath);
  2655. }
  2656. private void LoadDnsTlsCertificate(string tlsCertificatePath, string tlsCertificatePassword)
  2657. {
  2658. FileInfo fileInfo = new FileInfo(tlsCertificatePath);
  2659. if (!fileInfo.Exists)
  2660. throw new ArgumentException("DNS Server TLS certificate file does not exists: " + tlsCertificatePath);
  2661. if (Path.GetExtension(tlsCertificatePath) != ".pfx")
  2662. throw new ArgumentException("DNS Server TLS certificate file must be PKCS #12 formatted with .pfx extension: " + tlsCertificatePath);
  2663. X509Certificate2 certificate = new X509Certificate2(tlsCertificatePath, tlsCertificatePassword);
  2664. _dnsServer.Certificate = certificate;
  2665. _dnsTlsCertificateLastModifiedOn = fileInfo.LastWriteTimeUtc;
  2666. _log.Write("DNS Server TLS certificate was loaded: " + tlsCertificatePath);
  2667. }
  2668. #endregion
  2669. #region config
  2670. private void LoadConfigFile()
  2671. {
  2672. string configFile = Path.Combine(_configFolder, "dns.config");
  2673. try
  2674. {
  2675. bool passwordResetOption = false;
  2676. if (!File.Exists(configFile))
  2677. {
  2678. string passwordResetConfigFile = Path.Combine(_configFolder, "reset.config");
  2679. if (File.Exists(passwordResetConfigFile))
  2680. {
  2681. passwordResetOption = true;
  2682. configFile = passwordResetConfigFile;
  2683. }
  2684. }
  2685. byte version;
  2686. using (FileStream fS = new FileStream(configFile, FileMode.Open, FileAccess.Read))
  2687. {
  2688. BinaryReader bR = new BinaryReader(fS);
  2689. if (Encoding.ASCII.GetString(bR.ReadBytes(2)) != "DS") //format
  2690. throw new InvalidDataException("DnsServer config file format is invalid.");
  2691. version = bR.ReadByte();
  2692. switch (version)
  2693. {
  2694. case 2:
  2695. case 3:
  2696. case 4:
  2697. case 5:
  2698. case 6:
  2699. case 7:
  2700. case 8:
  2701. case 9:
  2702. case 10:
  2703. case 11:
  2704. case 12:
  2705. case 13:
  2706. case 14:
  2707. case 15:
  2708. case 16:
  2709. case 17:
  2710. case 18:
  2711. case 19:
  2712. case 20:
  2713. case 21:
  2714. case 22:
  2715. case 23:
  2716. case 24:
  2717. case 25:
  2718. case 26:
  2719. _dnsServer.ServerDomain = bR.ReadShortString();
  2720. _webServiceHttpPort = bR.ReadInt32();
  2721. if (version >= 13)
  2722. {
  2723. {
  2724. int count = bR.ReadByte();
  2725. if (count > 0)
  2726. {
  2727. IPAddress[] localAddresses = new IPAddress[count];
  2728. for (int i = 0; i < count; i++)
  2729. localAddresses[i] = IPAddressExtension.Parse(bR);
  2730. _webServiceLocalAddresses = localAddresses;
  2731. }
  2732. }
  2733. _webServiceTlsPort = bR.ReadInt32();
  2734. _webServiceEnableTls = bR.ReadBoolean();
  2735. _webServiceHttpToTlsRedirect = bR.ReadBoolean();
  2736. _webServiceTlsCertificatePath = bR.ReadShortString();
  2737. _webServiceTlsCertificatePassword = bR.ReadShortString();
  2738. if (_webServiceTlsCertificatePath.Length == 0)
  2739. _webServiceTlsCertificatePath = null;
  2740. if (_webServiceTlsCertificatePath != null)
  2741. {
  2742. try
  2743. {
  2744. LoadWebServiceTlsCertificate(_webServiceTlsCertificatePath, _webServiceTlsCertificatePassword);
  2745. }
  2746. catch (Exception ex)
  2747. {
  2748. _log.Write("DNS Server encountered an error while loading Web Service TLS certificate: " + _webServiceTlsCertificatePath + "\r\n" + ex.ToString());
  2749. }
  2750. StartTlsCertificateUpdateTimer();
  2751. }
  2752. }
  2753. else
  2754. {
  2755. _webServiceLocalAddresses = new IPAddress[] { IPAddress.Any, IPAddress.IPv6Any };
  2756. _webServiceTlsPort = 53443;
  2757. _webServiceEnableTls = false;
  2758. _webServiceHttpToTlsRedirect = false;
  2759. _webServiceTlsCertificatePath = string.Empty;
  2760. _webServiceTlsCertificatePassword = string.Empty;
  2761. }
  2762. _dnsServer.PreferIPv6 = bR.ReadBoolean();
  2763. if (bR.ReadBoolean()) //logQueries
  2764. _dnsServer.QueryLogManager = _log;
  2765. if (version >= 14)
  2766. _dnsServer.StatsManager.MaxStatFileDays = bR.ReadInt32();
  2767. else
  2768. _dnsServer.StatsManager.MaxStatFileDays = 0;
  2769. if (version >= 17)
  2770. {
  2771. _dnsServer.Recursion = (DnsServerRecursion)bR.ReadByte();
  2772. {
  2773. int count = bR.ReadByte();
  2774. if (count > 0)
  2775. {
  2776. NetworkAddress[] networks = new NetworkAddress[count];
  2777. for (int i = 0; i < count; i++)
  2778. networks[i] = NetworkAddress.Parse(bR);
  2779. _dnsServer.RecursionDeniedNetworks = networks;
  2780. }
  2781. }
  2782. {
  2783. int count = bR.ReadByte();
  2784. if (count > 0)
  2785. {
  2786. NetworkAddress[] networks = new NetworkAddress[count];
  2787. for (int i = 0; i < count; i++)
  2788. networks[i] = NetworkAddress.Parse(bR);
  2789. _dnsServer.RecursionAllowedNetworks = networks;
  2790. }
  2791. }
  2792. }
  2793. else
  2794. {
  2795. bool allowRecursion = bR.ReadBoolean();
  2796. bool allowRecursionOnlyForPrivateNetworks;
  2797. if (version >= 4)
  2798. allowRecursionOnlyForPrivateNetworks = bR.ReadBoolean();
  2799. else
  2800. allowRecursionOnlyForPrivateNetworks = true; //default true for security reasons
  2801. if (allowRecursion)
  2802. {
  2803. if (allowRecursionOnlyForPrivateNetworks)
  2804. _dnsServer.Recursion = DnsServerRecursion.AllowOnlyForPrivateNetworks;
  2805. else
  2806. _dnsServer.Recursion = DnsServerRecursion.Allow;
  2807. }
  2808. else
  2809. {
  2810. _dnsServer.Recursion = DnsServerRecursion.Deny;
  2811. }
  2812. }
  2813. if (version >= 12)
  2814. _dnsServer.RandomizeName = bR.ReadBoolean();
  2815. else
  2816. _dnsServer.RandomizeName = true; //default true to enable security feature
  2817. if (version >= 15)
  2818. _dnsServer.QnameMinimization = bR.ReadBoolean();
  2819. else
  2820. _dnsServer.QnameMinimization = true; //default true to enable privacy feature
  2821. if (version >= 20)
  2822. {
  2823. _dnsServer.QpmLimitRequests = bR.ReadInt32();
  2824. _dnsServer.QpmLimitErrors = bR.ReadInt32();
  2825. _dnsServer.QpmLimitSampleMinutes = bR.ReadInt32();
  2826. _dnsServer.QpmLimitIPv4PrefixLength = bR.ReadInt32();
  2827. _dnsServer.QpmLimitIPv6PrefixLength = bR.ReadInt32();
  2828. }
  2829. else if (version >= 17)
  2830. {
  2831. _dnsServer.QpmLimitRequests = bR.ReadInt32();
  2832. _dnsServer.QpmLimitSampleMinutes = bR.ReadInt32();
  2833. _ = bR.ReadInt32(); //read obsolete value _dnsServer.QpmLimitSamplingIntervalInMinutes
  2834. }
  2835. else
  2836. {
  2837. _dnsServer.QpmLimitRequests = 0;
  2838. _dnsServer.QpmLimitErrors = 0;
  2839. _dnsServer.QpmLimitSampleMinutes = 1;
  2840. _dnsServer.QpmLimitIPv4PrefixLength = 24;
  2841. _dnsServer.QpmLimitIPv6PrefixLength = 56;
  2842. }
  2843. if (version >= 13)
  2844. {
  2845. _dnsServer.ServeStale = bR.ReadBoolean();
  2846. _dnsServer.CacheZoneManager.ServeStaleTtl = bR.ReadUInt32();
  2847. }
  2848. else
  2849. {
  2850. _dnsServer.ServeStale = true;
  2851. _dnsServer.CacheZoneManager.ServeStaleTtl = CacheZoneManager.SERVE_STALE_TTL;
  2852. }
  2853. if (version >= 9)
  2854. {
  2855. _dnsServer.CachePrefetchEligibility = bR.ReadInt32();
  2856. _dnsServer.CachePrefetchTrigger = bR.ReadInt32();
  2857. _dnsServer.CachePrefetchSampleIntervalInMinutes = bR.ReadInt32();
  2858. _dnsServer.CachePrefetchSampleEligibilityHitsPerHour = bR.ReadInt32();
  2859. }
  2860. else
  2861. {
  2862. _dnsServer.CachePrefetchEligibility = 2;
  2863. _dnsServer.CachePrefetchTrigger = 9;
  2864. _dnsServer.CachePrefetchSampleIntervalInMinutes = 5;
  2865. _dnsServer.CachePrefetchSampleEligibilityHitsPerHour = 30;
  2866. }
  2867. NetProxyType proxyType = (NetProxyType)bR.ReadByte();
  2868. if (proxyType != NetProxyType.None)
  2869. {
  2870. string address = bR.ReadShortString();
  2871. int port = bR.ReadInt32();
  2872. NetworkCredential credential = null;
  2873. if (bR.ReadBoolean()) //credential set
  2874. credential = new NetworkCredential(bR.ReadShortString(), bR.ReadShortString());
  2875. _dnsServer.Proxy = NetProxy.CreateProxy(proxyType, address, port, credential);
  2876. if (version >= 10)
  2877. {
  2878. int count = bR.ReadByte();
  2879. List<NetProxyBypassItem> bypassList = new List<NetProxyBypassItem>(count);
  2880. for (int i = 0; i < count; i++)
  2881. bypassList.Add(new NetProxyBypassItem(bR.ReadShortString()));
  2882. _dnsServer.Proxy.BypassList = bypassList;
  2883. }
  2884. else
  2885. {
  2886. _dnsServer.Proxy.BypassList = null;
  2887. }
  2888. }
  2889. else
  2890. {
  2891. _dnsServer.Proxy = null;
  2892. }
  2893. {
  2894. int count = bR.ReadByte();
  2895. if (count > 0)
  2896. {
  2897. NameServerAddress[] forwarders = new NameServerAddress[count];
  2898. for (int i = 0; i < count; i++)
  2899. forwarders[i] = new NameServerAddress(bR);
  2900. _dnsServer.Forwarders = forwarders;
  2901. }
  2902. }
  2903. if (version <= 10)
  2904. {
  2905. DnsTransportProtocol forwarderProtocol = (DnsTransportProtocol)bR.ReadByte();
  2906. if (_dnsServer.Forwarders != null)
  2907. {
  2908. List<NameServerAddress> forwarders = new List<NameServerAddress>();
  2909. foreach (NameServerAddress forwarder in _dnsServer.Forwarders)
  2910. {
  2911. if (forwarder.Protocol == forwarderProtocol)
  2912. forwarders.Add(forwarder);
  2913. else
  2914. forwarders.Add(forwarder.ChangeProtocol(forwarderProtocol));
  2915. }
  2916. _dnsServer.Forwarders = forwarders;
  2917. }
  2918. }
  2919. {
  2920. int count = bR.ReadByte();
  2921. if (count > 0)
  2922. {
  2923. if (version > 2)
  2924. {
  2925. for (int i = 0; i < count; i++)
  2926. LoadCredentials(bR.ReadShortString(), bR.ReadShortString());
  2927. }
  2928. else
  2929. {
  2930. for (int i = 0; i < count; i++)
  2931. SetCredentials(bR.ReadShortString(), bR.ReadShortString());
  2932. }
  2933. }
  2934. }
  2935. if (version <= 6)
  2936. {
  2937. int count = bR.ReadInt32();
  2938. _configDisabledZones = new List<string>(count);
  2939. for (int i = 0; i < count; i++)
  2940. {
  2941. string domain = bR.ReadShortString();
  2942. _configDisabledZones.Add(domain);
  2943. }
  2944. }
  2945. if (version >= 18)
  2946. _dnsServer.EnableBlocking = bR.ReadBoolean();
  2947. else
  2948. _dnsServer.EnableBlocking = true;
  2949. if (version >= 18)
  2950. _dnsServer.BlockingType = (DnsServerBlockingType)bR.ReadByte();
  2951. else if (version >= 16)
  2952. _dnsServer.BlockingType = bR.ReadBoolean() ? DnsServerBlockingType.NxDomain : DnsServerBlockingType.AnyAddress;
  2953. else
  2954. _dnsServer.BlockingType = DnsServerBlockingType.AnyAddress;
  2955. if (version >= 18)
  2956. {
  2957. //read custom blocking addresses
  2958. int count = bR.ReadByte();
  2959. if (count > 0)
  2960. {
  2961. List<DnsARecordData> dnsARecords = new List<DnsARecordData>();
  2962. List<DnsAAAARecordData> dnsAAAARecords = new List<DnsAAAARecordData>();
  2963. for (int i = 0; i < count; i++)
  2964. {
  2965. IPAddress customAddress = IPAddressExtension.Parse(bR);
  2966. switch (customAddress.AddressFamily)
  2967. {
  2968. case AddressFamily.InterNetwork:
  2969. dnsARecords.Add(new DnsARecordData(customAddress));
  2970. break;
  2971. case AddressFamily.InterNetworkV6:
  2972. dnsAAAARecords.Add(new DnsAAAARecordData(customAddress));
  2973. break;
  2974. }
  2975. }
  2976. _dnsServer.CustomBlockingARecords = dnsARecords;
  2977. _dnsServer.CustomBlockingAAAARecords = dnsAAAARecords;
  2978. }
  2979. }
  2980. else
  2981. {
  2982. _dnsServer.CustomBlockingARecords = null;
  2983. _dnsServer.CustomBlockingAAAARecords = null;
  2984. }
  2985. if (version > 4)
  2986. {
  2987. //read block list urls
  2988. int count = bR.ReadByte();
  2989. for (int i = 0; i < count; i++)
  2990. {
  2991. string listUrl = bR.ReadShortString();
  2992. if (listUrl.StartsWith("!"))
  2993. _dnsServer.BlockListZoneManager.AllowListUrls.Add(new Uri(listUrl.Substring(1)));
  2994. else
  2995. _dnsServer.BlockListZoneManager.BlockListUrls.Add(new Uri(listUrl));
  2996. }
  2997. _blockListLastUpdatedOn = bR.ReadDateTime();
  2998. if (version >= 13)
  2999. _blockListUpdateIntervalHours = bR.ReadInt32();
  3000. }
  3001. else
  3002. {
  3003. _dnsServer.BlockListZoneManager.AllowListUrls.Clear();
  3004. _dnsServer.BlockListZoneManager.BlockListUrls.Clear();
  3005. _blockListLastUpdatedOn = DateTime.MinValue;
  3006. _blockListUpdateIntervalHours = 24;
  3007. }
  3008. if (version >= 11)
  3009. {
  3010. int count = bR.ReadByte();
  3011. if (count > 0)
  3012. {
  3013. IPEndPoint[] localEndPoints = new IPEndPoint[count];
  3014. for (int i = 0; i < count; i++)
  3015. localEndPoints[i] = (IPEndPoint)EndPointExtension.Parse(bR);
  3016. _dnsServer.LocalEndPoints = localEndPoints;
  3017. }
  3018. }
  3019. else if (version >= 6)
  3020. {
  3021. int count = bR.ReadByte();
  3022. if (count > 0)
  3023. {
  3024. IPEndPoint[] localEndPoints = new IPEndPoint[count];
  3025. for (int i = 0; i < count; i++)
  3026. localEndPoints[i] = new IPEndPoint(IPAddressExtension.Parse(bR), 53);
  3027. _dnsServer.LocalEndPoints = localEndPoints;
  3028. }
  3029. }
  3030. else
  3031. {
  3032. _dnsServer.LocalEndPoints = new IPEndPoint[] { new IPEndPoint(IPAddress.Any, 53), new IPEndPoint(IPAddress.IPv6Any, 53) };
  3033. }
  3034. if (version >= 8)
  3035. {
  3036. _dnsServer.EnableDnsOverHttp = bR.ReadBoolean();
  3037. _dnsServer.EnableDnsOverTls = bR.ReadBoolean();
  3038. _dnsServer.EnableDnsOverHttps = bR.ReadBoolean();
  3039. _dnsTlsCertificatePath = bR.ReadShortString();
  3040. _dnsTlsCertificatePassword = bR.ReadShortString();
  3041. if (_dnsTlsCertificatePath.Length == 0)
  3042. _dnsTlsCertificatePath = null;
  3043. if (_dnsTlsCertificatePath != null)
  3044. {
  3045. try
  3046. {
  3047. LoadDnsTlsCertificate(_dnsTlsCertificatePath, _dnsTlsCertificatePassword);
  3048. }
  3049. catch (Exception ex)
  3050. {
  3051. _log.Write("DNS Server encountered an error while loading DNS Server TLS certificate: " + _dnsTlsCertificatePath + "\r\n" + ex.ToString());
  3052. }
  3053. StartTlsCertificateUpdateTimer();
  3054. }
  3055. }
  3056. else
  3057. {
  3058. _dnsServer.EnableDnsOverHttp = false;
  3059. _dnsServer.EnableDnsOverTls = false;
  3060. _dnsServer.EnableDnsOverHttps = false;
  3061. _dnsTlsCertificatePath = string.Empty;
  3062. _dnsTlsCertificatePassword = string.Empty;
  3063. }
  3064. if (version >= 19)
  3065. {
  3066. _dnsServer.CacheZoneManager.MinimumRecordTtl = bR.ReadUInt32();
  3067. _dnsServer.CacheZoneManager.MaximumRecordTtl = bR.ReadUInt32();
  3068. _dnsServer.CacheZoneManager.NegativeRecordTtl = bR.ReadUInt32();
  3069. _dnsServer.CacheZoneManager.FailureRecordTtl = bR.ReadUInt32();
  3070. }
  3071. else
  3072. {
  3073. _dnsServer.CacheZoneManager.MinimumRecordTtl = CacheZoneManager.MINIMUM_RECORD_TTL;
  3074. _dnsServer.CacheZoneManager.MaximumRecordTtl = CacheZoneManager.MAXIMUM_RECORD_TTL;
  3075. _dnsServer.CacheZoneManager.NegativeRecordTtl = CacheZoneManager.NEGATIVE_RECORD_TTL;
  3076. _dnsServer.CacheZoneManager.FailureRecordTtl = CacheZoneManager.FAILURE_RECORD_TTL;
  3077. }
  3078. if (version >= 21)
  3079. {
  3080. int count = bR.ReadByte();
  3081. Dictionary<string, TsigKey> tsigKeys = new Dictionary<string, TsigKey>(count);
  3082. for (int i = 0; i < count; i++)
  3083. {
  3084. string keyName = bR.ReadShortString();
  3085. string sharedSecret = bR.ReadShortString();
  3086. TsigAlgorithm algorithm = (TsigAlgorithm)bR.ReadByte();
  3087. tsigKeys.Add(keyName, new TsigKey(keyName, sharedSecret, algorithm));
  3088. }
  3089. _dnsServer.TsigKeys = tsigKeys;
  3090. }
  3091. else if (version >= 20)
  3092. {
  3093. int count = bR.ReadByte();
  3094. Dictionary<string, TsigKey> tsigKeys = new Dictionary<string, TsigKey>(count);
  3095. for (int i = 0; i < count; i++)
  3096. {
  3097. string keyName = bR.ReadShortString();
  3098. string sharedSecret = bR.ReadShortString();
  3099. tsigKeys.Add(keyName, new TsigKey(keyName, sharedSecret, TsigAlgorithm.HMAC_SHA256));
  3100. }
  3101. _dnsServer.TsigKeys = tsigKeys;
  3102. }
  3103. else
  3104. {
  3105. _dnsServer.TsigKeys = null;
  3106. }
  3107. if (version >= 22)
  3108. _dnsServer.NsRevalidation = bR.ReadBoolean();
  3109. else
  3110. _dnsServer.NsRevalidation = false; //default false since some badly configured websites fail to load
  3111. if (version >= 23)
  3112. {
  3113. _dnsServer.AllowTxtBlockingReport = bR.ReadBoolean();
  3114. _zonesApi.DefaultRecordTtl = bR.ReadUInt32();
  3115. }
  3116. else
  3117. {
  3118. _dnsServer.AllowTxtBlockingReport = true;
  3119. _zonesApi.DefaultRecordTtl = 3600;
  3120. }
  3121. if (version >= 24)
  3122. {
  3123. _webServiceUseSelfSignedTlsCertificate = bR.ReadBoolean();
  3124. SelfSignedCertCheck(false);
  3125. }
  3126. else
  3127. {
  3128. _webServiceUseSelfSignedTlsCertificate = false;
  3129. }
  3130. if (version >= 25)
  3131. _dnsServer.UdpPayloadSize = bR.ReadUInt16();
  3132. else
  3133. _dnsServer.UdpPayloadSize = DnsDatagram.EDNS_DEFAULT_UDP_PAYLOAD_SIZE;
  3134. if (version >= 26)
  3135. {
  3136. _dnsServer.DnssecValidation = bR.ReadBoolean();
  3137. _dnsServer.ResolverRetries = bR.ReadInt32();
  3138. _dnsServer.ResolverTimeout = bR.ReadInt32();
  3139. _dnsServer.ResolverMaxStackCount = bR.ReadInt32();
  3140. _dnsServer.ForwarderRetries = bR.ReadInt32();
  3141. _dnsServer.ForwarderTimeout = bR.ReadInt32();
  3142. _dnsServer.ForwarderConcurrency = bR.ReadInt32();
  3143. _dnsServer.ClientTimeout = bR.ReadInt32();
  3144. _dnsServer.TcpSendTimeout = bR.ReadInt32();
  3145. _dnsServer.TcpReceiveTimeout = bR.ReadInt32();
  3146. }
  3147. else
  3148. {
  3149. _dnsServer.DnssecValidation = true;
  3150. CreateForwarderZoneToDisableDnssecForNTP();
  3151. _dnsServer.ResolverRetries = 3;
  3152. _dnsServer.ResolverTimeout = 2000;
  3153. _dnsServer.ResolverMaxStackCount = 16;
  3154. _dnsServer.ForwarderRetries = 3;
  3155. _dnsServer.ForwarderTimeout = 2000;
  3156. _dnsServer.ForwarderConcurrency = 2;
  3157. _dnsServer.ClientTimeout = 4000;
  3158. _dnsServer.TcpSendTimeout = 10000;
  3159. _dnsServer.TcpReceiveTimeout = 10000;
  3160. }
  3161. break;
  3162. default:
  3163. throw new InvalidDataException("DNS Server config version not supported.");
  3164. }
  3165. }
  3166. _log.Write("DNS Server config file was loaded: " + configFile);
  3167. if (passwordResetOption)
  3168. {
  3169. SetCredentials("admin", "admin");
  3170. _log.Write("DNS Server reset password for user: admin");
  3171. SaveConfigFile();
  3172. try
  3173. {
  3174. File.Delete(configFile);
  3175. }
  3176. catch
  3177. { }
  3178. }
  3179. if (version <= 6)
  3180. SaveConfigFile(); //save as new config version to avoid loading old version next time
  3181. }
  3182. catch (FileNotFoundException)
  3183. {
  3184. _log.Write("DNS Server config file was not found: " + configFile);
  3185. _log.Write("DNS Server is restoring default config file.");
  3186. string serverDomain = Environment.GetEnvironmentVariable("DNS_SERVER_DOMAIN");
  3187. if (!string.IsNullOrEmpty(serverDomain))
  3188. _dnsServer.ServerDomain = serverDomain;
  3189. string adminPassword = Environment.GetEnvironmentVariable("DNS_SERVER_ADMIN_PASSWORD");
  3190. string adminPasswordFile = Environment.GetEnvironmentVariable("DNS_SERVER_ADMIN_PASSWORD_FILE");
  3191. if (!string.IsNullOrEmpty(adminPassword))
  3192. {
  3193. SetCredentials("admin", adminPassword);
  3194. }
  3195. else if (!string.IsNullOrEmpty(adminPasswordFile))
  3196. {
  3197. try
  3198. {
  3199. using (StreamReader sR = new StreamReader(adminPasswordFile, true))
  3200. {
  3201. string password = sR.ReadLine();
  3202. SetCredentials("admin", password);
  3203. }
  3204. }
  3205. catch (Exception ex)
  3206. {
  3207. _log.Write(ex);
  3208. SetCredentials("admin", "admin");
  3209. }
  3210. }
  3211. else
  3212. {
  3213. SetCredentials("admin", "admin");
  3214. }
  3215. string strPreferIPv6 = Environment.GetEnvironmentVariable("DNS_SERVER_PREFER_IPV6");
  3216. if (!string.IsNullOrEmpty(strPreferIPv6))
  3217. _dnsServer.PreferIPv6 = bool.Parse(strPreferIPv6);
  3218. string strDnsOverHttp = Environment.GetEnvironmentVariable("DNS_SERVER_OPTIONAL_PROTOCOL_DNS_OVER_HTTP");
  3219. if (!string.IsNullOrEmpty(strDnsOverHttp))
  3220. _dnsServer.EnableDnsOverHttp = bool.Parse(strDnsOverHttp);
  3221. string strRecursion = Environment.GetEnvironmentVariable("DNS_SERVER_RECURSION");
  3222. if (!string.IsNullOrEmpty(strRecursion))
  3223. _dnsServer.Recursion = Enum.Parse<DnsServerRecursion>(strRecursion, true);
  3224. else
  3225. _dnsServer.Recursion = DnsServerRecursion.AllowOnlyForPrivateNetworks; //default for security reasons
  3226. string strRecursionDeniedNetworks = Environment.GetEnvironmentVariable("DNS_SERVER_RECURSION_DENIED_NETWORKS");
  3227. if (!string.IsNullOrEmpty(strRecursionDeniedNetworks))
  3228. {
  3229. string[] strRecursionDeniedNetworkAddresses = strRecursionDeniedNetworks.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  3230. NetworkAddress[] networks = new NetworkAddress[strRecursionDeniedNetworkAddresses.Length];
  3231. for (int i = 0; i < networks.Length; i++)
  3232. networks[i] = NetworkAddress.Parse(strRecursionDeniedNetworkAddresses[i].Trim());
  3233. _dnsServer.RecursionDeniedNetworks = networks;
  3234. }
  3235. string strRecursionAllowedNetworks = Environment.GetEnvironmentVariable("DNS_SERVER_RECURSION_ALLOWED_NETWORKS");
  3236. if (!string.IsNullOrEmpty(strRecursionAllowedNetworks))
  3237. {
  3238. string[] strRecursionAllowedNetworkAddresses = strRecursionAllowedNetworks.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  3239. NetworkAddress[] networks = new NetworkAddress[strRecursionAllowedNetworkAddresses.Length];
  3240. for (int i = 0; i < networks.Length; i++)
  3241. networks[i] = NetworkAddress.Parse(strRecursionAllowedNetworkAddresses[i].Trim());
  3242. _dnsServer.RecursionAllowedNetworks = networks;
  3243. }
  3244. string strEnableBlocking = Environment.GetEnvironmentVariable("DNS_SERVER_ENABLE_BLOCKING");
  3245. if (!string.IsNullOrEmpty(strEnableBlocking))
  3246. _dnsServer.EnableBlocking = bool.Parse(strEnableBlocking);
  3247. string strAllowTxtBlockingReport = Environment.GetEnvironmentVariable("DNS_SERVER_ALLOW_TXT_BLOCKING_REPORT");
  3248. if (!string.IsNullOrEmpty(strAllowTxtBlockingReport))
  3249. _dnsServer.AllowTxtBlockingReport = bool.Parse(strAllowTxtBlockingReport);
  3250. string strForwarders = Environment.GetEnvironmentVariable("DNS_SERVER_FORWARDERS");
  3251. if (!string.IsNullOrEmpty(strForwarders))
  3252. {
  3253. DnsTransportProtocol forwarderProtocol;
  3254. string strForwarderProtocol = Environment.GetEnvironmentVariable("DNS_SERVER_FORWARDER_PROTOCOL");
  3255. if (string.IsNullOrEmpty(strForwarderProtocol))
  3256. forwarderProtocol = DnsTransportProtocol.Udp;
  3257. else
  3258. forwarderProtocol = Enum.Parse<DnsTransportProtocol>(strForwarderProtocol, true);
  3259. List<NameServerAddress> forwarders = new List<NameServerAddress>();
  3260. string[] strForwardersAddresses = strForwarders.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  3261. foreach (string strForwarderAddress in strForwardersAddresses)
  3262. forwarders.Add(new NameServerAddress(strForwarderAddress.Trim(), forwarderProtocol));
  3263. _dnsServer.Forwarders = forwarders;
  3264. }
  3265. _dnsServer.RandomizeName = true; //default true to enable security feature
  3266. _dnsServer.QnameMinimization = true; //default true to enable privacy feature
  3267. _dnsServer.NsRevalidation = false; //default false since some badly configured websites fail to load
  3268. _dnsServer.DnssecValidation = true;
  3269. CreateForwarderZoneToDisableDnssecForNTP();
  3270. SaveConfigFile();
  3271. }
  3272. catch (Exception ex)
  3273. {
  3274. _log.Write("DNS Server encountered an error while loading config file: " + configFile + "\r\n" + ex.ToString());
  3275. _log.Write("Note: You may try deleting the config file to fix this issue. However, you will lose DNS settings but, zone data wont be affected.");
  3276. throw;
  3277. }
  3278. }
  3279. private void CreateForwarderZoneToDisableDnssecForNTP()
  3280. {
  3281. if (Environment.OSVersion.Platform == PlatformID.Unix)
  3282. {
  3283. //adding a conditional forwarder zone for disabling DNSSEC validation for ntp.org so that systems with no real-time clock can sync time
  3284. string ntpDomain = "ntp.org";
  3285. string fwdRecordComments = "This forwarder zone was automatically created to disable DNSSEC validation for ntp.org to allow systems with no real-time clock (e.g. Raspberry Pi) to sync time via NTP when booting.";
  3286. if (_dnsServer.AuthZoneManager.CreateForwarderZone(ntpDomain, DnsTransportProtocol.Udp, "this-server", false, NetProxyType.None, null, 0, null, null, fwdRecordComments) is not null)
  3287. {
  3288. Directory.CreateDirectory(Path.Combine(_dnsServer.ConfigFolder, "zones"));
  3289. _dnsServer.AuthZoneManager.SaveZoneFile(ntpDomain);
  3290. }
  3291. }
  3292. }
  3293. private void SaveConfigFile()
  3294. {
  3295. string configFile = Path.Combine(_configFolder, "dns.config");
  3296. using (MemoryStream mS = new MemoryStream())
  3297. {
  3298. //serialize config
  3299. BinaryWriter bW = new BinaryWriter(mS);
  3300. bW.Write(Encoding.ASCII.GetBytes("DS")); //format
  3301. bW.Write((byte)26); //version
  3302. bW.WriteShortString(_dnsServer.ServerDomain);
  3303. bW.Write(_webServiceHttpPort);
  3304. {
  3305. bW.Write(Convert.ToByte(_webServiceLocalAddresses.Count));
  3306. foreach (IPAddress localAddress in _webServiceLocalAddresses)
  3307. localAddress.WriteTo(bW);
  3308. }
  3309. bW.Write(_webServiceTlsPort);
  3310. bW.Write(_webServiceEnableTls);
  3311. bW.Write(_webServiceHttpToTlsRedirect);
  3312. if (_webServiceTlsCertificatePath == null)
  3313. bW.WriteShortString(string.Empty);
  3314. else
  3315. bW.WriteShortString(_webServiceTlsCertificatePath);
  3316. if (_webServiceTlsCertificatePassword == null)
  3317. bW.WriteShortString(string.Empty);
  3318. else
  3319. bW.WriteShortString(_webServiceTlsCertificatePassword);
  3320. bW.Write(_dnsServer.PreferIPv6);
  3321. bW.Write(_dnsServer.QueryLogManager != null); //logQueries
  3322. bW.Write(_dnsServer.StatsManager.MaxStatFileDays);
  3323. bW.Write((byte)_dnsServer.Recursion);
  3324. if (_dnsServer.RecursionDeniedNetworks is null)
  3325. {
  3326. bW.Write((byte)0);
  3327. }
  3328. else
  3329. {
  3330. bW.Write(Convert.ToByte(_dnsServer.RecursionDeniedNetworks.Count));
  3331. foreach (NetworkAddress networkAddress in _dnsServer.RecursionDeniedNetworks)
  3332. networkAddress.WriteTo(bW);
  3333. }
  3334. if (_dnsServer.RecursionAllowedNetworks is null)
  3335. {
  3336. bW.Write((byte)0);
  3337. }
  3338. else
  3339. {
  3340. bW.Write(Convert.ToByte(_dnsServer.RecursionAllowedNetworks.Count));
  3341. foreach (NetworkAddress networkAddress in _dnsServer.RecursionAllowedNetworks)
  3342. networkAddress.WriteTo(bW);
  3343. }
  3344. bW.Write(_dnsServer.RandomizeName);
  3345. bW.Write(_dnsServer.QnameMinimization);
  3346. bW.Write(_dnsServer.QpmLimitRequests);
  3347. bW.Write(_dnsServer.QpmLimitErrors);
  3348. bW.Write(_dnsServer.QpmLimitSampleMinutes);
  3349. bW.Write(_dnsServer.QpmLimitIPv4PrefixLength);
  3350. bW.Write(_dnsServer.QpmLimitIPv6PrefixLength);
  3351. bW.Write(_dnsServer.ServeStale);
  3352. bW.Write(_dnsServer.CacheZoneManager.ServeStaleTtl);
  3353. bW.Write(_dnsServer.CachePrefetchEligibility);
  3354. bW.Write(_dnsServer.CachePrefetchTrigger);
  3355. bW.Write(_dnsServer.CachePrefetchSampleIntervalInMinutes);
  3356. bW.Write(_dnsServer.CachePrefetchSampleEligibilityHitsPerHour);
  3357. if (_dnsServer.Proxy == null)
  3358. {
  3359. bW.Write((byte)NetProxyType.None);
  3360. }
  3361. else
  3362. {
  3363. bW.Write((byte)_dnsServer.Proxy.Type);
  3364. bW.WriteShortString(_dnsServer.Proxy.Address);
  3365. bW.Write(_dnsServer.Proxy.Port);
  3366. NetworkCredential credential = _dnsServer.Proxy.Credential;
  3367. if (credential == null)
  3368. {
  3369. bW.Write(false);
  3370. }
  3371. else
  3372. {
  3373. bW.Write(true);
  3374. bW.WriteShortString(credential.UserName);
  3375. bW.WriteShortString(credential.Password);
  3376. }
  3377. //bypass list
  3378. {
  3379. bW.Write(Convert.ToByte(_dnsServer.Proxy.BypassList.Count));
  3380. foreach (NetProxyBypassItem item in _dnsServer.Proxy.BypassList)
  3381. bW.WriteShortString(item.Value);
  3382. }
  3383. }
  3384. if (_dnsServer.Forwarders == null)
  3385. {
  3386. bW.Write((byte)0);
  3387. }
  3388. else
  3389. {
  3390. bW.Write(Convert.ToByte(_dnsServer.Forwarders.Count));
  3391. foreach (NameServerAddress forwarder in _dnsServer.Forwarders)
  3392. forwarder.WriteTo(bW);
  3393. }
  3394. {
  3395. bW.Write(Convert.ToByte(_credentials.Count));
  3396. foreach (KeyValuePair<string, string> credential in _credentials)
  3397. {
  3398. bW.WriteShortString(credential.Key);
  3399. bW.WriteShortString(credential.Value);
  3400. }
  3401. }
  3402. //block list
  3403. bW.Write(_dnsServer.EnableBlocking);
  3404. bW.Write((byte)_dnsServer.BlockingType);
  3405. {
  3406. bW.Write(Convert.ToByte(_dnsServer.CustomBlockingARecords.Count + _dnsServer.CustomBlockingAAAARecords.Count));
  3407. foreach (DnsARecordData record in _dnsServer.CustomBlockingARecords)
  3408. record.Address.WriteTo(bW);
  3409. foreach (DnsAAAARecordData record in _dnsServer.CustomBlockingAAAARecords)
  3410. record.Address.WriteTo(bW);
  3411. }
  3412. {
  3413. bW.Write(Convert.ToByte(_dnsServer.BlockListZoneManager.AllowListUrls.Count + _dnsServer.BlockListZoneManager.BlockListUrls.Count));
  3414. foreach (Uri allowListUrl in _dnsServer.BlockListZoneManager.AllowListUrls)
  3415. bW.WriteShortString("!" + allowListUrl.AbsoluteUri);
  3416. foreach (Uri blockListUrl in _dnsServer.BlockListZoneManager.BlockListUrls)
  3417. bW.WriteShortString(blockListUrl.AbsoluteUri);
  3418. bW.Write(_blockListLastUpdatedOn);
  3419. bW.Write(_blockListUpdateIntervalHours);
  3420. }
  3421. {
  3422. bW.Write(Convert.ToByte(_dnsServer.LocalEndPoints.Count));
  3423. foreach (IPEndPoint localEP in _dnsServer.LocalEndPoints)
  3424. localEP.WriteTo(bW);
  3425. }
  3426. bW.Write(_dnsServer.EnableDnsOverHttp);
  3427. bW.Write(_dnsServer.EnableDnsOverTls);
  3428. bW.Write(_dnsServer.EnableDnsOverHttps);
  3429. if (_dnsTlsCertificatePath == null)
  3430. bW.WriteShortString(string.Empty);
  3431. else
  3432. bW.WriteShortString(_dnsTlsCertificatePath);
  3433. if (_dnsTlsCertificatePassword == null)
  3434. bW.WriteShortString(string.Empty);
  3435. else
  3436. bW.WriteShortString(_dnsTlsCertificatePassword);
  3437. bW.Write(_dnsServer.CacheZoneManager.MinimumRecordTtl);
  3438. bW.Write(_dnsServer.CacheZoneManager.MaximumRecordTtl);
  3439. bW.Write(_dnsServer.CacheZoneManager.NegativeRecordTtl);
  3440. bW.Write(_dnsServer.CacheZoneManager.FailureRecordTtl);
  3441. if (_dnsServer.TsigKeys is null)
  3442. {
  3443. bW.Write((byte)0);
  3444. }
  3445. else
  3446. {
  3447. bW.Write(Convert.ToByte(_dnsServer.TsigKeys.Count));
  3448. foreach (KeyValuePair<string, TsigKey> tsigKey in _dnsServer.TsigKeys)
  3449. {
  3450. bW.WriteShortString(tsigKey.Key);
  3451. bW.WriteShortString(tsigKey.Value.SharedSecret);
  3452. bW.Write((byte)tsigKey.Value.Algorithm);
  3453. }
  3454. }
  3455. bW.Write(_dnsServer.NsRevalidation);
  3456. bW.Write(_dnsServer.AllowTxtBlockingReport);
  3457. bW.Write(_zonesApi.DefaultRecordTtl);
  3458. bW.Write(_webServiceUseSelfSignedTlsCertificate);
  3459. bW.Write(_dnsServer.UdpPayloadSize);
  3460. bW.Write(_dnsServer.DnssecValidation);
  3461. bW.Write(_dnsServer.ResolverRetries);
  3462. bW.Write(_dnsServer.ResolverTimeout);
  3463. bW.Write(_dnsServer.ResolverMaxStackCount);
  3464. bW.Write(_dnsServer.ForwarderRetries);
  3465. bW.Write(_dnsServer.ForwarderTimeout);
  3466. bW.Write(_dnsServer.ForwarderConcurrency);
  3467. bW.Write(_dnsServer.ClientTimeout);
  3468. bW.Write(_dnsServer.TcpSendTimeout);
  3469. bW.Write(_dnsServer.TcpReceiveTimeout);
  3470. //write config
  3471. mS.Position = 0;
  3472. using (FileStream fS = new FileStream(configFile, FileMode.Create, FileAccess.Write))
  3473. {
  3474. mS.CopyTo(fS);
  3475. }
  3476. }
  3477. _log.Write("DNS Server config file was saved: " + configFile);
  3478. }
  3479. #endregion
  3480. #region web service start stop
  3481. private void StartDnsWebService()
  3482. {
  3483. int acceptTasks = Math.Max(1, Environment.ProcessorCount);
  3484. //HTTP service
  3485. try
  3486. {
  3487. string webServiceHostname = null;
  3488. _webService = new HttpListener();
  3489. IPAddress httpAddress = null;
  3490. foreach (IPAddress webServiceLocalAddress in _webServiceLocalAddresses)
  3491. {
  3492. string host;
  3493. if (webServiceLocalAddress.Equals(IPAddress.Any))
  3494. {
  3495. host = "+";
  3496. httpAddress = IPAddress.Loopback;
  3497. }
  3498. else if (webServiceLocalAddress.Equals(IPAddress.IPv6Any))
  3499. {
  3500. host = "+";
  3501. if ((httpAddress == null) || !IPAddress.IsLoopback(httpAddress))
  3502. httpAddress = IPAddress.IPv6Loopback;
  3503. }
  3504. else
  3505. {
  3506. if (webServiceLocalAddress.AddressFamily == AddressFamily.InterNetworkV6)
  3507. host = "[" + webServiceLocalAddress.ToString() + "]";
  3508. else
  3509. host = webServiceLocalAddress.ToString();
  3510. if (httpAddress == null)
  3511. httpAddress = webServiceLocalAddress;
  3512. if (webServiceHostname == null)
  3513. webServiceHostname = host;
  3514. }
  3515. _webService.Prefixes.Add("http://" + host + ":" + _webServiceHttpPort + "/");
  3516. }
  3517. _webService.Start();
  3518. if (httpAddress == null)
  3519. httpAddress = IPAddress.Loopback;
  3520. _webServiceHttpEP = new IPEndPoint(httpAddress, _webServiceHttpPort);
  3521. _webServiceHostname = webServiceHostname ?? Environment.MachineName.ToLower();
  3522. }
  3523. catch (Exception ex)
  3524. {
  3525. _log.Write("Web Service failed to bind using default hostname. Attempting to bind again using 'localhost' hostname.\r\n" + ex.ToString());
  3526. try
  3527. {
  3528. _webService = new HttpListener();
  3529. _webService.Prefixes.Add("http://localhost:" + _webServiceHttpPort + "/");
  3530. _webService.Prefixes.Add("http://127.0.0.1:" + _webServiceHttpPort + "/");
  3531. _webService.Start();
  3532. }
  3533. catch
  3534. {
  3535. _webService = new HttpListener();
  3536. _webService.Prefixes.Add("http://localhost:" + _webServiceHttpPort + "/");
  3537. _webService.Start();
  3538. }
  3539. _webServiceHttpEP = new IPEndPoint(IPAddress.Loopback, _webServiceHttpPort);
  3540. _webServiceHostname = "localhost";
  3541. }
  3542. _webService.IgnoreWriteExceptions = true;
  3543. for (int i = 0; i < acceptTasks; i++)
  3544. {
  3545. _ = Task.Factory.StartNew(delegate ()
  3546. {
  3547. return AcceptWebRequestAsync();
  3548. }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, _webServiceTaskScheduler);
  3549. }
  3550. _log.Write(new IPEndPoint(IPAddress.Any, _webServiceHttpPort), "HTTP Web Service was started successfully.");
  3551. //TLS service
  3552. if (_webServiceEnableTls && (_webServiceTlsCertificate != null))
  3553. {
  3554. List<Socket> webServiceTlsListeners = new List<Socket>();
  3555. try
  3556. {
  3557. foreach (IPAddress webServiceLocalAddress in _webServiceLocalAddresses)
  3558. {
  3559. Socket tlsListener = new Socket(webServiceLocalAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  3560. tlsListener.Bind(new IPEndPoint(webServiceLocalAddress, _webServiceTlsPort));
  3561. tlsListener.Listen(10);
  3562. webServiceTlsListeners.Add(tlsListener);
  3563. }
  3564. foreach (Socket tlsListener in webServiceTlsListeners)
  3565. {
  3566. for (int i = 0; i < acceptTasks; i++)
  3567. {
  3568. _ = Task.Factory.StartNew(delegate ()
  3569. {
  3570. return AcceptTlsWebRequestAsync(tlsListener);
  3571. }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, _webServiceTaskScheduler);
  3572. }
  3573. }
  3574. _webServiceTlsListeners = webServiceTlsListeners;
  3575. _log.Write(new IPEndPoint(IPAddress.Any, _webServiceHttpPort), "TLS Web Service was started successfully.");
  3576. }
  3577. catch (Exception ex)
  3578. {
  3579. _log.Write("TLS Web Service failed to start.\r\n" + ex.ToString());
  3580. foreach (Socket tlsListener in webServiceTlsListeners)
  3581. tlsListener.Dispose();
  3582. }
  3583. }
  3584. }
  3585. private void StopDnsWebService()
  3586. {
  3587. _webService.Stop();
  3588. if (_webServiceTlsListeners != null)
  3589. {
  3590. foreach (Socket tlsListener in _webServiceTlsListeners)
  3591. tlsListener.Dispose();
  3592. _webServiceTlsListeners = null;
  3593. }
  3594. }
  3595. #endregion
  3596. #endregion
  3597. #region public
  3598. public void Start()
  3599. {
  3600. if (_disposed)
  3601. throw new ObjectDisposedException("WebService");
  3602. if (_state != ServiceState.Stopped)
  3603. throw new InvalidOperationException("Web Service is already running.");
  3604. _state = ServiceState.Starting;
  3605. try
  3606. {
  3607. //get initial server domain
  3608. string dnsServerDomain = Environment.MachineName.ToLower();
  3609. if (!DnsClient.IsDomainNameValid(dnsServerDomain))
  3610. dnsServerDomain = "dns-server-1"; //use this name instead since machine name is not a valid domain name
  3611. //init dns server
  3612. _dnsServer = new DnsServer(dnsServerDomain, _configFolder, Path.Combine(_appFolder, "dohwww"), _log);
  3613. //init dhcp server
  3614. _dhcpServer = new DhcpServer(Path.Combine(_configFolder, "scopes"), _log);
  3615. _dhcpServer.AuthZoneManager = _dnsServer.AuthZoneManager;
  3616. //load config
  3617. LoadConfigFile();
  3618. //load all dns applications
  3619. _dnsServer.DnsApplicationManager.LoadAllApplications();
  3620. //load all zones files
  3621. _dnsServer.AuthZoneManager.LoadAllZoneFiles();
  3622. //disable zones from old config format
  3623. if (_configDisabledZones != null)
  3624. {
  3625. foreach (string domain in _configDisabledZones)
  3626. {
  3627. AuthZoneInfo zoneInfo = _dnsServer.AuthZoneManager.GetAuthZoneInfo(domain);
  3628. if (zoneInfo is not null)
  3629. {
  3630. zoneInfo.Disabled = true;
  3631. _dnsServer.AuthZoneManager.SaveZoneFile(zoneInfo.Name);
  3632. }
  3633. }
  3634. }
  3635. //load allowed zone and blocked zone
  3636. _dnsServer.AllowedZoneManager.LoadAllowedZoneFile();
  3637. _dnsServer.BlockedZoneManager.LoadBlockedZoneFile();
  3638. //load block list zone async
  3639. if (_dnsServer.BlockListZoneManager.BlockListUrls.Count > 0)
  3640. {
  3641. ThreadPool.QueueUserWorkItem(delegate (object state)
  3642. {
  3643. try
  3644. {
  3645. _dnsServer.BlockListZoneManager.LoadBlockLists();
  3646. StartBlockListUpdateTimer();
  3647. }
  3648. catch (Exception ex)
  3649. {
  3650. _log.Write(ex);
  3651. }
  3652. });
  3653. }
  3654. //start dns and dhcp
  3655. _dnsServer.Start();
  3656. _dhcpServer.Start();
  3657. //start web service
  3658. StartDnsWebService();
  3659. _state = ServiceState.Running;
  3660. _log.Write("DNS Server (v" + _currentVersion.ToString() + ") was started successfully.");
  3661. }
  3662. catch (Exception ex)
  3663. {
  3664. _log.Write("Failed to start DNS Server (v" + _currentVersion.ToString() + ")\r\n" + ex.ToString());
  3665. throw;
  3666. }
  3667. }
  3668. public void Stop()
  3669. {
  3670. if (_state != ServiceState.Running)
  3671. return;
  3672. _state = ServiceState.Stopping;
  3673. try
  3674. {
  3675. StopDnsWebService();
  3676. _dnsServer.Dispose();
  3677. _dhcpServer.Dispose();
  3678. StopBlockListUpdateTimer();
  3679. StopTlsCertificateUpdateTimer();
  3680. if (_temporaryDisableBlockingTimer is not null)
  3681. _temporaryDisableBlockingTimer.Dispose();
  3682. _state = ServiceState.Stopped;
  3683. _log.Write("DNS Server (v" + _currentVersion.ToString() + ") was stopped successfully.");
  3684. }
  3685. catch (Exception ex)
  3686. {
  3687. _log.Write("Failed to stop DNS Server (v" + _currentVersion.ToString() + ")\r\n" + ex.ToString());
  3688. throw;
  3689. }
  3690. }
  3691. #endregion
  3692. #region properties
  3693. internal LogManager Log
  3694. { get { return _log; } }
  3695. internal DnsServer DnsServer
  3696. { get { return _dnsServer; } }
  3697. internal DhcpServer DhcpServer
  3698. { get { return _dhcpServer; } }
  3699. public string ConfigFolder
  3700. { get { return _configFolder; } }
  3701. public int WebServiceHttpPort
  3702. { get { return _webServiceHttpPort; } }
  3703. public int WebServiceTlsPort
  3704. { get { return _webServiceTlsPort; } }
  3705. public string WebServiceHostname
  3706. { get { return _webServiceHostname; } }
  3707. #endregion
  3708. }
  3709. }