123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452 |
- /*
- Technitium DNS Server
- Copyright (C) 2024 Shreyas Zare (shreyas@technitium.com)
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- using DnsServerCore.Auth;
- using DnsServerCore.Dns.Dnssec;
- using DnsServerCore.Dns.ResourceRecords;
- using DnsServerCore.Dns.Zones;
- using Microsoft.AspNetCore.Http;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Net;
- using System.Text;
- using System.Text.Json;
- using System.Threading.Tasks;
- using TechnitiumLibrary;
- using TechnitiumLibrary.Net;
- using TechnitiumLibrary.Net.Dns;
- using TechnitiumLibrary.Net.Dns.ResourceRecords;
- namespace DnsServerCore
- {
- class WebServiceZonesApi
- {
- #region variables
- static readonly char[] _commaSeparator = new char[] { ',' };
- static readonly char[] _pipeSeparator = new char[] { '|' };
- static readonly char[] _commaSpaceSeparator = new char[] { ',', ' ' };
- static readonly char[] _newLineSeparator = new char[] { '\r', '\n' };
- readonly DnsWebService _dnsWebService;
- uint _defaultRecordTtl = 3600;
- #endregion
- #region constructor
- public WebServiceZonesApi(DnsWebService dnsWebService)
- {
- _dnsWebService = dnsWebService;
- }
- #endregion
- #region static
- public static void WriteRecordsAsJson(List<DnsResourceRecord> records, Utf8JsonWriter jsonWriter, bool authoritativeZoneRecords, AuthZoneInfo zoneInfo = null)
- {
- if (records is null)
- {
- jsonWriter.WritePropertyName("records");
- jsonWriter.WriteStartArray();
- jsonWriter.WriteEndArray();
- return;
- }
- records.Sort();
- Dictionary<string, Dictionary<DnsResourceRecordType, List<DnsResourceRecord>>> groupedByDomainRecords = DnsResourceRecord.GroupRecords(records);
- jsonWriter.WritePropertyName("records");
- jsonWriter.WriteStartArray();
- foreach (KeyValuePair<string, Dictionary<DnsResourceRecordType, List<DnsResourceRecord>>> groupedByTypeRecords in groupedByDomainRecords)
- {
- foreach (KeyValuePair<DnsResourceRecordType, List<DnsResourceRecord>> groupedRecords in groupedByTypeRecords.Value)
- {
- foreach (DnsResourceRecord record in groupedRecords.Value)
- WriteRecordAsJson(record, jsonWriter, authoritativeZoneRecords, zoneInfo);
- }
- }
- jsonWriter.WriteEndArray();
- }
- #endregion
- #region private
- private static void WriteRecordAsJson(DnsResourceRecord record, Utf8JsonWriter jsonWriter, bool authoritativeZoneRecords, AuthZoneInfo zoneInfo = null)
- {
- jsonWriter.WriteStartObject();
- jsonWriter.WriteString("name", record.Name);
- if (DnsClient.TryConvertDomainNameToUnicode(record.Name, out string idn))
- jsonWriter.WriteString("nameIdn", idn);
- jsonWriter.WriteString("type", record.Type.ToString());
- if (authoritativeZoneRecords)
- {
- GenericRecordInfo authRecordInfo = record.GetAuthGenericRecordInfo();
- jsonWriter.WriteNumber("ttl", record.TTL);
- jsonWriter.WriteBoolean("disabled", authRecordInfo.Disabled);
- string comments = authRecordInfo.Comments;
- if (!string.IsNullOrEmpty(comments))
- jsonWriter.WriteString("comments", comments);
- }
- else
- {
- if (record.IsStale)
- jsonWriter.WriteString("ttl", "0 (0 sec)");
- else
- jsonWriter.WriteString("ttl", record.TTL + " (" + WebUtilities.GetFormattedTime((int)record.TTL) + ")");
- }
- jsonWriter.WritePropertyName("rData");
- jsonWriter.WriteStartObject();
- switch (record.Type)
- {
- case DnsResourceRecordType.A:
- {
- if (record.RDATA is DnsARecordData rdata)
- {
- jsonWriter.WriteString("ipAddress", rdata.Address.ToString());
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.NS:
- {
- if (record.RDATA is DnsNSRecordData rdata)
- {
- jsonWriter.WriteString("nameServer", rdata.NameServer.Length == 0 ? "." : rdata.NameServer);
- if (DnsClient.TryConvertDomainNameToUnicode(rdata.NameServer, out string nameServerIdn))
- jsonWriter.WriteString("nameServerIdn", nameServerIdn);
- if (!authoritativeZoneRecords)
- {
- if (rdata.IsParentSideTtlSet)
- jsonWriter.WriteString("parentSideTtl", rdata.ParentSideTtl + " (" + WebUtilities.GetFormattedTime((int)rdata.ParentSideTtl) + ")");
- }
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.CNAME:
- {
- if (record.RDATA is DnsCNAMERecordData rdata)
- {
- jsonWriter.WriteString("cname", rdata.Domain.Length == 0 ? "." : rdata.Domain);
- if (DnsClient.TryConvertDomainNameToUnicode(rdata.Domain, out string cnameIdn))
- jsonWriter.WriteString("cnameIdn", cnameIdn);
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.SOA:
- {
- if (record.RDATA is DnsSOARecordData rdata)
- {
- jsonWriter.WriteString("primaryNameServer", rdata.PrimaryNameServer);
- if (DnsClient.TryConvertDomainNameToUnicode(rdata.PrimaryNameServer, out string primaryNameServerIdn))
- jsonWriter.WriteString("primaryNameServerIdn", primaryNameServerIdn);
- jsonWriter.WriteString("responsiblePerson", rdata.ResponsiblePerson);
- jsonWriter.WriteNumber("serial", rdata.Serial);
- jsonWriter.WriteNumber("refresh", rdata.Refresh);
- jsonWriter.WriteNumber("retry", rdata.Retry);
- jsonWriter.WriteNumber("expire", rdata.Expire);
- jsonWriter.WriteNumber("minimum", rdata.Minimum);
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- if (authoritativeZoneRecords && (zoneInfo is not null))
- {
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Forwarder:
- case AuthZoneType.Catalog:
- jsonWriter.WriteBoolean("useSerialDateScheme", record.GetAuthSOARecordInfo().UseSoaSerialDateScheme);
- break;
- }
- }
- }
- break;
- case DnsResourceRecordType.PTR:
- {
- if (record.RDATA is DnsPTRRecordData rdata)
- {
- jsonWriter.WriteString("ptrName", rdata.Domain.Length == 0 ? "." : rdata.Domain);
- if (DnsClient.TryConvertDomainNameToUnicode(rdata.Domain, out string ptrNameIdn))
- jsonWriter.WriteString("ptrNameIdn", ptrNameIdn);
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.MX:
- {
- if (record.RDATA is DnsMXRecordData rdata)
- {
- jsonWriter.WriteNumber("preference", rdata.Preference);
- jsonWriter.WriteString("exchange", rdata.Exchange.Length == 0 ? "." : rdata.Exchange);
- if (DnsClient.TryConvertDomainNameToUnicode(rdata.Exchange, out string exchangeIdn))
- jsonWriter.WriteString("exchangeIdn", exchangeIdn);
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.TXT:
- {
- if (record.RDATA is DnsTXTRecordData rdata)
- {
- jsonWriter.WriteString("text", rdata.GetText());
- jsonWriter.WriteBoolean("splitText", rdata.CharacterStrings.Count > 1);
- jsonWriter.WriteStartArray("characterStrings");
- foreach (string characterString in rdata.CharacterStrings)
- jsonWriter.WriteStringValue(characterString);
- jsonWriter.WriteEndArray();
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.RP:
- {
- if (record.RDATA is DnsRPRecordData rdata)
- {
- jsonWriter.WriteString("mailbox", rdata.Mailbox);
- jsonWriter.WriteString("txtDomain", rdata.TxtDomain);
- if (DnsClient.TryConvertDomainNameToUnicode(rdata.Mailbox, out string txtDomainIdn))
- jsonWriter.WriteString("txtDomainIdn", txtDomainIdn);
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.AAAA:
- {
- if (record.RDATA is DnsAAAARecordData rdata)
- {
- jsonWriter.WriteString("ipAddress", rdata.Address.ToString());
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.SRV:
- {
- if (record.RDATA is DnsSRVRecordData rdata)
- {
- jsonWriter.WriteNumber("priority", rdata.Priority);
- jsonWriter.WriteNumber("weight", rdata.Weight);
- jsonWriter.WriteNumber("port", rdata.Port);
- jsonWriter.WriteString("target", rdata.Target.Length == 0 ? "." : rdata.Target);
- if (DnsClient.TryConvertDomainNameToUnicode(rdata.Target, out string targetIdn))
- jsonWriter.WriteString("targetIdn", targetIdn);
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.NAPTR:
- {
- if (record.RDATA is DnsNAPTRRecordData rdata)
- {
- jsonWriter.WriteNumber("order", rdata.Order);
- jsonWriter.WriteNumber("preference", rdata.Preference);
- jsonWriter.WriteString("flags", rdata.Flags);
- jsonWriter.WriteString("services", rdata.Services);
- jsonWriter.WriteString("regexp", rdata.Regexp);
- jsonWriter.WriteString("replacement", rdata.Replacement.Length == 0 ? "." : rdata.Replacement);
- if (DnsClient.TryConvertDomainNameToUnicode(rdata.Replacement, out string replacementIdn))
- jsonWriter.WriteString("replacementIdn", replacementIdn);
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.DNAME:
- {
- if (record.RDATA is DnsDNAMERecordData rdata)
- {
- jsonWriter.WriteString("dname", rdata.Domain.Length == 0 ? "." : rdata.Domain);
- if (DnsClient.TryConvertDomainNameToUnicode(rdata.Domain, out string dnameIdn))
- jsonWriter.WriteString("dnameIdn", dnameIdn);
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.APL:
- {
- if (record.RDATA is DnsAPLRecordData rdata)
- {
- jsonWriter.WriteStartArray("addressPrefixes");
- foreach (DnsAPLRecordData.APItem apItem in rdata.APItems)
- {
- jsonWriter.WriteStartObject();
- jsonWriter.WriteString("addressFamily", apItem.AddressFamily.ToString());
- jsonWriter.WriteNumber("prefix", apItem.Prefix);
- jsonWriter.WriteBoolean("negation", apItem.Negation);
- jsonWriter.WriteString("afdPart", apItem.NetworkAddress.Address.ToString());
- jsonWriter.WriteEndObject();
- }
- jsonWriter.WriteEndArray();
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.DS:
- {
- if (record.RDATA is DnsDSRecordData rdata)
- {
- jsonWriter.WriteNumber("keyTag", rdata.KeyTag);
- jsonWriter.WriteString("algorithm", rdata.Algorithm.ToString());
- jsonWriter.WriteString("digestType", rdata.DigestType.ToString());
- jsonWriter.WriteString("digest", Convert.ToHexString(rdata.Digest));
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.SSHFP:
- {
- if (record.RDATA is DnsSSHFPRecordData rdata)
- {
- jsonWriter.WriteString("algorithm", rdata.Algorithm.ToString());
- jsonWriter.WriteString("fingerprintType", rdata.FingerprintType.ToString());
- jsonWriter.WriteString("fingerprint", Convert.ToHexString(rdata.Fingerprint));
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.RRSIG:
- {
- if (record.RDATA is DnsRRSIGRecordData rdata)
- {
- jsonWriter.WriteString("typeCovered", rdata.TypeCovered.ToString());
- jsonWriter.WriteString("algorithm", rdata.Algorithm.ToString());
- jsonWriter.WriteNumber("labels", rdata.Labels);
- jsonWriter.WriteNumber("originalTtl", rdata.OriginalTtl);
- jsonWriter.WriteString("signatureExpiration", DateTime.UnixEpoch.AddSeconds(rdata.SignatureExpiration));
- jsonWriter.WriteString("signatureInception", DateTime.UnixEpoch.AddSeconds(rdata.SignatureInception));
- jsonWriter.WriteNumber("keyTag", rdata.KeyTag);
- jsonWriter.WriteString("signersName", rdata.SignersName.Length == 0 ? "." : rdata.SignersName);
- jsonWriter.WriteString("signature", Convert.ToBase64String(rdata.Signature));
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.NSEC:
- {
- if (record.RDATA is DnsNSECRecordData rdata)
- {
- jsonWriter.WriteString("nextDomainName", rdata.NextDomainName);
- jsonWriter.WritePropertyName("types");
- jsonWriter.WriteStartArray();
- foreach (DnsResourceRecordType type in rdata.Types)
- jsonWriter.WriteStringValue(type.ToString());
- jsonWriter.WriteEndArray();
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.DNSKEY:
- {
- if (record.RDATA is DnsDNSKEYRecordData rdata)
- {
- jsonWriter.WriteString("flags", rdata.Flags.ToString());
- jsonWriter.WriteNumber("protocol", rdata.Protocol);
- jsonWriter.WriteString("algorithm", rdata.Algorithm.ToString());
- jsonWriter.WriteString("publicKey", rdata.PublicKey.ToString());
- jsonWriter.WriteNumber("computedKeyTag", rdata.ComputedKeyTag);
- if (authoritativeZoneRecords)
- {
- if ((zoneInfo is not null) && (zoneInfo.Type == AuthZoneType.Primary))
- {
- IReadOnlyCollection<DnssecPrivateKey> dnssecPrivateKeys = zoneInfo.DnssecPrivateKeys;
- if (dnssecPrivateKeys is not null)
- {
- foreach (DnssecPrivateKey dnssecPrivateKey in dnssecPrivateKeys)
- {
- if (dnssecPrivateKey.KeyTag == rdata.ComputedKeyTag)
- {
- jsonWriter.WriteString("dnsKeyState", dnssecPrivateKey.State.ToString());
- if ((dnssecPrivateKey.KeyType == DnssecPrivateKeyType.KeySigningKey) && (dnssecPrivateKey.State == DnssecPrivateKeyState.Published))
- jsonWriter.WriteString("dnsKeyStateReadyBy", (zoneInfo.ApexZone as PrimaryZone).GetKskDnsKeyStateReadyBy(dnssecPrivateKey));
- break;
- }
- }
- }
- }
- if (rdata.Flags.HasFlag(DnsDnsKeyFlag.SecureEntryPoint))
- {
- jsonWriter.WritePropertyName("computedDigests");
- jsonWriter.WriteStartArray();
- {
- jsonWriter.WriteStartObject();
- jsonWriter.WriteString("digestType", "SHA256");
- jsonWriter.WriteString("digest", Convert.ToHexString(rdata.CreateDS(record.Name, DnssecDigestType.SHA256).Digest));
- jsonWriter.WriteEndObject();
- }
- {
- jsonWriter.WriteStartObject();
- jsonWriter.WriteString("digestType", "SHA384");
- jsonWriter.WriteString("digest", Convert.ToHexString(rdata.CreateDS(record.Name, DnssecDigestType.SHA384).Digest));
- jsonWriter.WriteEndObject();
- }
- jsonWriter.WriteEndArray();
- }
- }
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.NSEC3:
- {
- if (record.RDATA is DnsNSEC3RecordData rdata)
- {
- jsonWriter.WriteString("hashAlgorithm", rdata.HashAlgorithm.ToString());
- jsonWriter.WriteString("flags", rdata.Flags.ToString());
- jsonWriter.WriteNumber("iterations", rdata.Iterations);
- jsonWriter.WriteString("salt", Convert.ToHexString(rdata.Salt));
- jsonWriter.WriteString("nextHashedOwnerName", rdata.NextHashedOwnerName);
- jsonWriter.WritePropertyName("types");
- jsonWriter.WriteStartArray();
- foreach (DnsResourceRecordType type in rdata.Types)
- jsonWriter.WriteStringValue(type.ToString());
- jsonWriter.WriteEndArray();
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.NSEC3PARAM:
- {
- if (record.RDATA is DnsNSEC3PARAMRecordData rdata)
- {
- jsonWriter.WriteString("hashAlgorithm", rdata.HashAlgorithm.ToString());
- jsonWriter.WriteString("flags", rdata.Flags.ToString());
- jsonWriter.WriteNumber("iterations", rdata.Iterations);
- jsonWriter.WriteString("salt", Convert.ToHexString(rdata.Salt));
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.TLSA:
- {
- if (record.RDATA is DnsTLSARecordData rdata)
- {
- jsonWriter.WriteString("certificateUsage", rdata.CertificateUsage.ToString().Replace('_', '-'));
- jsonWriter.WriteString("selector", rdata.Selector.ToString());
- jsonWriter.WriteString("matchingType", rdata.MatchingType.ToString().Replace('_', '-'));
- jsonWriter.WriteString("certificateAssociationData", Convert.ToHexString(rdata.CertificateAssociationData));
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.ZONEMD:
- {
- if (record.RDATA is DnsZONEMDRecordData rdata)
- {
- jsonWriter.WriteNumber("serial", rdata.Serial);
- jsonWriter.WriteString("scheme", rdata.Scheme.ToString());
- jsonWriter.WriteString("hashAlgorithm", rdata.HashAlgorithm.ToString());
- jsonWriter.WriteString("digest", Convert.ToHexString(rdata.Digest));
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.SVCB:
- case DnsResourceRecordType.HTTPS:
- {
- if (record.RDATA is DnsSVCBRecordData rdata)
- {
- jsonWriter.WriteNumber("svcPriority", rdata.SvcPriority);
- jsonWriter.WriteString("svcTargetName", rdata.TargetName);
- jsonWriter.WritePropertyName("svcParams");
- jsonWriter.WriteStartObject();
- foreach (KeyValuePair<DnsSvcParamKey, DnsSvcParamValue> svcParam in rdata.SvcParams)
- jsonWriter.WriteString(svcParam.Key.ToString().ToLowerInvariant().Replace('_', '-'), svcParam.Value.ToString());
- jsonWriter.WriteEndObject();
- if (authoritativeZoneRecords)
- {
- SVCBRecordInfo rrInfo = record.GetAuthSVCBRecordInfo();
- jsonWriter.WriteBoolean("autoIpv4Hint", rrInfo.AutoIpv4Hint);
- jsonWriter.WriteBoolean("autoIpv6Hint", rrInfo.AutoIpv6Hint);
- }
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.URI:
- {
- if (record.RDATA is DnsURIRecordData rdata)
- {
- jsonWriter.WriteNumber("priority", rdata.Priority);
- jsonWriter.WriteNumber("weight", rdata.Weight);
- jsonWriter.WriteString("uri", rdata.Uri.AbsoluteUri);
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.CAA:
- {
- if (record.RDATA is DnsCAARecordData rdata)
- {
- jsonWriter.WriteNumber("flags", rdata.Flags);
- jsonWriter.WriteString("tag", rdata.Tag);
- jsonWriter.WriteString("value", rdata.Value);
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.ANAME:
- {
- if (record.RDATA is DnsANAMERecordData rdata)
- {
- jsonWriter.WriteString("aname", rdata.Domain.Length == 0 ? "." : rdata.Domain);
- if (DnsClient.TryConvertDomainNameToUnicode(rdata.Domain, out string anameIdn))
- jsonWriter.WriteString("anameIdn", anameIdn);
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- case DnsResourceRecordType.FWD:
- {
- if (record.RDATA is DnsForwarderRecordData rdata)
- {
- jsonWriter.WriteString("protocol", rdata.Protocol.ToString());
- jsonWriter.WriteString("forwarder", rdata.Forwarder);
- jsonWriter.WriteNumber("priority", rdata.Priority);
- jsonWriter.WriteBoolean("dnssecValidation", rdata.DnssecValidation);
- jsonWriter.WriteString("proxyType", rdata.ProxyType.ToString());
- switch (rdata.ProxyType)
- {
- case DnsForwarderRecordProxyType.Http:
- case DnsForwarderRecordProxyType.Socks5:
- jsonWriter.WriteString("proxyAddress", rdata.ProxyAddress);
- jsonWriter.WriteNumber("proxyPort", rdata.ProxyPort);
- jsonWriter.WriteString("proxyUsername", rdata.ProxyUsername);
- jsonWriter.WriteString("proxyPassword", rdata.ProxyPassword);
- break;
- }
- }
- }
- break;
- case DnsResourceRecordType.APP:
- {
- if (record.RDATA is DnsApplicationRecordData rdata)
- {
- jsonWriter.WriteString("appName", rdata.AppName);
- jsonWriter.WriteString("classPath", rdata.ClassPath);
- jsonWriter.WriteString("data", rdata.Data);
- }
- }
- break;
- case DnsResourceRecordType.ALIAS:
- {
- if (record.RDATA is DnsALIASRecordData rdata)
- {
- jsonWriter.WriteString("type", rdata.Type.ToString());
- jsonWriter.WriteString("alias", rdata.Domain.Length == 0 ? "." : rdata.Domain);
- if (DnsClient.TryConvertDomainNameToUnicode(rdata.Domain, out string aliasIdn))
- jsonWriter.WriteString("aliasIdn", aliasIdn);
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- default:
- {
- if (record.RDATA is DnsUnknownRecordData rdata)
- {
- jsonWriter.WriteString("value", BitConverter.ToString(rdata.DATA).Replace('-', ':'));
- }
- else
- {
- jsonWriter.WriteString("dataType", record.RDATA.GetType().Name);
- jsonWriter.WriteString("data", record.RDATA.ToString());
- }
- }
- break;
- }
- jsonWriter.WriteEndObject();
- jsonWriter.WriteString("dnssecStatus", record.DnssecStatus.ToString());
- if (authoritativeZoneRecords)
- {
- GenericRecordInfo authRecordInfo = record.GetAuthGenericRecordInfo();
- if (authRecordInfo is NSRecordInfo nsRecordInfo)
- {
- IReadOnlyList<DnsResourceRecord> glueRecords = nsRecordInfo.GlueRecords;
- if (glueRecords is not null)
- {
- jsonWriter.WritePropertyName("glueRecords");
- jsonWriter.WriteStartArray();
- foreach (DnsResourceRecord glueRecord in glueRecords)
- jsonWriter.WriteStringValue(glueRecord.RDATA.ToString());
- jsonWriter.WriteEndArray();
- }
- }
- jsonWriter.WriteString("lastUsedOn", authRecordInfo.LastUsedOn);
- jsonWriter.WriteString("lastModified", authRecordInfo.LastModified);
- jsonWriter.WriteNumber("expiryTtl", authRecordInfo.ExpiryTtl);
- }
- else
- {
- CacheRecordInfo cacheRecordInfo = record.GetCacheRecordInfo();
- IReadOnlyList<DnsResourceRecord> glueRecords = cacheRecordInfo.GlueRecords;
- if (glueRecords is not null)
- {
- jsonWriter.WritePropertyName("glueRecords");
- jsonWriter.WriteStartArray();
- foreach (DnsResourceRecord glueRecord in glueRecords)
- jsonWriter.WriteStringValue(glueRecord.RDATA.ToString());
- jsonWriter.WriteEndArray();
- }
- IReadOnlyList<DnsResourceRecord> rrsigRecords = cacheRecordInfo.RRSIGRecords;
- IReadOnlyList<DnsResourceRecord> nsecRecords = cacheRecordInfo.NSECRecords;
- if ((rrsigRecords is not null) || (nsecRecords is not null))
- {
- jsonWriter.WritePropertyName("dnssecRecords");
- jsonWriter.WriteStartArray();
- if (rrsigRecords is not null)
- {
- foreach (DnsResourceRecord rrsigRecord in rrsigRecords)
- jsonWriter.WriteStringValue(rrsigRecord.ToString());
- }
- if (nsecRecords is not null)
- {
- foreach (DnsResourceRecord nsecRecord in nsecRecords)
- jsonWriter.WriteStringValue(nsecRecord.ToString());
- }
- jsonWriter.WriteEndArray();
- }
- NetworkAddress eDnsClientSubnet = cacheRecordInfo.EDnsClientSubnet;
- if (eDnsClientSubnet is not null)
- jsonWriter.WriteString("eDnsClientSubnet", eDnsClientSubnet.ToString());
- if (record.RDATA is DnsNSRecordData nsRData)
- {
- NameServerMetadata metadata = nsRData.Metadata;
- jsonWriter.WriteStartObject("nameServerMetadata");
- jsonWriter.WriteNumber("totalQueries", metadata.TotalQueries);
- jsonWriter.WriteString("answerRate", Math.Round(metadata.GetAnswerRate(), 2) + "%");
- jsonWriter.WriteString("smoothedRoundTripTime", Math.Round(metadata.SRTT, 2) + " ms");
- jsonWriter.WriteString("smoothedPenaltyRoundTripTime", Math.Round(metadata.SPRTT, 2) + " ms");
- jsonWriter.WriteString("netRoundTripTime", Math.Round(metadata.GetNetRTT(), 2) + " ms");
- jsonWriter.WriteEndObject();
- }
- DnsDatagramMetadata responseMetadata = cacheRecordInfo.ResponseMetadata;
- if (responseMetadata is not null)
- {
- jsonWriter.WritePropertyName("responseMetadata");
- jsonWriter.WriteStartObject();
- jsonWriter.WriteString("nameServer", responseMetadata.NameServer?.ToString());
- jsonWriter.WriteString("protocol", (responseMetadata.NameServer is null ? DnsTransportProtocol.Udp : responseMetadata.NameServer.Protocol).ToString());
- jsonWriter.WriteString("datagramSize", responseMetadata.DatagramSize + " bytes");
- jsonWriter.WriteString("roundTripTime", Math.Round(responseMetadata.RoundTripTime, 2) + " ms");
- jsonWriter.WriteEndObject();
- }
- jsonWriter.WriteString("lastUsedOn", cacheRecordInfo.LastUsedOn);
- }
- jsonWriter.WriteEndObject();
- }
- private static void WriteZoneInfoAsJson(AuthZoneInfo zoneInfo, Utf8JsonWriter jsonWriter)
- {
- jsonWriter.WriteStartObject();
- jsonWriter.WriteString("name", zoneInfo.Name);
- if (DnsClient.TryConvertDomainNameToUnicode(zoneInfo.Name, out string nameIdn))
- jsonWriter.WriteString("nameIdn", nameIdn);
- jsonWriter.WriteString("type", zoneInfo.Type.ToString());
- jsonWriter.WriteString("lastModified", zoneInfo.LastModified);
- jsonWriter.WriteBoolean("disabled", zoneInfo.Disabled);
- jsonWriter.WriteNumber("soaSerial", zoneInfo.ApexZone.GetZoneSoaSerial());
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- jsonWriter.WriteBoolean("internal", zoneInfo.Internal);
- break;
- }
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Secondary:
- case AuthZoneType.Stub:
- case AuthZoneType.Forwarder:
- case AuthZoneType.SecondaryForwarder:
- jsonWriter.WriteString("catalog", zoneInfo.CatalogZoneName);
- break;
- }
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Secondary:
- jsonWriter.WriteString("dnssecStatus", zoneInfo.ApexZone.DnssecStatus.ToString());
- break;
- }
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Secondary:
- jsonWriter.WriteBoolean("validationFailed", zoneInfo.ValidationFailed);
- break;
- }
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Secondary:
- case AuthZoneType.Stub:
- case AuthZoneType.SecondaryForwarder:
- case AuthZoneType.SecondaryCatalog:
- jsonWriter.WriteString("expiry", zoneInfo.Expiry);
- jsonWriter.WriteBoolean("isExpired", zoneInfo.IsExpired);
- jsonWriter.WriteBoolean("syncFailed", zoneInfo.SyncFailed);
- break;
- }
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Secondary:
- case AuthZoneType.Forwarder:
- case AuthZoneType.Catalog:
- if (!zoneInfo.Internal)
- {
- string[] notifyFailed = zoneInfo.NotifyFailed;
- jsonWriter.WriteBoolean("notifyFailed", notifyFailed.Length > 0);
- jsonWriter.WritePropertyName("notifyFailedFor");
- jsonWriter.WriteStartArray();
- foreach (string server in notifyFailed)
- jsonWriter.WriteStringValue(server);
- jsonWriter.WriteEndArray();
- }
- break;
- }
- jsonWriter.WriteEndObject();
- }
- private static string[] DecodeCharacterStrings(string text)
- {
- string[] characterStrings = text.Split(_newLineSeparator, StringSplitOptions.RemoveEmptyEntries);
- for (int i = 0; i < characterStrings.Length; i++)
- characterStrings[i] = Unescape(characterStrings[i]);
- return characterStrings;
- }
- private static string Unescape(string text)
- {
- StringBuilder sb = new StringBuilder(text.Length);
- for (int i = 0, j; i < text.Length; i++)
- {
- char c = text[i];
- if (c == '\\')
- {
- j = i + 1;
- if (j == text.Length)
- {
- sb.Append(c);
- break;
- }
- char next = text[j];
- switch (next)
- {
- case 'n':
- sb.Append('\n');
- break;
- case 'r':
- sb.Append('\r');
- break;
- case 't':
- sb.Append('\t');
- break;
- case '\\':
- sb.Append('\\');
- break;
- default:
- sb.Append(c).Append(next);
- break;
- }
- i++;
- }
- else
- {
- sb.Append(c);
- }
- }
- return sb.ToString();
- }
- private static string GetSvcbTargetName(DnsResourceRecord svcbRecord)
- {
- DnsSVCBRecordData rData = svcbRecord.RDATA as DnsSVCBRecordData;
- if (rData.TargetName.Length > 0)
- return rData.TargetName;
- if (rData.SvcPriority == 0) //alias mode
- return null;
- //service mode
- return svcbRecord.Name;
- }
- private void ResolveSvcbAutoHints(string zoneName, DnsResourceRecord svcbRecord, bool resolveIpv4Hint, bool resolveIpv6Hint, Dictionary<DnsSvcParamKey, DnsSvcParamValue> svcParams, IReadOnlyCollection<DnsResourceRecord> importRecords = null)
- {
- string targetName = GetSvcbTargetName(svcbRecord);
- if (targetName is not null)
- ResolveSvcbAutoHints(zoneName, targetName, resolveIpv4Hint, resolveIpv6Hint, svcParams, importRecords);
- }
- private void ResolveSvcbAutoHints(string zoneName, string targetName, bool resolveIpv4Hint, bool resolveIpv6Hint, Dictionary<DnsSvcParamKey, DnsSvcParamValue> svcParams, IReadOnlyCollection<DnsResourceRecord> importRecords = null)
- {
- if (resolveIpv4Hint)
- {
- List<IPAddress> ipv4Hint = new List<IPAddress>();
- IReadOnlyList<DnsResourceRecord> records = _dnsWebService.DnsServer.AuthZoneManager.GetRecords(zoneName, targetName, DnsResourceRecordType.A);
- foreach (DnsResourceRecord record in records)
- {
- if (record.GetAuthGenericRecordInfo().Disabled)
- continue;
- ipv4Hint.Add((record.RDATA as DnsARecordData).Address);
- }
- if (importRecords is not null)
- {
- foreach (DnsResourceRecord record in importRecords)
- {
- if (record.Type != DnsResourceRecordType.A)
- continue;
- if (record.Name.Equals(targetName, StringComparison.OrdinalIgnoreCase))
- {
- IPAddress address = (record.RDATA as DnsARecordData).Address;
- if (!ipv4Hint.Contains(address))
- ipv4Hint.Add(address);
- }
- }
- }
- if (ipv4Hint.Count > 0)
- svcParams[DnsSvcParamKey.IPv4Hint] = new DnsSvcIPv4HintParamValue(ipv4Hint);
- else
- svcParams.Remove(DnsSvcParamKey.IPv4Hint);
- }
- if (resolveIpv6Hint)
- {
- List<IPAddress> ipv6Hint = new List<IPAddress>();
- IReadOnlyList<DnsResourceRecord> records = _dnsWebService.DnsServer.AuthZoneManager.GetRecords(zoneName, targetName, DnsResourceRecordType.AAAA);
- foreach (DnsResourceRecord record in records)
- {
- if (record.GetAuthGenericRecordInfo().Disabled)
- continue;
- ipv6Hint.Add((record.RDATA as DnsAAAARecordData).Address);
- }
- if (importRecords is not null)
- {
- foreach (DnsResourceRecord record in importRecords)
- {
- if (record.Type != DnsResourceRecordType.AAAA)
- continue;
- if (record.Name.Equals(targetName, StringComparison.OrdinalIgnoreCase))
- {
- IPAddress address = (record.RDATA as DnsAAAARecordData).Address;
- if (!ipv6Hint.Contains(address))
- ipv6Hint.Add(address);
- }
- }
- }
- if (ipv6Hint.Count > 0)
- svcParams[DnsSvcParamKey.IPv6Hint] = new DnsSvcIPv6HintParamValue(ipv6Hint);
- else
- svcParams.Remove(DnsSvcParamKey.IPv6Hint);
- }
- }
- private void UpdateSvcbAutoHints(string zoneName, string targetName, bool resolveIpv4Hint, bool resolveIpv6Hint)
- {
- List<DnsResourceRecord> allSvcbRecords = new List<DnsResourceRecord>();
- _dnsWebService.DnsServer.AuthZoneManager.ListAllZoneRecords(zoneName, [DnsResourceRecordType.SVCB, DnsResourceRecordType.HTTPS], allSvcbRecords);
- foreach (DnsResourceRecord record in allSvcbRecords)
- {
- SVCBRecordInfo info = record.GetAuthSVCBRecordInfo();
- if ((info.AutoIpv4Hint && resolveIpv4Hint) || (info.AutoIpv6Hint && resolveIpv6Hint))
- {
- string scvbTargetName = GetSvcbTargetName(record);
- if (targetName.Equals(scvbTargetName, StringComparison.OrdinalIgnoreCase))
- {
- DnsSVCBRecordData oldRData = record.RDATA as DnsSVCBRecordData;
- Dictionary<DnsSvcParamKey, DnsSvcParamValue> newSvcParams = new Dictionary<DnsSvcParamKey, DnsSvcParamValue>(oldRData.SvcParams);
- ResolveSvcbAutoHints(zoneName, targetName, resolveIpv4Hint, resolveIpv6Hint, newSvcParams);
- DnsSVCBRecordData newRData = new DnsSVCBRecordData(oldRData.SvcPriority, oldRData.TargetName, newSvcParams);
- DnsResourceRecord newRecord = new DnsResourceRecord(record.Name, record.Type, record.Class, record.TTL, newRData) { Tag = record.Tag };
- _dnsWebService.DnsServer.AuthZoneManager.UpdateRecord(zoneName, record, newRecord);
- }
- }
- }
- }
- #endregion
- #region public
- public void ListZones(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- IReadOnlyList<AuthZoneInfo> zoneInfoList = _dnsWebService.DnsServer.AuthZoneManager.GetZones(delegate (AuthZoneInfo zoneInfo)
- {
- return _dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.View);
- });
- if (request.TryGetQueryOrForm("pageNumber", int.Parse, out int pageNumber))
- {
- int zonesPerPage = request.GetQueryOrForm("zonesPerPage", int.Parse, 10);
- int totalPages;
- int totalZones = zoneInfoList.Count;
- if (totalZones > 0)
- {
- if (pageNumber == 0)
- pageNumber = 1;
- totalPages = (totalZones / zonesPerPage) + (totalZones % zonesPerPage > 0 ? 1 : 0);
- if ((pageNumber > totalPages) || (pageNumber < 0))
- pageNumber = totalPages;
- int start = (pageNumber - 1) * zonesPerPage;
- int end = Math.Min(start + zonesPerPage, totalZones);
- List<AuthZoneInfo> zoneInfoPageList = new List<AuthZoneInfo>(end - start);
- for (int i = start; i < end; i++)
- zoneInfoPageList.Add(zoneInfoList[i]);
- zoneInfoList = zoneInfoPageList;
- }
- else
- {
- pageNumber = 0;
- totalPages = 0;
- }
- jsonWriter.WriteNumber("pageNumber", pageNumber);
- jsonWriter.WriteNumber("totalPages", totalPages);
- jsonWriter.WriteNumber("totalZones", totalZones);
- }
- jsonWriter.WritePropertyName("zones");
- jsonWriter.WriteStartArray();
- foreach (AuthZoneInfo zoneInfo in zoneInfoList)
- WriteZoneInfoAsJson(zoneInfo, jsonWriter);
- jsonWriter.WriteEndArray();
- }
- public void ListCatalogZones(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- IReadOnlyList<AuthZoneInfo> catalogZoneInfoList = _dnsWebService.DnsServer.AuthZoneManager.GetCatalogZones(delegate (AuthZoneInfo catalogZoneInfo)
- {
- return !catalogZoneInfo.Disabled && _dnsWebService._authManager.IsPermitted(PermissionSection.Zones, catalogZoneInfo.Name, session.User, PermissionFlag.Modify);
- });
- jsonWriter.WritePropertyName("catalogZoneNames");
- jsonWriter.WriteStartArray();
- foreach (AuthZoneInfo catalogZoneInfo in catalogZoneInfoList)
- jsonWriter.WriteStringValue(catalogZoneInfo.Name);
- jsonWriter.WriteEndArray();
- }
- public async Task CreateZoneAsync(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string zoneName = request.GetQueryOrFormAlt("zone", "domain");
- if (zoneName.Contains('*'))
- throw new DnsWebServiceException("Domain name for a zone cannot contain wildcard character.");
- if (IPAddress.TryParse(zoneName, out IPAddress ipAddress))
- {
- zoneName = ipAddress.GetReverseDomain().ToLowerInvariant();
- }
- else if (zoneName.Contains('/'))
- {
- string[] parts = zoneName.Split('/');
- if ((parts.Length == 2) && IPAddress.TryParse(parts[0], out ipAddress) && int.TryParse(parts[1], out int subnetMaskWidth))
- zoneName = Zone.GetReverseZone(ipAddress, subnetMaskWidth);
- }
- else if (zoneName.EndsWith('.'))
- {
- zoneName = zoneName.Substring(0, zoneName.Length - 1);
- }
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- AuthZoneType type = request.GetQueryOrFormEnum("type", AuthZoneType.Primary);
- AuthZoneInfo zoneInfo;
- switch (type)
- {
- case AuthZoneType.Primary:
- {
- bool useSoaSerialDateScheme = request.GetQueryOrForm("useSoaSerialDateScheme", bool.Parse, _dnsWebService.DnsServer.AuthZoneManager.UseSoaSerialDateScheme);
- string catalogZoneName = request.GetQueryOrForm("catalog", null);
- AuthZoneInfo catalogZoneInfo = null;
- if (catalogZoneName is not null)
- {
- catalogZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(catalogZoneName);
- if (catalogZoneInfo is null)
- throw new DnsWebServiceException("No such Catalog zone was found: " + catalogZoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, catalogZoneInfo.Name, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied to use Catalog zone: " + catalogZoneInfo.Name);
- }
- zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.CreatePrimaryZone(zoneName, useSoaSerialDateScheme);
- if (zoneInfo is null)
- throw new DnsWebServiceException("Zone already exists: " + zoneName);
- //set permissions
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.DNS_ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SaveConfigFile();
- //add membership for catalog zone
- if (catalogZoneInfo is not null)
- _dnsWebService.DnsServer.AuthZoneManager.AddCatalogMemberZone(catalogZoneInfo.Name, zoneInfo);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Authoritative Primary zone was created: " + zoneInfo.DisplayName);
- }
- break;
- case AuthZoneType.Secondary:
- {
- string primaryNameServerAddresses = request.GetQueryOrForm("primaryNameServerAddresses", null);
- DnsTransportProtocol primaryZoneTransferProtocol = request.GetQueryOrFormEnum("zoneTransferProtocol", DnsTransportProtocol.Tcp);
- string primaryZoneTransferTsigKeyName = request.GetQueryOrForm("tsigKeyName", null);
- bool validateZone = request.GetQueryOrForm("validateZone", bool.Parse, false);
- if (primaryZoneTransferProtocol == DnsTransportProtocol.Quic)
- DnsWebService.ValidateQuicSupport();
- zoneInfo = await _dnsWebService.DnsServer.AuthZoneManager.CreateSecondaryZoneAsync(zoneName, primaryNameServerAddresses, primaryZoneTransferProtocol, primaryZoneTransferTsigKeyName, validateZone);
- if (zoneInfo is null)
- throw new DnsWebServiceException("Zone already exists: " + zoneName);
- //set permissions
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.DNS_ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SaveConfigFile();
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Authoritative Secondary zone was created: " + zoneInfo.DisplayName);
- }
- break;
- case AuthZoneType.Stub:
- {
- string primaryNameServerAddresses = request.GetQueryOrForm("primaryNameServerAddresses", null);
- string catalogZoneName = request.GetQueryOrForm("catalog", null);
- AuthZoneInfo catalogZoneInfo = null;
- if (catalogZoneName is not null)
- {
- catalogZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(catalogZoneName);
- if (catalogZoneInfo is null)
- throw new DnsWebServiceException("No such Catalog zone was found: " + catalogZoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, catalogZoneInfo.Name, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied to use Catalog zone: " + catalogZoneInfo.Name);
- }
- zoneInfo = await _dnsWebService.DnsServer.AuthZoneManager.CreateStubZoneAsync(zoneName, primaryNameServerAddresses);
- if (zoneInfo is null)
- throw new DnsWebServiceException("Zone already exists: " + zoneName);
- //set permissions
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.DNS_ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SaveConfigFile();
- //add membership for catalog zone
- if (catalogZoneInfo is not null)
- _dnsWebService.DnsServer.AuthZoneManager.AddCatalogMemberZone(catalogZoneInfo.Name, zoneInfo);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Stub zone was created: " + zoneInfo.DisplayName);
- }
- break;
- case AuthZoneType.Forwarder:
- {
- DnsTransportProtocol forwarderProtocol = request.GetQueryOrFormEnum("protocol", DnsTransportProtocol.Udp);
- string forwarder = request.GetQueryOrForm("forwarder");
- bool dnssecValidation = request.GetQueryOrForm("dnssecValidation", bool.Parse, false);
- DnsForwarderRecordProxyType proxyType = request.GetQueryOrFormEnum("proxyType", DnsForwarderRecordProxyType.DefaultProxy);
- string proxyAddress = null;
- ushort proxyPort = 0;
- string proxyUsername = null;
- string proxyPassword = null;
- switch (proxyType)
- {
- case DnsForwarderRecordProxyType.Http:
- case DnsForwarderRecordProxyType.Socks5:
- proxyAddress = request.GetQueryOrForm("proxyAddress");
- proxyPort = request.GetQueryOrForm("proxyPort", ushort.Parse);
- proxyUsername = request.QueryOrForm("proxyUsername");
- proxyPassword = request.QueryOrForm("proxyPassword");
- break;
- }
- if (forwarderProtocol == DnsTransportProtocol.Quic)
- DnsWebService.ValidateQuicSupport();
- string catalogZoneName = request.GetQueryOrForm("catalog", null);
- AuthZoneInfo catalogZoneInfo = null;
- if (catalogZoneName is not null)
- {
- catalogZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(catalogZoneName);
- if (catalogZoneInfo is null)
- throw new DnsWebServiceException("No such Catalog zone was found: " + catalogZoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, catalogZoneInfo.Name, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied to use Catalog zone: " + catalogZoneInfo.Name);
- }
- zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.CreateForwarderZone(zoneName, forwarderProtocol, forwarder, dnssecValidation, proxyType, proxyAddress, proxyPort, proxyUsername, proxyPassword, null);
- if (zoneInfo is null)
- throw new DnsWebServiceException("Zone already exists: " + zoneName);
- //set permissions
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.DNS_ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SaveConfigFile();
- //add membership for catalog zone
- if (catalogZoneInfo is not null)
- _dnsWebService.DnsServer.AuthZoneManager.AddCatalogMemberZone(catalogZoneInfo.Name, zoneInfo);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Forwarder zone was created: " + zoneInfo.DisplayName);
- }
- break;
- case AuthZoneType.SecondaryForwarder:
- {
- string primaryNameServerAddresses = request.GetQueryOrForm("primaryNameServerAddresses");
- DnsTransportProtocol primaryZoneTransferProtocol = request.GetQueryOrFormEnum("zoneTransferProtocol", DnsTransportProtocol.Tcp);
- string primaryZoneTransferTsigKeyName = request.GetQueryOrForm("tsigKeyName", null);
- if (primaryZoneTransferProtocol == DnsTransportProtocol.Quic)
- DnsWebService.ValidateQuicSupport();
- zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.CreateSecondaryForwarderZone(zoneName, primaryNameServerAddresses, primaryZoneTransferProtocol, primaryZoneTransferTsigKeyName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("Zone already exists: " + zoneName);
- //set permissions
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.DNS_ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SaveConfigFile();
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Secondary Forwarder zone was created: " + zoneInfo.DisplayName);
- }
- break;
- case AuthZoneType.Catalog:
- {
- zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.CreateCatalogZone(zoneName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("Zone already exists: " + zoneName);
- //set permissions
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.DNS_ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SaveConfigFile();
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Catalog zone was created: " + zoneInfo.DisplayName);
- }
- break;
- case AuthZoneType.SecondaryCatalog:
- {
- string primaryNameServerAddresses = request.GetQueryOrForm("primaryNameServerAddresses");
- DnsTransportProtocol primaryZoneTransferProtocol = request.GetQueryOrFormEnum("zoneTransferProtocol", DnsTransportProtocol.Tcp);
- string primaryZoneTransferTsigKeyName = request.GetQueryOrForm("tsigKeyName", null);
- if (primaryZoneTransferProtocol == DnsTransportProtocol.Quic)
- DnsWebService.ValidateQuicSupport();
- zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.CreateSecondaryCatalogZone(zoneName, primaryNameServerAddresses, primaryZoneTransferProtocol, primaryZoneTransferTsigKeyName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("Zone already exists: " + zoneName);
- //set permissions
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.DNS_ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SaveConfigFile();
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Secondary Catalog zone was created: " + zoneInfo.DisplayName);
- }
- break;
- default:
- throw new NotSupportedException("Zone type not supported.");
- }
- //delete cache for this zone to allow rebuilding cache data as needed by stub or forwarder zones
- _dnsWebService.DnsServer.CacheZoneManager.DeleteZone(zoneInfo.Name);
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- jsonWriter.WriteString("domain", string.IsNullOrEmpty(zoneInfo.Name) ? "." : zoneInfo.Name);
- }
- public async Task ImportZoneAsync(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string zoneName = request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- AuthZoneInfo zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(zoneName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("No such zone was found: " + zoneName);
- if (zoneInfo.Internal)
- throw new DnsWebServiceException("Access was denied to manage internal DNS Server zone.");
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- bool overwrite = request.GetQueryOrForm("overwrite", bool.Parse, true);
- bool overwriteSoaSerial = request.GetQueryOrForm("overwriteSoaSerial", bool.Parse, false);
- TextReader textReader;
- switch (request.ContentType?.ToLowerInvariant())
- {
- case "application/x-www-form-urlencoded":
- string zoneRecords = request.GetQueryOrForm("records");
- textReader = new StringReader(zoneRecords);
- break;
- case "text/plain":
- textReader = new StreamReader(request.Body);
- break;
- default:
- throw new DnsWebServiceException("Content type is not supported: " + request.ContentType);
- }
- using TextReader zoneReader = textReader;
- IReadOnlyCollection<DnsResourceRecord> records = await ZoneFile.ReadZoneFileFromAsync(zoneReader, zoneInfo.Name, _dnsWebService._zonesApi.DefaultRecordTtl);
- List<DnsResourceRecord> newRecords = new List<DnsResourceRecord>(records.Count);
- foreach (DnsResourceRecord record in records)
- {
- if (record.Class != DnsClass.IN)
- throw new DnsWebServiceException("Cannot import records: only IN class is supported by the DNS server.");
- switch (record.Type)
- {
- case DnsResourceRecordType.DNSKEY:
- case DnsResourceRecordType.RRSIG:
- case DnsResourceRecordType.NSEC:
- case DnsResourceRecordType.NSEC3:
- case DnsResourceRecordType.NSEC3PARAM:
- continue; //skip DNSSEC records
- case DnsResourceRecordType.SVCB:
- case DnsResourceRecordType.HTTPS:
- {
- if (record.Tag is string comments)
- {
- SVCBRecordInfo rrInfo = new SVCBRecordInfo();
- rrInfo.Comments = comments;
- record.Tag = rrInfo;
- }
- if (record.RDATA is DnsSVCBRecordData rdata && (rdata.AutoIpv4Hint || rdata.AutoIpv6Hint))
- {
- if (rdata.AutoIpv4Hint)
- record.GetAuthSVCBRecordInfo().AutoIpv4Hint = true;
- if (rdata.AutoIpv6Hint)
- record.GetAuthSVCBRecordInfo().AutoIpv6Hint = true;
- Dictionary<DnsSvcParamKey, DnsSvcParamValue> svcParams = new Dictionary<DnsSvcParamKey, DnsSvcParamValue>(rdata.SvcParams);
- DnsResourceRecord newRecord = new DnsResourceRecord(record.Name, record.Type, record.Class, record.TTL, new DnsSVCBRecordData(rdata.SvcPriority, rdata.TargetName, svcParams)) { Tag = record.Tag };
- ResolveSvcbAutoHints(zoneInfo.Name, record, rdata.AutoIpv4Hint, rdata.AutoIpv6Hint, svcParams, records);
- newRecords.Add(newRecord);
- break;
- }
- newRecords.Add(record);
- }
- break;
- default:
- {
- if (record.Tag is string comments)
- {
- GenericRecordInfo rrInfo = new GenericRecordInfo();
- rrInfo.Comments = comments;
- record.Tag = rrInfo;
- }
- newRecords.Add(record);
- }
- break;
- }
- }
- _dnsWebService.DnsServer.AuthZoneManager.ImportRecords(zoneInfo.Name, newRecords, overwrite, overwriteSoaSerial);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Total " + newRecords.Count + " record(s) were imported successfully into " + zoneInfo.TypeName + " zone: " + zoneInfo.DisplayName);
- }
- public async Task ExportZoneAsync(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string zoneName = request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- AuthZoneInfo zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(zoneName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("No such zone was found: " + zoneName);
- if (zoneInfo.Internal)
- throw new DnsWebServiceException("Access was denied to manage internal DNS Server zone.");
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- List<DnsResourceRecord> records = new List<DnsResourceRecord>();
- _dnsWebService.DnsServer.AuthZoneManager.ListAllZoneRecords(zoneInfo.Name, records);
- foreach (DnsResourceRecord record in records)
- {
- switch (record.Type)
- {
- case DnsResourceRecordType.SVCB:
- case DnsResourceRecordType.HTTPS:
- SVCBRecordInfo info = record.GetAuthSVCBRecordInfo();
- if (info.AutoIpv4Hint)
- (record.RDATA as DnsSVCBRecordData).AutoIpv4Hint = true;
- if (info.AutoIpv6Hint)
- (record.RDATA as DnsSVCBRecordData).AutoIpv6Hint = true;
- break;
- }
- }
- HttpResponse response = context.Response;
- response.ContentType = "text/plain";
- response.Headers.ContentDisposition = "attachment;filename=" + (zoneInfo.Name.Length == 0 ? "root.zone" : zoneInfo.Name + ".zone");
- await using (StreamWriter sW = new StreamWriter(response.Body))
- {
- await ZoneFile.WriteZoneFileToAsync(sW, zoneInfo.Name, records, delegate (DnsResourceRecord record)
- {
- if (record.Tag is null)
- return null;
- return record.GetAuthGenericRecordInfo().Comments;
- });
- }
- }
- public void CloneZone(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string zoneName = request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- string sourceZoneName = request.GetQueryOrForm("sourceZone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(sourceZoneName))
- sourceZoneName = DnsClient.ConvertDomainNameToAscii(sourceZoneName);
- AuthZoneInfo sourceZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(sourceZoneName);
- if (sourceZoneInfo is null)
- throw new DnsWebServiceException("No such zone was found: " + sourceZoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, sourceZoneInfo.Name, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- AuthZoneInfo zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.CloneZone(zoneName, sourceZoneInfo.Name);
- //clone user/group permissions from source zone
- Permission sourceZonePermissions = _dnsWebService._authManager.GetPermission(PermissionSection.Zones, sourceZoneInfo.Name);
- foreach (KeyValuePair<User, PermissionFlag> userPermission in sourceZonePermissions.UserPermissions)
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, userPermission.Key, userPermission.Value);
- foreach (KeyValuePair<Group, PermissionFlag> groupPermissions in sourceZonePermissions.GroupPermissions)
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, groupPermissions.Key, groupPermissions.Value);
- //set default permissions
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.DNS_ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SaveConfigFile();
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] " + sourceZoneInfo.TypeName + " zone '" + sourceZoneInfo.DisplayName + "' was cloned as '" + zoneInfo.DisplayName + "' sucessfully.");
- }
- public void ConvertZone(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string zoneName = request.GetQueryOrForm("zone").TrimEnd('.');
- AuthZoneType type = request.GetQueryOrFormEnum<AuthZoneType>("type");
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- AuthZoneInfo zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(zoneName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("No such zone was found: " + zoneName);
- if (zoneInfo.Internal)
- throw new DnsWebServiceException("Access was denied to manage internal DNS Server zone.");
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- _dnsWebService.DnsServer.AuthZoneManager.ConvertZoneType(zoneInfo.Name, type);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] " + zoneInfo.TypeName + " zone '" + zoneInfo.DisplayName + "' was converted to " + AuthZoneInfo.GetZoneTypeName(type) + " zone sucessfully.");
- }
- public void SignPrimaryZone(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string zoneName = request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneName, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- string algorithm = request.GetQueryOrForm("algorithm");
- uint dnsKeyTtl = request.GetQueryOrForm<uint>("dnsKeyTtl", uint.Parse, 24 * 60 * 60);
- ushort zskRolloverDays = request.GetQueryOrForm<ushort>("zskRolloverDays", ushort.Parse, 30);
- bool useNSEC3 = false;
- string strNxProof = request.QueryOrForm("nxProof");
- if (!string.IsNullOrEmpty(strNxProof))
- {
- switch (strNxProof.ToUpper())
- {
- case "NSEC":
- useNSEC3 = false;
- break;
- case "NSEC3":
- useNSEC3 = true;
- break;
- default:
- throw new NotSupportedException("Non-existence proof type is not supported: " + strNxProof);
- }
- }
- ushort iterations = 0;
- byte saltLength = 0;
- if (useNSEC3)
- {
- iterations = request.GetQueryOrForm<ushort>("iterations", ushort.Parse, 0);
- saltLength = request.GetQueryOrForm<byte>("saltLength", byte.Parse, 0);
- }
- switch (algorithm.ToUpper())
- {
- case "RSA":
- string hashAlgorithm = request.GetQueryOrForm("hashAlgorithm");
- int kskKeySize = request.GetQueryOrForm("kskKeySize", int.Parse);
- int zskKeySize = request.GetQueryOrForm("zskKeySize", int.Parse);
- if (useNSEC3)
- _dnsWebService.DnsServer.AuthZoneManager.SignPrimaryZoneWithRsaNSEC3(zoneName, hashAlgorithm, kskKeySize, zskKeySize, iterations, saltLength, dnsKeyTtl, zskRolloverDays);
- else
- _dnsWebService.DnsServer.AuthZoneManager.SignPrimaryZoneWithRsaNSEC(zoneName, hashAlgorithm, kskKeySize, zskKeySize, dnsKeyTtl, zskRolloverDays);
- break;
- case "ECDSA":
- string curve = request.GetQueryOrForm("curve");
- if (useNSEC3)
- _dnsWebService.DnsServer.AuthZoneManager.SignPrimaryZoneWithEcdsaNSEC3(zoneName, curve, iterations, saltLength, dnsKeyTtl, zskRolloverDays);
- else
- _dnsWebService.DnsServer.AuthZoneManager.SignPrimaryZoneWithEcdsaNSEC(zoneName, curve, dnsKeyTtl, zskRolloverDays);
- break;
- default:
- throw new NotSupportedException("Algorithm is not supported: " + algorithm);
- }
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Primary zone was signed successfully: " + zoneName);
- }
- public void UnsignPrimaryZone(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- string zoneName = context.Request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneName, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- _dnsWebService.DnsServer.AuthZoneManager.UnsignPrimaryZone(zoneName);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Primary zone was unsigned successfully: " + zoneName);
- }
- public void GetPrimaryZoneDsInfo(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- string zoneName = context.Request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- AuthZoneInfo zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(zoneName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("No such zone was found: " + zoneName);
- if (zoneInfo.Internal)
- throw new DnsWebServiceException("Access was denied to manage internal DNS Server zone.");
- if (zoneInfo.Type != AuthZoneType.Primary)
- throw new DnsWebServiceException("The zone must be a primary zone.");
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- if (zoneInfo.ApexZone.DnssecStatus == AuthZoneDnssecStatus.Unsigned)
- throw new DnsWebServiceException("The zone must be signed with DNSSEC.");
- IReadOnlyList<DnsResourceRecord> dnsKeyRecords = zoneInfo.ApexZone.GetRecords(DnsResourceRecordType.DNSKEY);
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- jsonWriter.WriteString("name", zoneInfo.Name);
- jsonWriter.WriteString("type", zoneInfo.Type.ToString());
- jsonWriter.WriteBoolean("internal", zoneInfo.Internal);
- jsonWriter.WriteBoolean("disabled", zoneInfo.Disabled);
- jsonWriter.WriteString("dnssecStatus", zoneInfo.ApexZone.DnssecStatus.ToString());
- jsonWriter.WritePropertyName("dsRecords");
- jsonWriter.WriteStartArray();
- foreach (DnsResourceRecord record in dnsKeyRecords)
- {
- if (record.RDATA is DnsDNSKEYRecordData rdata && rdata.Flags.HasFlag(DnsDnsKeyFlag.SecureEntryPoint))
- {
- jsonWriter.WriteStartObject();
- jsonWriter.WriteNumber("keyTag", rdata.ComputedKeyTag);
- IReadOnlyCollection<DnssecPrivateKey> dnssecPrivateKeys = zoneInfo.DnssecPrivateKeys;
- if (dnssecPrivateKeys is not null)
- {
- foreach (DnssecPrivateKey dnssecPrivateKey in dnssecPrivateKeys)
- {
- if ((dnssecPrivateKey.KeyType == DnssecPrivateKeyType.KeySigningKey) && (dnssecPrivateKey.KeyTag == rdata.ComputedKeyTag))
- {
- jsonWriter.WriteString("dnsKeyState", dnssecPrivateKey.State.ToString());
- if (dnssecPrivateKey.State == DnssecPrivateKeyState.Published)
- jsonWriter.WriteString("dnsKeyStateReadyBy", (zoneInfo.ApexZone as PrimaryZone).GetKskDnsKeyStateReadyBy(dnssecPrivateKey));
- break;
- }
- }
- }
- jsonWriter.WriteString("algorithm", rdata.Algorithm.ToString());
- jsonWriter.WriteString("publicKey", rdata.PublicKey.ToString());
- jsonWriter.WritePropertyName("digests");
- jsonWriter.WriteStartArray();
- {
- jsonWriter.WriteStartObject();
- jsonWriter.WriteString("digestType", "SHA256");
- jsonWriter.WriteString("digest", Convert.ToHexString(rdata.CreateDS(record.Name, DnssecDigestType.SHA256).Digest));
- jsonWriter.WriteEndObject();
- }
- {
- jsonWriter.WriteStartObject();
- jsonWriter.WriteString("digestType", "SHA384");
- jsonWriter.WriteString("digest", Convert.ToHexString(rdata.CreateDS(record.Name, DnssecDigestType.SHA384).Digest));
- jsonWriter.WriteEndObject();
- }
- jsonWriter.WriteEndArray();
- jsonWriter.WriteEndObject();
- }
- }
- jsonWriter.WriteEndArray();
- }
- public void GetPrimaryZoneDnssecProperties(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- string zoneName = context.Request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- AuthZoneInfo zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(zoneName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("No such zone was found: " + zoneName);
- if (zoneInfo.Internal)
- throw new DnsWebServiceException("Access was denied to manage internal DNS Server zone.");
- if (zoneInfo.Type != AuthZoneType.Primary)
- throw new DnsWebServiceException("The zone must be a primary zone.");
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- jsonWriter.WriteString("name", zoneInfo.Name);
- jsonWriter.WriteString("type", zoneInfo.Type.ToString());
- jsonWriter.WriteBoolean("internal", zoneInfo.Internal);
- jsonWriter.WriteBoolean("disabled", zoneInfo.Disabled);
- jsonWriter.WriteString("dnssecStatus", zoneInfo.ApexZone.DnssecStatus.ToString());
- if (zoneInfo.ApexZone.DnssecStatus == AuthZoneDnssecStatus.SignedWithNSEC3)
- {
- IReadOnlyList<DnsResourceRecord> nsec3ParamRecords = zoneInfo.ApexZone.GetRecords(DnsResourceRecordType.NSEC3PARAM);
- DnsNSEC3PARAMRecordData nsec3Param = nsec3ParamRecords[0].RDATA as DnsNSEC3PARAMRecordData;
- jsonWriter.WriteNumber("nsec3Iterations", nsec3Param.Iterations);
- jsonWriter.WriteNumber("nsec3SaltLength", nsec3Param.Salt.Length);
- }
- jsonWriter.WriteNumber("dnsKeyTtl", zoneInfo.DnsKeyTtl);
- jsonWriter.WritePropertyName("dnssecPrivateKeys");
- jsonWriter.WriteStartArray();
- IReadOnlyCollection<DnssecPrivateKey> dnssecPrivateKeys = zoneInfo.DnssecPrivateKeys;
- if (dnssecPrivateKeys is not null)
- {
- List<DnssecPrivateKey> sortedDnssecPrivateKey = new List<DnssecPrivateKey>(dnssecPrivateKeys);
- sortedDnssecPrivateKey.Sort(delegate (DnssecPrivateKey key1, DnssecPrivateKey key2)
- {
- int value = key1.KeyType.CompareTo(key2.KeyType);
- if (value == 0)
- value = key1.StateChangedOn.CompareTo(key2.StateChangedOn);
- return value;
- });
- foreach (DnssecPrivateKey dnssecPrivateKey in sortedDnssecPrivateKey)
- {
- jsonWriter.WriteStartObject();
- jsonWriter.WriteNumber("keyTag", dnssecPrivateKey.KeyTag);
- jsonWriter.WriteString("keyType", dnssecPrivateKey.KeyType.ToString());
- switch (dnssecPrivateKey.Algorithm)
- {
- case DnssecAlgorithm.RSAMD5:
- case DnssecAlgorithm.RSASHA1:
- case DnssecAlgorithm.RSASHA1_NSEC3_SHA1:
- case DnssecAlgorithm.RSASHA256:
- case DnssecAlgorithm.RSASHA512:
- jsonWriter.WriteString("algorithm", dnssecPrivateKey.Algorithm.ToString() + " (" + (dnssecPrivateKey as DnssecRsaPrivateKey).KeySize + " bits)");
- break;
- default:
- jsonWriter.WriteString("algorithm", dnssecPrivateKey.Algorithm.ToString());
- break;
- }
- jsonWriter.WriteString("state", dnssecPrivateKey.State.ToString());
- jsonWriter.WriteString("stateChangedOn", dnssecPrivateKey.StateChangedOn);
- if ((dnssecPrivateKey.KeyType == DnssecPrivateKeyType.KeySigningKey) && (dnssecPrivateKey.State == DnssecPrivateKeyState.Published))
- jsonWriter.WriteString("stateReadyBy", (zoneInfo.ApexZone as PrimaryZone).GetKskDnsKeyStateReadyBy(dnssecPrivateKey));
- jsonWriter.WriteBoolean("isRetiring", dnssecPrivateKey.IsRetiring);
- jsonWriter.WriteNumber("rolloverDays", dnssecPrivateKey.RolloverDays);
- jsonWriter.WriteEndObject();
- }
- }
- jsonWriter.WriteEndArray();
- }
- public void ConvertPrimaryZoneToNSEC(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- string zoneName = context.Request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneName, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- _dnsWebService.DnsServer.AuthZoneManager.ConvertPrimaryZoneToNSEC(zoneName);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Primary zone was converted to NSEC successfully: " + zoneName);
- }
- public void ConvertPrimaryZoneToNSEC3(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string zoneName = request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneName, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- ushort iterations = request.GetQueryOrForm<ushort>("iterations", ushort.Parse, 0);
- byte saltLength = request.GetQueryOrForm<byte>("saltLength", byte.Parse, 0);
- _dnsWebService.DnsServer.AuthZoneManager.ConvertPrimaryZoneToNSEC3(zoneName, iterations, saltLength);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Primary zone was converted to NSEC3 successfully: " + zoneName);
- }
- public void UpdatePrimaryZoneNSEC3Parameters(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string zoneName = request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneName, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- ushort iterations = request.GetQueryOrForm<ushort>("iterations", ushort.Parse, 0);
- byte saltLength = request.GetQueryOrForm<byte>("saltLength", byte.Parse, 0);
- _dnsWebService.DnsServer.AuthZoneManager.UpdatePrimaryZoneNSEC3Parameters(zoneName, iterations, saltLength);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Primary zone NSEC3 parameters were updated successfully: " + zoneName);
- }
- public void UpdatePrimaryZoneDnssecDnsKeyTtl(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string zoneName = request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneName, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- uint dnsKeyTtl = request.GetQueryOrForm("ttl", uint.Parse);
- _dnsWebService.DnsServer.AuthZoneManager.UpdatePrimaryZoneDnsKeyTtl(zoneName, dnsKeyTtl);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Primary zone DNSKEY TTL was updated successfully: " + zoneName);
- }
- public void GenerateAndAddPrimaryZoneDnssecPrivateKey(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string zoneName = request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneName, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- DnssecPrivateKeyType keyType = request.GetQueryOrFormEnum<DnssecPrivateKeyType>("keyType");
- ushort rolloverDays = request.GetQueryOrForm("rolloverDays", ushort.Parse, (ushort)(keyType == DnssecPrivateKeyType.ZoneSigningKey ? 30 : 0));
- string algorithm = request.GetQueryOrForm("algorithm");
- switch (algorithm.ToUpper())
- {
- case "RSA":
- string hashAlgorithm = request.GetQueryOrForm("hashAlgorithm");
- int keySize = request.GetQueryOrForm("keySize", int.Parse);
- _dnsWebService.DnsServer.AuthZoneManager.GenerateAndAddPrimaryZoneDnssecRsaPrivateKey(zoneName, keyType, hashAlgorithm, keySize, rolloverDays);
- break;
- case "ECDSA":
- string curve = request.GetQueryOrForm("curve");
- _dnsWebService.DnsServer.AuthZoneManager.GenerateAndAddPrimaryZoneDnssecEcdsaPrivateKey(zoneName, keyType, curve, rolloverDays);
- break;
- default:
- throw new NotSupportedException("Algorithm is not supported: " + algorithm);
- }
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] DNSSEC private key was generated and added to the primary zone successfully: " + zoneName);
- }
- public void UpdatePrimaryZoneDnssecPrivateKey(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string zoneName = request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneName, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- ushort keyTag = request.GetQueryOrForm("keyTag", ushort.Parse);
- ushort rolloverDays = request.GetQueryOrForm("rolloverDays", ushort.Parse);
- _dnsWebService.DnsServer.AuthZoneManager.UpdatePrimaryZoneDnssecPrivateKey(zoneName, keyTag, rolloverDays);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Primary zone DNSSEC private key config was updated successfully: " + zoneName);
- }
- public void DeletePrimaryZoneDnssecPrivateKey(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string zoneName = request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneName, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- ushort keyTag = request.GetQueryOrForm("keyTag", ushort.Parse);
- _dnsWebService.DnsServer.AuthZoneManager.DeletePrimaryZoneDnssecPrivateKey(zoneName, keyTag);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] DNSSEC private key was deleted from primary zone successfully: " + zoneName);
- }
- public void PublishAllGeneratedPrimaryZoneDnssecPrivateKeys(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- string zoneName = context.Request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneName, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- _dnsWebService.DnsServer.AuthZoneManager.PublishAllGeneratedPrimaryZoneDnssecPrivateKeys(zoneName);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] All DNSSEC private keys from the primary zone were published successfully: " + zoneName);
- }
- public void RolloverPrimaryZoneDnsKey(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string zoneName = request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneName, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- ushort keyTag = request.GetQueryOrForm("keyTag", ushort.Parse);
- _dnsWebService.DnsServer.AuthZoneManager.RolloverPrimaryZoneDnsKey(zoneName, keyTag);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] The DNSKEY (" + keyTag + ") from the primary zone was rolled over successfully: " + zoneName);
- }
- public void RetirePrimaryZoneDnsKey(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string zoneName = request.GetQueryOrForm("zone").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneName, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- ushort keyTag = request.GetQueryOrForm("keyTag", ushort.Parse);
- _dnsWebService.DnsServer.AuthZoneManager.RetirePrimaryZoneDnsKey(zoneName, keyTag);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] The DNSKEY (" + keyTag + ") from the primary zone was retired successfully: " + zoneName);
- }
- public void DeleteZone(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- string zoneName = context.Request.GetQueryOrFormAlt("zone", "domain").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- AuthZoneInfo zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(zoneName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("No such zone was found: " + zoneName);
- if (zoneInfo.Internal)
- throw new DnsWebServiceException("Access was denied to manage internal DNS Server zone.");
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- if (!_dnsWebService.DnsServer.AuthZoneManager.DeleteZone(zoneInfo, true))
- throw new DnsWebServiceException("Failed to delete the zone: " + zoneInfo.DisplayName);
- _dnsWebService._authManager.RemoveAllPermissions(PermissionSection.Zones, zoneInfo.Name);
- _dnsWebService._authManager.SaveConfigFile();
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] " + zoneInfo.TypeName + " zone was deleted: " + zoneInfo.DisplayName);
- }
- public void EnableZone(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- string zoneName = context.Request.GetQueryOrFormAlt("zone", "domain").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- AuthZoneInfo zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(zoneName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("No such zone was found: " + zoneName);
- if (zoneInfo.Internal)
- throw new DnsWebServiceException("Access was denied to manage internal DNS Server zone.");
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- zoneInfo.Disabled = false;
- _dnsWebService.DnsServer.AuthZoneManager.SaveZoneFile(zoneInfo.Name);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] " + zoneInfo.TypeName + " zone was enabled: " + zoneInfo.DisplayName);
- //delete cache for this zone to allow rebuilding cache data as needed by stub or forwarder zones
- _dnsWebService.DnsServer.CacheZoneManager.DeleteZone(zoneInfo.Name);
- }
- public void DisableZone(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- string zoneName = context.Request.GetQueryOrFormAlt("zone", "domain").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- AuthZoneInfo zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(zoneName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("No such zone was found: " + zoneName);
- if (zoneInfo.Internal)
- throw new DnsWebServiceException("Access was denied to manage internal DNS Server zone.");
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- zoneInfo.Disabled = true;
- _dnsWebService.DnsServer.AuthZoneManager.SaveZoneFile(zoneInfo.Name);
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] " + zoneInfo.TypeName + " zone was disabled: " + zoneInfo.DisplayName);
- }
- public void GetZoneOptions(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string zoneName = request.GetQueryOrFormAlt("zone", "domain").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- bool includeAvailableCatalogZoneNames = request.GetQueryOrForm("includeAvailableCatalogZoneNames", bool.Parse, false);
- bool includeAvailableTsigKeyNames = request.GetQueryOrForm("includeAvailableTsigKeyNames", bool.Parse, false);
- AuthZoneInfo zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(zoneName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("No such zone was found: " + zoneName);
- if (zoneInfo.Internal)
- throw new DnsWebServiceException("Access was denied to manage internal DNS Server zone.");
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- jsonWriter.WriteString("name", zoneInfo.Name);
- if (DnsClient.TryConvertDomainNameToUnicode(zoneInfo.Name, out string nameIdn))
- jsonWriter.WriteString("nameIdn", nameIdn);
- jsonWriter.WriteString("type", zoneInfo.Type.ToString());
- if (zoneInfo.Type == AuthZoneType.Primary)
- jsonWriter.WriteBoolean("internal", zoneInfo.Internal);
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Secondary:
- jsonWriter.WriteString("dnssecStatus", zoneInfo.ApexZone.DnssecStatus.ToString());
- break;
- }
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Secondary:
- case AuthZoneType.Forwarder:
- case AuthZoneType.Catalog:
- if (!zoneInfo.Internal)
- {
- string[] notifyFailed = zoneInfo.NotifyFailed;
- jsonWriter.WriteBoolean("notifyFailed", notifyFailed.Length > 0);
- jsonWriter.WritePropertyName("notifyFailedFor");
- jsonWriter.WriteStartArray();
- foreach (string server in notifyFailed)
- jsonWriter.WriteStringValue(server);
- jsonWriter.WriteEndArray();
- }
- break;
- }
- jsonWriter.WriteBoolean("disabled", zoneInfo.Disabled);
- //catalog zone
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Forwarder:
- jsonWriter.WriteString("catalog", zoneInfo.CatalogZoneName);
- if (zoneInfo.CatalogZoneName is not null)
- {
- jsonWriter.WriteBoolean("overrideCatalogQueryAccess", zoneInfo.OverrideCatalogQueryAccess);
- jsonWriter.WriteBoolean("overrideCatalogZoneTransfer", zoneInfo.OverrideCatalogZoneTransfer);
- jsonWriter.WriteBoolean("overrideCatalogNotify", zoneInfo.OverrideCatalogNotify);
- }
- break;
- case AuthZoneType.Stub:
- jsonWriter.WriteString("catalog", zoneInfo.CatalogZoneName);
- if (zoneInfo.CatalogZoneName is not null)
- {
- jsonWriter.WriteBoolean("isSecondaryCatalogMember", zoneInfo.ApexZone.SecondaryCatalogZone is not null);
- jsonWriter.WriteBoolean("overrideCatalogQueryAccess", zoneInfo.OverrideCatalogQueryAccess);
- }
- break;
- case AuthZoneType.Secondary:
- jsonWriter.WriteString("catalog", zoneInfo.CatalogZoneName);
- if (zoneInfo.CatalogZoneName is not null)
- {
- jsonWriter.WriteBoolean("overrideCatalogQueryAccess", zoneInfo.OverrideCatalogQueryAccess);
- jsonWriter.WriteBoolean("overrideCatalogZoneTransfer", zoneInfo.OverrideCatalogZoneTransfer);
- jsonWriter.WriteBoolean("overrideCatalogPrimaryNameServers", zoneInfo.OverrideCatalogPrimaryNameServers);
- }
- break;
- case AuthZoneType.SecondaryForwarder:
- jsonWriter.WriteString("catalog", zoneInfo.CatalogZoneName);
- if (zoneInfo.CatalogZoneName is not null)
- jsonWriter.WriteBoolean("overrideCatalogQueryAccess", zoneInfo.OverrideCatalogQueryAccess);
- break;
- }
- //primary server
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Secondary:
- case AuthZoneType.SecondaryForwarder:
- case AuthZoneType.SecondaryCatalog:
- case AuthZoneType.Stub:
- jsonWriter.WriteStartArray("primaryNameServerAddresses");
- IReadOnlyList<NameServerAddress> primaryNameServerAddresses = zoneInfo.PrimaryNameServerAddresses;
- if (primaryNameServerAddresses is not null)
- {
- foreach (NameServerAddress primaryNameServerAddress in primaryNameServerAddresses)
- jsonWriter.WriteStringValue(primaryNameServerAddress.OriginalAddress);
- }
- jsonWriter.WriteEndArray();
- break;
- }
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Secondary:
- case AuthZoneType.SecondaryForwarder:
- case AuthZoneType.SecondaryCatalog:
- if (zoneInfo.PrimaryZoneTransferProtocol == DnsTransportProtocol.Udp)
- jsonWriter.WriteString("primaryZoneTransferProtocol", "Tcp");
- else
- jsonWriter.WriteString("primaryZoneTransferProtocol", zoneInfo.PrimaryZoneTransferProtocol.ToString());
- jsonWriter.WriteString("primaryZoneTransferTsigKeyName", zoneInfo.PrimaryZoneTransferTsigKeyName);
- break;
- }
- if (zoneInfo.Type == AuthZoneType.Secondary)
- jsonWriter.WriteBoolean("validateZone", zoneInfo.ValidateZone);
- //query access
- {
- jsonWriter.WriteString("queryAccess", zoneInfo.QueryAccess.ToString());
- jsonWriter.WriteStartArray("queryAccessNetworkACL");
- if (zoneInfo.QueryAccessNetworkACL is not null)
- {
- foreach (NetworkAccessControl nac in zoneInfo.QueryAccessNetworkACL)
- jsonWriter.WriteStringValue(nac.ToString());
- }
- jsonWriter.WriteEndArray();
- }
- //zone transfer
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Secondary:
- case AuthZoneType.Forwarder:
- case AuthZoneType.Catalog:
- case AuthZoneType.SecondaryCatalog:
- jsonWriter.WriteString("zoneTransfer", zoneInfo.ZoneTransfer.ToString());
- jsonWriter.WritePropertyName("zoneTransferNetworkACL");
- {
- jsonWriter.WriteStartArray();
- if (zoneInfo.ZoneTransferNetworkACL is not null)
- {
- foreach (NetworkAccessControl nac in zoneInfo.ZoneTransferNetworkACL)
- jsonWriter.WriteStringValue(nac.ToString());
- }
- jsonWriter.WriteEndArray();
- }
- jsonWriter.WritePropertyName("zoneTransferTsigKeyNames");
- {
- jsonWriter.WriteStartArray();
- if (zoneInfo.ZoneTransferTsigKeyNames is not null)
- {
- foreach (KeyValuePair<string, object> tsigKeyName in zoneInfo.ZoneTransferTsigKeyNames)
- jsonWriter.WriteStringValue(tsigKeyName.Key);
- }
- jsonWriter.WriteEndArray();
- }
- break;
- }
- //notify
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Secondary:
- case AuthZoneType.Forwarder:
- case AuthZoneType.Catalog:
- jsonWriter.WriteString("notify", zoneInfo.Notify.ToString());
- jsonWriter.WritePropertyName("notifyNameServers");
- {
- jsonWriter.WriteStartArray();
- if (zoneInfo.NotifyNameServers is not null)
- {
- foreach (IPAddress nameServer in zoneInfo.NotifyNameServers)
- jsonWriter.WriteStringValue(nameServer.ToString());
- }
- jsonWriter.WriteEndArray();
- }
- if (zoneInfo.Type == AuthZoneType.Catalog)
- {
- jsonWriter.WriteStartArray("notifySecondaryCatalogsNameServers");
- if (zoneInfo.NotifySecondaryCatalogNameServers is not null)
- {
- foreach (IPAddress nameServer in zoneInfo.NotifySecondaryCatalogNameServers)
- jsonWriter.WriteStringValue(nameServer.ToString());
- }
- jsonWriter.WriteEndArray();
- }
- break;
- }
- //update
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Secondary:
- case AuthZoneType.SecondaryForwarder:
- case AuthZoneType.Forwarder:
- jsonWriter.WriteString("update", zoneInfo.Update.ToString());
- jsonWriter.WritePropertyName("updateNetworkACL");
- {
- jsonWriter.WriteStartArray();
- if (zoneInfo.UpdateNetworkACL is not null)
- {
- foreach (NetworkAccessControl nac in zoneInfo.UpdateNetworkACL)
- jsonWriter.WriteStringValue(nac.ToString());
- }
- jsonWriter.WriteEndArray();
- }
- break;
- }
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Forwarder:
- jsonWriter.WritePropertyName("updateSecurityPolicies");
- {
- jsonWriter.WriteStartArray();
- if (zoneInfo.UpdateSecurityPolicies is not null)
- {
- foreach (KeyValuePair<string, IReadOnlyDictionary<string, IReadOnlyList<DnsResourceRecordType>>> updateSecurityPolicy in zoneInfo.UpdateSecurityPolicies)
- {
- foreach (KeyValuePair<string, IReadOnlyList<DnsResourceRecordType>> policy in updateSecurityPolicy.Value)
- {
- jsonWriter.WriteStartObject();
- jsonWriter.WriteString("tsigKeyName", updateSecurityPolicy.Key);
- jsonWriter.WriteString("domain", policy.Key);
- jsonWriter.WritePropertyName("allowedTypes");
- jsonWriter.WriteStartArray();
- foreach (DnsResourceRecordType allowedType in policy.Value)
- jsonWriter.WriteStringValue(allowedType.ToString());
- jsonWriter.WriteEndArray();
- jsonWriter.WriteEndObject();
- }
- }
- }
- jsonWriter.WriteEndArray();
- }
- break;
- }
- if (includeAvailableCatalogZoneNames)
- {
- IReadOnlyList<AuthZoneInfo> catalogZoneInfoList = _dnsWebService.DnsServer.AuthZoneManager.GetCatalogZones(delegate (AuthZoneInfo catalogZoneInfo)
- {
- return !catalogZoneInfo.Disabled && _dnsWebService._authManager.IsPermitted(PermissionSection.Zones, catalogZoneInfo.Name, session.User, PermissionFlag.Modify);
- });
- jsonWriter.WritePropertyName("availableCatalogZoneNames");
- jsonWriter.WriteStartArray();
- foreach (AuthZoneInfo catalogZoneInfo in catalogZoneInfoList)
- jsonWriter.WriteStringValue(catalogZoneInfo.Name);
- jsonWriter.WriteEndArray();
- }
- if (includeAvailableTsigKeyNames)
- {
- jsonWriter.WritePropertyName("availableTsigKeyNames");
- {
- jsonWriter.WriteStartArray();
- if (_dnsWebService.DnsServer.TsigKeys is not null)
- {
- foreach (KeyValuePair<string, TsigKey> tsigKey in _dnsWebService.DnsServer.TsigKeys)
- jsonWriter.WriteStringValue(tsigKey.Key);
- }
- jsonWriter.WriteEndArray();
- }
- }
- }
- public void SetZoneOptions(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- HttpRequest request = context.Request;
- string zoneName = request.GetQueryOrFormAlt("zone", "domain").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- AuthZoneInfo zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(zoneName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("No such zone was found: " + zoneName);
- if (zoneInfo.Internal)
- throw new DnsWebServiceException("Access was denied to manage internal DNS Server zone.");
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- if (request.TryGetQueryOrForm("disabled", bool.Parse, out bool disabled))
- zoneInfo.Disabled = disabled;
- //catalog zone override options
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Forwarder:
- {
- if (request.TryGetQueryOrForm("overrideCatalogQueryAccess", bool.Parse, out bool overrideCatalogQueryAccess))
- zoneInfo.OverrideCatalogQueryAccess = overrideCatalogQueryAccess;
- if (request.TryGetQueryOrForm("overrideCatalogZoneTransfer", bool.Parse, out bool overrideCatalogZoneTransfer))
- zoneInfo.OverrideCatalogZoneTransfer = overrideCatalogZoneTransfer;
- if (request.TryGetQueryOrForm("overrideCatalogNotify", bool.Parse, out bool overrideCatalogNotify))
- zoneInfo.OverrideCatalogNotify = overrideCatalogNotify;
- }
- break;
- case AuthZoneType.Stub:
- {
- if (zoneInfo.ApexZone.SecondaryCatalogZone is not null)
- break; //cannot set option for Stub zone that is a member of Secondary Catalog Zone
- if (request.TryGetQueryOrForm("overrideCatalogQueryAccess", bool.Parse, out bool overrideCatalogQueryAccess))
- zoneInfo.OverrideCatalogQueryAccess = overrideCatalogQueryAccess;
- }
- break;
- }
- //primary server
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Secondary:
- case AuthZoneType.SecondaryForwarder:
- case AuthZoneType.SecondaryCatalog:
- {
- if (zoneInfo.ApexZone.SecondaryCatalogZone is not null)
- break; //cannot set option for zone that is a member of Secondary Catalog Zone
- if (request.TryGetQueryOrFormEnum("primaryZoneTransferProtocol", out DnsTransportProtocol primaryZoneTransferProtocol))
- {
- if (primaryZoneTransferProtocol == DnsTransportProtocol.Quic)
- DnsWebService.ValidateQuicSupport();
- zoneInfo.PrimaryZoneTransferProtocol = primaryZoneTransferProtocol;
- }
- string primaryNameServerAddresses = request.QueryOrForm("primaryNameServerAddresses");
- if (primaryNameServerAddresses is not null)
- {
- if (primaryNameServerAddresses.Length == 0)
- {
- zoneInfo.PrimaryNameServerAddresses = null;
- }
- else
- {
- zoneInfo.PrimaryNameServerAddresses = primaryNameServerAddresses.Split(delegate (string address)
- {
- NameServerAddress nameServer = NameServerAddress.Parse(address);
- if (nameServer.Protocol != primaryZoneTransferProtocol)
- nameServer = nameServer.ChangeProtocol(primaryZoneTransferProtocol);
- return nameServer;
- }, ',');
- }
- }
- string primaryZoneTransferTsigKeyName = request.QueryOrForm("primaryZoneTransferTsigKeyName");
- if (primaryZoneTransferTsigKeyName is not null)
- {
- if (primaryZoneTransferTsigKeyName.Length == 0)
- zoneInfo.PrimaryZoneTransferTsigKeyName = null;
- else
- zoneInfo.PrimaryZoneTransferTsigKeyName = primaryZoneTransferTsigKeyName;
- }
- }
- break;
- case AuthZoneType.Stub:
- {
- if (zoneInfo.ApexZone.SecondaryCatalogZone is not null)
- break; //cannot set option for Stub zone that is a member of Secondary Catalog Zone
- string primaryNameServerAddresses = request.QueryOrForm("primaryNameServerAddresses");
- if (primaryNameServerAddresses is not null)
- {
- if (primaryNameServerAddresses.Length == 0)
- {
- zoneInfo.PrimaryNameServerAddresses = null;
- }
- else
- {
- zoneInfo.PrimaryNameServerAddresses = primaryNameServerAddresses.Split(delegate (string address)
- {
- NameServerAddress nameServer = NameServerAddress.Parse(address);
- if (nameServer.Protocol != DnsTransportProtocol.Udp)
- nameServer = nameServer.ChangeProtocol(DnsTransportProtocol.Udp);
- return nameServer;
- }, ',');
- }
- }
- }
- break;
- }
- if (zoneInfo.Type == AuthZoneType.Secondary)
- {
- if (zoneInfo.ApexZone.SecondaryCatalogZone is not null)
- {
- //cannot set option for zone that is a member of Secondary Catalog Zone
- }
- else if (request.TryGetQueryOrForm("validateZone", bool.Parse, out bool validateZone))
- {
- zoneInfo.ValidateZone = validateZone;
- }
- }
- //query access
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Secondary:
- case AuthZoneType.Stub:
- case AuthZoneType.Forwarder:
- case AuthZoneType.SecondaryForwarder:
- case AuthZoneType.Catalog:
- if (zoneInfo.ApexZone.SecondaryCatalogZone is not null)
- break; //cannot set option for zone that is a member of Secondary Catalog Zone
- string queryAccessNetworkACL = request.QueryOrForm("queryAccessNetworkACL");
- if (queryAccessNetworkACL is not null)
- {
- if ((queryAccessNetworkACL.Length == 0) || queryAccessNetworkACL.Equals("false", StringComparison.OrdinalIgnoreCase))
- zoneInfo.QueryAccessNetworkACL = null;
- else
- zoneInfo.QueryAccessNetworkACL = queryAccessNetworkACL.Split(NetworkAccessControl.Parse, ',');
- }
- if (request.TryGetQueryOrFormEnum("queryAccess", out AuthZoneQueryAccess queryAccess))
- zoneInfo.QueryAccess = queryAccess;
- break;
- }
- //zone transfer
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Secondary:
- case AuthZoneType.Forwarder:
- case AuthZoneType.Catalog:
- if (zoneInfo.ApexZone.SecondaryCatalogZone is not null)
- break; //cannot set option for zone that is a member of Secondary Catalog Zone
- string strZoneTransferNetworkACL = request.QueryOrForm("zoneTransferNetworkACL");
- if (strZoneTransferNetworkACL is not null)
- {
- if ((strZoneTransferNetworkACL.Length == 0) || strZoneTransferNetworkACL.Equals("false", StringComparison.OrdinalIgnoreCase))
- zoneInfo.ZoneTransferNetworkACL = null;
- else
- zoneInfo.ZoneTransferNetworkACL = strZoneTransferNetworkACL.Split(NetworkAccessControl.Parse, ',');
- }
- if (request.TryGetQueryOrFormEnum("zoneTransfer", out AuthZoneTransfer zoneTransfer))
- zoneInfo.ZoneTransfer = zoneTransfer;
- string strZoneTransferTsigKeyNames = request.QueryOrForm("zoneTransferTsigKeyNames");
- if (strZoneTransferTsigKeyNames is not null)
- {
- if ((strZoneTransferTsigKeyNames.Length == 0) || strZoneTransferTsigKeyNames.Equals("false", StringComparison.OrdinalIgnoreCase))
- {
- zoneInfo.ZoneTransferTsigKeyNames = null;
- }
- else
- {
- string[] strZoneTransferTsigKeyNamesParts = strZoneTransferTsigKeyNames.Split(_commaSeparator, StringSplitOptions.RemoveEmptyEntries);
- Dictionary<string, object> zoneTransferTsigKeyNames = new Dictionary<string, object>(strZoneTransferTsigKeyNamesParts.Length);
- for (int i = 0; i < strZoneTransferTsigKeyNamesParts.Length; i++)
- zoneTransferTsigKeyNames.Add(strZoneTransferTsigKeyNamesParts[i].TrimEnd('.').ToLowerInvariant(), null);
- zoneInfo.ZoneTransferTsigKeyNames = zoneTransferTsigKeyNames;
- }
- }
- break;
- }
- //notify
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Secondary:
- case AuthZoneType.Forwarder:
- case AuthZoneType.Catalog:
- if (request.TryGetQueryOrFormEnum("notify", out AuthZoneNotify notify))
- zoneInfo.Notify = notify;
- string strNotifyNameServers = request.QueryOrForm("notifyNameServers");
- if (strNotifyNameServers is not null)
- {
- if ((strNotifyNameServers.Length == 0) || strNotifyNameServers.Equals("false", StringComparison.OrdinalIgnoreCase))
- zoneInfo.NotifyNameServers = null;
- else
- zoneInfo.NotifyNameServers = strNotifyNameServers.Split(IPAddress.Parse, ',');
- }
- if (zoneInfo.Type == AuthZoneType.Catalog)
- {
- string strNotifySecondaryCatalogNameServers = request.QueryOrForm("notifySecondaryCatalogsNameServers");
- if (strNotifySecondaryCatalogNameServers is not null)
- {
- if ((strNotifySecondaryCatalogNameServers.Length == 0) || strNotifySecondaryCatalogNameServers.Equals("false", StringComparison.OrdinalIgnoreCase))
- zoneInfo.NotifySecondaryCatalogNameServers = null;
- else
- zoneInfo.NotifySecondaryCatalogNameServers = strNotifySecondaryCatalogNameServers.Split(IPAddress.Parse, ',');
- }
- }
- break;
- }
- //update
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Secondary:
- case AuthZoneType.SecondaryForwarder:
- case AuthZoneType.Forwarder:
- if (request.TryGetQueryOrFormEnum("update", out AuthZoneUpdate update))
- zoneInfo.Update = update;
- string strUpdateNetworkACL = request.QueryOrForm("updateNetworkACL");
- if (strUpdateNetworkACL is not null)
- {
- if ((strUpdateNetworkACL.Length == 0) || strUpdateNetworkACL.Equals("false", StringComparison.OrdinalIgnoreCase))
- zoneInfo.UpdateNetworkACL = null;
- else
- zoneInfo.UpdateNetworkACL = strUpdateNetworkACL.Split(NetworkAccessControl.Parse, ',');
- }
- break;
- }
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Forwarder:
- string strUpdateSecurityPolicies = request.QueryOrForm("updateSecurityPolicies");
- if (strUpdateSecurityPolicies is not null)
- {
- if ((strUpdateSecurityPolicies.Length == 0) || strUpdateSecurityPolicies.Equals("false", StringComparison.OrdinalIgnoreCase))
- {
- zoneInfo.UpdateSecurityPolicies = null;
- }
- else
- {
- string[] strUpdateSecurityPoliciesParts = strUpdateSecurityPolicies.Split(_pipeSeparator, StringSplitOptions.RemoveEmptyEntries);
- Dictionary<string, IReadOnlyDictionary<string, IReadOnlyList<DnsResourceRecordType>>> updateSecurityPolicies = new Dictionary<string, IReadOnlyDictionary<string, IReadOnlyList<DnsResourceRecordType>>>(strUpdateSecurityPoliciesParts.Length);
- for (int i = 0; i < strUpdateSecurityPoliciesParts.Length; i += 3)
- {
- string tsigKeyName = strUpdateSecurityPoliciesParts[i].TrimEnd('.').ToLowerInvariant();
- string domain = strUpdateSecurityPoliciesParts[i + 1].TrimEnd('.').ToLowerInvariant();
- string strTypes = strUpdateSecurityPoliciesParts[i + 2];
- if (!domain.Equals(zoneInfo.Name, StringComparison.OrdinalIgnoreCase) && !domain.EndsWith("." + zoneInfo.Name, StringComparison.OrdinalIgnoreCase))
- throw new DnsWebServiceException("Cannot set Dynamic Updates security policies: the domain '" + domain + "' must be part of the current zone.");
- if (!updateSecurityPolicies.TryGetValue(tsigKeyName, out IReadOnlyDictionary<string, IReadOnlyList<DnsResourceRecordType>> policyMap))
- {
- policyMap = new Dictionary<string, IReadOnlyList<DnsResourceRecordType>>();
- updateSecurityPolicies.Add(tsigKeyName, policyMap);
- }
- if (!policyMap.TryGetValue(domain, out IReadOnlyList<DnsResourceRecordType> types))
- {
- types = new List<DnsResourceRecordType>();
- (policyMap as Dictionary<string, IReadOnlyList<DnsResourceRecordType>>).Add(domain, types);
- }
- foreach (string strType in strTypes.Split(_commaSpaceSeparator, StringSplitOptions.RemoveEmptyEntries))
- (types as List<DnsResourceRecordType>).Add(Enum.Parse<DnsResourceRecordType>(strType, true));
- }
- zoneInfo.UpdateSecurityPolicies = updateSecurityPolicies;
- }
- }
- break;
- }
- //catalog zone; done last to allow using updated properties when there is change of ownership
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Stub:
- case AuthZoneType.Forwarder:
- if (zoneInfo.ApexZone.SecondaryCatalogZone is not null)
- break; //cannot set option for Stub zone that is a member of Secondary Catalog Zone
- string catalogZoneName = request.QueryOrForm("catalog");
- if (catalogZoneName is not null)
- {
- string oldCatalogZoneName = zoneInfo.CatalogZoneName;
- if (catalogZoneName.Length == 0)
- {
- if (!string.IsNullOrEmpty(oldCatalogZoneName))
- _dnsWebService.DnsServer.AuthZoneManager.RemoveCatalogMemberZone(zoneInfo);
- }
- else
- {
- if (string.IsNullOrEmpty(oldCatalogZoneName))
- {
- //check catalog permissions
- AuthZoneInfo catalogZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(catalogZoneName);
- if (catalogZoneInfo is null)
- throw new DnsWebServiceException("No such Catalog zone was found: " + catalogZoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, catalogZoneInfo.Name, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied to use Catalog zone: " + catalogZoneInfo.Name);
- _dnsWebService.DnsServer.AuthZoneManager.AddCatalogMemberZone(catalogZoneName, zoneInfo);
- }
- else if (!catalogZoneName.Equals(oldCatalogZoneName, StringComparison.OrdinalIgnoreCase))
- {
- //check catalog permissions
- AuthZoneInfo catalogZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(catalogZoneName);
- if (catalogZoneInfo is null)
- throw new DnsWebServiceException("No such Catalog zone was found: " + catalogZoneName);
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, catalogZoneInfo.Name, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied to use Catalog zone: " + catalogZoneInfo.Name);
- _dnsWebService.DnsServer.AuthZoneManager.ChangeCatalogMemberZoneOwnership(zoneInfo, catalogZoneName);
- }
- }
- }
- if (zoneInfo.ApexZone.CatalogZone is not null)
- _dnsWebService.DnsServer.AuthZoneManager.SaveZoneFile(zoneInfo.ApexZone.CatalogZoneName);
- break;
- }
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] " + zoneInfo.TypeName + " zone options were updated successfully: " + zoneInfo.DisplayName);
- _dnsWebService.DnsServer.AuthZoneManager.SaveZoneFile(zoneInfo.Name);
- }
- public void ResyncZone(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- string zoneName = context.Request.GetQueryOrFormAlt("zone", "domain").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- AuthZoneInfo zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(zoneName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("No such zone was found: " + zoneName);
- if (zoneInfo.Internal)
- throw new DnsWebServiceException("Access was denied to manage internal DNS Server zone.");
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Secondary:
- case AuthZoneType.SecondaryForwarder:
- case AuthZoneType.SecondaryCatalog:
- case AuthZoneType.Stub:
- zoneInfo.TriggerResync();
- break;
- default:
- throw new DnsWebServiceException("Only Secondary, Secondary Forwarder, Secondary Catalog, and Stub zones support resync.");
- }
- }
- public void AddRecord(HttpContext context)
- {
- HttpRequest request = context.Request;
- string domain = request.GetQueryOrForm("domain").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(domain))
- domain = DnsClient.ConvertDomainNameToAscii(domain);
- string zoneName = request.QueryOrForm("zone");
- if (zoneName is not null)
- {
- zoneName = zoneName.TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- }
- AuthZoneInfo zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.FindAuthZoneInfo(string.IsNullOrEmpty(zoneName) ? domain : zoneName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("No such zone was found: " + domain);
- if (zoneInfo.Internal)
- throw new DnsWebServiceException("Access was denied to manage internal DNS Server zone.");
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- DnsResourceRecordType type = request.GetQueryOrFormEnum<DnsResourceRecordType>("type");
- uint ttl = request.GetQueryOrForm("ttl", uint.Parse, _defaultRecordTtl);
- bool overwrite = request.GetQueryOrForm("overwrite", bool.Parse, false);
- string comments = request.QueryOrForm("comments");
- uint expiryTtl = request.GetQueryOrForm("expiryTtl", uint.Parse, 0u);
- DnsResourceRecord newRecord;
- switch (type)
- {
- case DnsResourceRecordType.A:
- case DnsResourceRecordType.AAAA:
- {
- string strIPAddress = request.GetQueryOrFormAlt("ipAddress", "value");
- IPAddress ipAddress;
- if (strIPAddress.Equals("request-ip-address"))
- ipAddress = context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader).Address;
- else
- ipAddress = IPAddress.Parse(strIPAddress);
- bool ptr = request.GetQueryOrForm("ptr", bool.Parse, false);
- if (ptr)
- {
- string ptrDomain = Zone.GetReverseZone(ipAddress, type == DnsResourceRecordType.A ? 32 : 128);
- AuthZoneInfo reverseZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.FindAuthZoneInfo(ptrDomain);
- if (reverseZoneInfo is null)
- {
- bool createPtrZone = request.GetQueryOrForm("createPtrZone", bool.Parse, false);
- if (!createPtrZone)
- throw new DnsWebServiceException("No reverse zone available to add PTR record.");
- string ptrZone = Zone.GetReverseZone(ipAddress, type == DnsResourceRecordType.A ? 24 : 64);
- reverseZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.CreatePrimaryZone(ptrZone);
- if (reverseZoneInfo == null)
- throw new DnsWebServiceException("Failed to create reverse zone to add PTR record: " + ptrZone);
- //set permissions
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, reverseZoneInfo.Name, session.User, PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, reverseZoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, reverseZoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.DNS_ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SaveConfigFile();
- }
- if (reverseZoneInfo.Internal)
- throw new DnsWebServiceException("Reverse zone '" + reverseZoneInfo.DisplayName + "' is an internal zone.");
- if ((reverseZoneInfo.Type != AuthZoneType.Primary) && (reverseZoneInfo.Type != AuthZoneType.Forwarder))
- throw new DnsWebServiceException("Reverse zone '" + reverseZoneInfo.DisplayName + "' is not a primary or forwarder zone.");
- DnsResourceRecord ptrRecord = new DnsResourceRecord(ptrDomain, DnsResourceRecordType.PTR, DnsClass.IN, ttl, new DnsPTRRecordData(domain));
- ptrRecord.GetAuthGenericRecordInfo().LastModified = DateTime.UtcNow;
- ptrRecord.GetAuthGenericRecordInfo().ExpiryTtl = expiryTtl;
- _dnsWebService.DnsServer.AuthZoneManager.SetRecord(reverseZoneInfo.Name, ptrRecord);
- _dnsWebService.DnsServer.AuthZoneManager.SaveZoneFile(reverseZoneInfo.Name);
- }
- if (type == DnsResourceRecordType.A)
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsARecordData(ipAddress));
- else
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsAAAARecordData(ipAddress));
- }
- break;
- case DnsResourceRecordType.NS:
- {
- string nameServer = request.GetQueryOrFormAlt("nameServer", "value").TrimEnd('.');
- string glueAddresses = request.GetQueryOrForm("glue", null);
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsNSRecordData(nameServer));
- if (!string.IsNullOrEmpty(glueAddresses))
- newRecord.SetGlueRecords(glueAddresses);
- }
- break;
- case DnsResourceRecordType.CNAME:
- {
- if (!overwrite)
- {
- IReadOnlyList<DnsResourceRecord> existingRecords = _dnsWebService.DnsServer.AuthZoneManager.GetRecords(zoneInfo.Name, domain, type);
- if (existingRecords.Count > 0)
- throw new DnsWebServiceException("Record already exists. Use overwrite option if you wish to overwrite existing record.");
- }
- string cname = request.GetQueryOrFormAlt("cname", "value").TrimEnd('.');
- if (cname.Equals(domain, StringComparison.OrdinalIgnoreCase))
- throw new DnsWebServiceException("CNAME domain name cannot be same as that of the record name.");
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsCNAMERecordData(cname));
- overwrite = true; //force SetRecord
- }
- break;
- case DnsResourceRecordType.PTR:
- {
- string ptrName = request.GetQueryOrFormAlt("ptrName", "value").TrimEnd('.');
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsPTRRecordData(ptrName));
- }
- break;
- case DnsResourceRecordType.MX:
- {
- ushort preference = request.GetQueryOrForm("preference", ushort.Parse);
- string exchange = request.GetQueryOrFormAlt("exchange", "value").TrimEnd('.');
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsMXRecordData(preference, exchange));
- }
- break;
- case DnsResourceRecordType.TXT:
- {
- string text = request.GetQueryOrFormAlt("text", "value");
- bool splitText = request.GetQueryOrForm("splitText", bool.Parse, false);
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, splitText ? new DnsTXTRecordData(DecodeCharacterStrings(text)) : new DnsTXTRecordData(text));
- }
- break;
- case DnsResourceRecordType.RP:
- {
- string mailbox = request.GetQueryOrForm("mailbox", "").TrimEnd('.');
- string txtDomain = request.GetQueryOrForm("txtDomain", "").TrimEnd('.');
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsRPRecordData(mailbox, txtDomain));
- }
- break;
- case DnsResourceRecordType.SRV:
- {
- ushort priority = request.GetQueryOrForm("priority", ushort.Parse);
- ushort weight = request.GetQueryOrForm("weight", ushort.Parse);
- ushort port = request.GetQueryOrForm("port", ushort.Parse);
- string target = request.GetQueryOrFormAlt("target", "value").TrimEnd('.');
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsSRVRecordData(priority, weight, port, target));
- }
- break;
- case DnsResourceRecordType.NAPTR:
- {
- ushort order = request.GetQueryOrForm("naptrOrder", ushort.Parse);
- ushort preference = request.GetQueryOrForm("naptrPreference", ushort.Parse);
- string flags = request.GetQueryOrForm("naptrFlags", "");
- string services = request.GetQueryOrForm("naptrServices", "");
- string regexp = request.GetQueryOrForm("naptrRegexp", "");
- string replacement = request.GetQueryOrForm("naptrReplacement", "").TrimEnd('.');
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsNAPTRRecordData(order, preference, flags, services, regexp, replacement));
- }
- break;
- case DnsResourceRecordType.DNAME:
- {
- if (!overwrite)
- {
- IReadOnlyList<DnsResourceRecord> existingRecords = _dnsWebService.DnsServer.AuthZoneManager.GetRecords(zoneInfo.Name, domain, type);
- if (existingRecords.Count > 0)
- throw new DnsWebServiceException("Record already exists. Use overwrite option if you wish to overwrite existing record.");
- }
- string dname = request.GetQueryOrFormAlt("dname", "value").TrimEnd('.');
- if (dname.EndsWith("." + domain, StringComparison.OrdinalIgnoreCase))
- throw new DnsWebServiceException("DNAME domain name cannot be a sub domain of the record name.");
- if (dname.Equals(domain, StringComparison.OrdinalIgnoreCase))
- throw new DnsWebServiceException("DNAME domain name cannot be same as that of the record name.");
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsDNAMERecordData(dname));
- overwrite = true; //force SetRecord
- }
- break;
- case DnsResourceRecordType.DS:
- {
- ushort keyTag = request.GetQueryOrForm("keyTag", ushort.Parse);
- DnssecAlgorithm algorithm = Enum.Parse<DnssecAlgorithm>(request.GetQueryOrForm("algorithm").Replace('-', '_'), true);
- DnssecDigestType digestType = Enum.Parse<DnssecDigestType>(request.GetQueryOrForm("digestType").Replace('-', '_'), true);
- byte[] digest = request.GetQueryOrFormAlt("digest", "value", Convert.FromHexString);
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsDSRecordData(keyTag, algorithm, digestType, digest));
- }
- break;
- case DnsResourceRecordType.SSHFP:
- {
- DnsSSHFPAlgorithm sshfpAlgorithm = request.GetQueryOrFormEnum<DnsSSHFPAlgorithm>("sshfpAlgorithm");
- DnsSSHFPFingerprintType sshfpFingerprintType = request.GetQueryOrFormEnum<DnsSSHFPFingerprintType>("sshfpFingerprintType");
- byte[] sshfpFingerprint = request.GetQueryOrForm("sshfpFingerprint", Convert.FromHexString);
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsSSHFPRecordData(sshfpAlgorithm, sshfpFingerprintType, sshfpFingerprint));
- }
- break;
- case DnsResourceRecordType.TLSA:
- {
- DnsTLSACertificateUsage tlsaCertificateUsage = Enum.Parse<DnsTLSACertificateUsage>(request.GetQueryOrForm("tlsaCertificateUsage").Replace('-', '_'), true);
- DnsTLSASelector tlsaSelector = request.GetQueryOrFormEnum<DnsTLSASelector>("tlsaSelector");
- DnsTLSAMatchingType tlsaMatchingType = Enum.Parse<DnsTLSAMatchingType>(request.GetQueryOrForm("tlsaMatchingType").Replace('-', '_'), true);
- string tlsaCertificateAssociationData = request.GetQueryOrForm("tlsaCertificateAssociationData");
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsTLSARecordData(tlsaCertificateUsage, tlsaSelector, tlsaMatchingType, tlsaCertificateAssociationData));
- }
- break;
- case DnsResourceRecordType.SVCB:
- case DnsResourceRecordType.HTTPS:
- {
- ushort svcPriority = request.GetQueryOrForm("svcPriority", ushort.Parse);
- string targetName = request.GetQueryOrForm("svcTargetName").TrimEnd('.');
- string strSvcParams = request.GetQueryOrForm("svcParams");
- bool autoIpv4Hint = request.GetQueryOrForm("autoIpv4Hint", bool.Parse, false);
- bool autoIpv6Hint = request.GetQueryOrForm("autoIpv6Hint", bool.Parse, false);
- Dictionary<DnsSvcParamKey, DnsSvcParamValue> svcParams;
- if (strSvcParams.Equals("false", StringComparison.OrdinalIgnoreCase))
- {
- svcParams = new Dictionary<DnsSvcParamKey, DnsSvcParamValue>(0);
- }
- else
- {
- string[] strSvcParamsParts = strSvcParams.Split('|');
- svcParams = new Dictionary<DnsSvcParamKey, DnsSvcParamValue>(strSvcParamsParts.Length / 2);
- for (int i = 0; i < strSvcParamsParts.Length; i += 2)
- {
- DnsSvcParamKey svcParamKey = Enum.Parse<DnsSvcParamKey>(strSvcParamsParts[i].Replace('-', '_'), true);
- DnsSvcParamValue svcParamValue = DnsSvcParamValue.Parse(svcParamKey, strSvcParamsParts[i + 1]);
- svcParams.Add(svcParamKey, svcParamValue);
- }
- }
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsSVCBRecordData(svcPriority, targetName, svcParams));
- if (autoIpv4Hint)
- newRecord.GetAuthSVCBRecordInfo().AutoIpv4Hint = true;
- if (autoIpv6Hint)
- newRecord.GetAuthSVCBRecordInfo().AutoIpv6Hint = true;
- if (autoIpv4Hint || autoIpv6Hint)
- ResolveSvcbAutoHints(zoneInfo.Name, newRecord, autoIpv4Hint, autoIpv6Hint, svcParams);
- }
- break;
- case DnsResourceRecordType.URI:
- {
- ushort priority = request.GetQueryOrForm("uriPriority", ushort.Parse);
- ushort weight = request.GetQueryOrForm("uriWeight", ushort.Parse);
- Uri uri = request.GetQueryOrForm("uri", delegate (string value) { return new Uri(value); });
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsURIRecordData(priority, weight, uri));
- }
- break;
- case DnsResourceRecordType.CAA:
- {
- byte flags = request.GetQueryOrForm("flags", byte.Parse);
- string tag = request.GetQueryOrForm("tag");
- string value = request.GetQueryOrForm("value");
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsCAARecordData(flags, tag, value));
- }
- break;
- case DnsResourceRecordType.ANAME:
- {
- string aname = request.GetQueryOrFormAlt("aname", "value").TrimEnd('.');
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsANAMERecordData(aname));
- }
- break;
- case DnsResourceRecordType.FWD:
- {
- DnsTransportProtocol protocol = request.GetQueryOrFormEnum("protocol", DnsTransportProtocol.Udp);
- string forwarder = request.GetQueryOrFormAlt("forwarder", "value");
- bool dnssecValidation = request.GetQueryOrForm("dnssecValidation", bool.Parse, false);
- DnsForwarderRecordProxyType proxyType = DnsForwarderRecordProxyType.DefaultProxy;
- string proxyAddress = null;
- ushort proxyPort = 0;
- string proxyUsername = null;
- string proxyPassword = null;
- if (!forwarder.Equals("this-server"))
- {
- proxyType = request.GetQueryOrFormEnum("proxyType", DnsForwarderRecordProxyType.DefaultProxy);
- switch (proxyType)
- {
- case DnsForwarderRecordProxyType.Http:
- case DnsForwarderRecordProxyType.Socks5:
- proxyAddress = request.GetQueryOrForm("proxyAddress");
- proxyPort = request.GetQueryOrForm("proxyPort", ushort.Parse);
- proxyUsername = request.QueryOrForm("proxyUsername");
- proxyPassword = request.QueryOrForm("proxyPassword");
- break;
- }
- }
- byte priority = request.GetQueryOrForm("forwarderPriority", byte.Parse, byte.MinValue);
- if (protocol == DnsTransportProtocol.Quic)
- DnsWebService.ValidateQuicSupport();
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsForwarderRecordData(protocol, forwarder, dnssecValidation, proxyType, proxyAddress, proxyPort, proxyUsername, proxyPassword, priority));
- }
- break;
- case DnsResourceRecordType.APP:
- {
- if (!overwrite)
- {
- IReadOnlyList<DnsResourceRecord> existingRecords = _dnsWebService.DnsServer.AuthZoneManager.GetRecords(zoneInfo.Name, domain, type);
- if (existingRecords.Count > 0)
- throw new DnsWebServiceException("Record already exists. Use overwrite option if you wish to overwrite existing record.");
- }
- string appName = request.GetQueryOrFormAlt("appName", "value");
- string classPath = request.GetQueryOrForm("classPath");
- string recordData = request.GetQueryOrForm("recordData", "");
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsApplicationRecordData(appName, classPath, recordData));
- overwrite = true; //force SetRecord
- }
- break;
- default:
- {
- string strRData = request.GetQueryOrForm("rdata");
- byte[] rdata;
- if (strRData.Contains(':'))
- rdata = strRData.ParseColonHexString();
- else
- rdata = Convert.FromHexString(strRData);
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, DnsResourceRecord.ReadRecordDataFrom(type, rdata));
- }
- break;
- }
- //update record info
- GenericRecordInfo recordInfo = newRecord.GetAuthGenericRecordInfo();
- recordInfo.LastModified = DateTime.UtcNow;
- recordInfo.ExpiryTtl = expiryTtl;
- if (!string.IsNullOrEmpty(comments))
- recordInfo.Comments = comments;
- //add record
- if (overwrite)
- _dnsWebService.DnsServer.AuthZoneManager.SetRecord(zoneInfo.Name, newRecord);
- else
- _dnsWebService.DnsServer.AuthZoneManager.AddRecord(zoneInfo.Name, newRecord);
- //additional processing
- if ((type == DnsResourceRecordType.A) || (type == DnsResourceRecordType.AAAA))
- {
- bool updateSvcbHints = request.GetQueryOrForm("updateSvcbHints", bool.Parse, false);
- if (updateSvcbHints)
- UpdateSvcbAutoHints(zoneInfo.Name, domain, type == DnsResourceRecordType.A, type == DnsResourceRecordType.AAAA);
- }
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] New record was added to " + zoneInfo.TypeName + " zone '" + zoneInfo.DisplayName + "' successfully {record: " + newRecord.ToString() + "}");
- //save zone
- _dnsWebService.DnsServer.AuthZoneManager.SaveZoneFile(zoneInfo.Name);
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- jsonWriter.WritePropertyName("zone");
- WriteZoneInfoAsJson(zoneInfo, jsonWriter);
- jsonWriter.WritePropertyName("addedRecord");
- WriteRecordAsJson(newRecord, jsonWriter, true, null);
- }
- public void GetRecords(HttpContext context)
- {
- HttpRequest request = context.Request;
- string domain = request.GetQueryOrForm("domain").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(domain))
- domain = DnsClient.ConvertDomainNameToAscii(domain);
- string zoneName = request.QueryOrForm("zone");
- if (zoneName is not null)
- {
- zoneName = zoneName.TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- }
- AuthZoneInfo zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.FindAuthZoneInfo(string.IsNullOrEmpty(zoneName) ? domain : zoneName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("No such zone was found: " + domain);
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
- bool listZone = request.GetQueryOrForm("listZone", bool.Parse, false);
- List<DnsResourceRecord> records = new List<DnsResourceRecord>();
- if (listZone)
- _dnsWebService.DnsServer.AuthZoneManager.ListAllZoneRecords(zoneInfo.Name, records);
- else
- _dnsWebService.DnsServer.AuthZoneManager.ListAllRecords(zoneInfo.Name, domain, records);
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- jsonWriter.WritePropertyName("zone");
- WriteZoneInfoAsJson(zoneInfo, jsonWriter);
- WriteRecordsAsJson(records, jsonWriter, true, zoneInfo);
- }
- public void DeleteRecord(HttpContext context)
- {
- HttpRequest request = context.Request;
- string domain = request.GetQueryOrForm("domain").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(domain))
- domain = DnsClient.ConvertDomainNameToAscii(domain);
- string zoneName = request.QueryOrForm("zone");
- if (zoneName is not null)
- {
- zoneName = zoneName.TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- }
- AuthZoneInfo zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.FindAuthZoneInfo(string.IsNullOrEmpty(zoneName) ? domain : zoneName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("No such zone was found: " + domain);
- if (zoneInfo.Internal)
- throw new DnsWebServiceException("Access was denied to manage internal DNS Server zone.");
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.Delete))
- throw new DnsWebServiceException("Access was denied.");
- DnsResourceRecordType type = request.GetQueryOrFormEnum<DnsResourceRecordType>("type");
- switch (type)
- {
- case DnsResourceRecordType.A:
- case DnsResourceRecordType.AAAA:
- {
- IPAddress ipAddress = IPAddress.Parse(request.GetQueryOrFormAlt("ipAddress", "value"));
- if (type == DnsResourceRecordType.A)
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, new DnsARecordData(ipAddress));
- else
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, new DnsAAAARecordData(ipAddress));
- string ptrDomain = Zone.GetReverseZone(ipAddress, type == DnsResourceRecordType.A ? 32 : 128);
- AuthZoneInfo reverseZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.FindAuthZoneInfo(ptrDomain);
- if ((reverseZoneInfo is not null) && !reverseZoneInfo.Internal && ((reverseZoneInfo.Type == AuthZoneType.Primary) || (reverseZoneInfo.Type == AuthZoneType.Forwarder)))
- {
- IReadOnlyList<DnsResourceRecord> ptrRecords = _dnsWebService.DnsServer.AuthZoneManager.GetRecords(reverseZoneInfo.Name, ptrDomain, DnsResourceRecordType.PTR);
- if (ptrRecords.Count > 0)
- {
- foreach (DnsResourceRecord ptrRecord in ptrRecords)
- {
- if ((ptrRecord.RDATA as DnsPTRRecordData).Domain.Equals(domain, StringComparison.OrdinalIgnoreCase))
- {
- //delete PTR record and save reverse zone
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(reverseZoneInfo.Name, ptrDomain, DnsResourceRecordType.PTR, ptrRecord.RDATA);
- _dnsWebService.DnsServer.AuthZoneManager.SaveZoneFile(reverseZoneInfo.Name);
- break;
- }
- }
- }
- }
- bool updateSvcbHints = request.GetQueryOrForm("updateSvcbHints", bool.Parse, false);
- if (updateSvcbHints)
- UpdateSvcbAutoHints(zoneInfo.Name, domain, type == DnsResourceRecordType.A, type == DnsResourceRecordType.AAAA);
- }
- break;
- case DnsResourceRecordType.NS:
- {
- string nameServer = request.GetQueryOrFormAlt("nameServer", "value").TrimEnd('.');
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, new DnsNSRecordData(nameServer, false));
- }
- break;
- case DnsResourceRecordType.CNAME:
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecords(zoneInfo.Name, domain, type);
- break;
- case DnsResourceRecordType.PTR:
- {
- string ptrName = request.GetQueryOrFormAlt("ptrName", "value").TrimEnd('.');
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, new DnsPTRRecordData(ptrName));
- }
- break;
- case DnsResourceRecordType.MX:
- {
- ushort preference = request.GetQueryOrForm("preference", ushort.Parse);
- string exchange = request.GetQueryOrFormAlt("exchange", "value").TrimEnd('.');
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, new DnsMXRecordData(preference, exchange));
- }
- break;
- case DnsResourceRecordType.TXT:
- {
- string text = request.GetQueryOrFormAlt("text", "value");
- bool splitText = request.GetQueryOrForm("splitText", bool.Parse, false);
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, splitText ? new DnsTXTRecordData(DecodeCharacterStrings(text)) : new DnsTXTRecordData(text));
- }
- break;
- case DnsResourceRecordType.RP:
- {
- string mailbox = request.GetQueryOrForm("mailbox", "").TrimEnd('.');
- string txtDomain = request.GetQueryOrForm("txtDomain", "").TrimEnd('.');
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, new DnsRPRecordData(mailbox, txtDomain));
- }
- break;
- case DnsResourceRecordType.SRV:
- {
- ushort priority = request.GetQueryOrForm("priority", ushort.Parse);
- ushort weight = request.GetQueryOrForm("weight", ushort.Parse);
- ushort port = request.GetQueryOrForm("port", ushort.Parse);
- string target = request.GetQueryOrFormAlt("target", "value").TrimEnd('.');
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, new DnsSRVRecordData(priority, weight, port, target));
- }
- break;
- case DnsResourceRecordType.NAPTR:
- {
- ushort order = request.GetQueryOrForm("naptrOrder", ushort.Parse);
- ushort preference = request.GetQueryOrForm("naptrPreference", ushort.Parse);
- string flags = request.GetQueryOrForm("naptrFlags", "");
- string services = request.GetQueryOrForm("naptrServices", "");
- string regexp = request.GetQueryOrForm("naptrRegexp", "");
- string replacement = request.GetQueryOrForm("naptrReplacement", "").TrimEnd('.');
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, new DnsNAPTRRecordData(order, preference, flags, services, regexp, replacement));
- }
- break;
- case DnsResourceRecordType.DNAME:
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecords(zoneInfo.Name, domain, type);
- break;
- case DnsResourceRecordType.DS:
- {
- ushort keyTag = request.GetQueryOrForm("keyTag", ushort.Parse);
- DnssecAlgorithm algorithm = Enum.Parse<DnssecAlgorithm>(request.GetQueryOrForm("algorithm").Replace('-', '_'), true);
- DnssecDigestType digestType = Enum.Parse<DnssecDigestType>(request.GetQueryOrForm("digestType").Replace('-', '_'), true);
- byte[] digest = Convert.FromHexString(request.GetQueryOrFormAlt("digest", "value"));
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, new DnsDSRecordData(keyTag, algorithm, digestType, digest));
- }
- break;
- case DnsResourceRecordType.SSHFP:
- {
- DnsSSHFPAlgorithm sshfpAlgorithm = request.GetQueryOrFormEnum<DnsSSHFPAlgorithm>("sshfpAlgorithm");
- DnsSSHFPFingerprintType sshfpFingerprintType = request.GetQueryOrFormEnum<DnsSSHFPFingerprintType>("sshfpFingerprintType");
- byte[] sshfpFingerprint = request.GetQueryOrForm("sshfpFingerprint", Convert.FromHexString);
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, new DnsSSHFPRecordData(sshfpAlgorithm, sshfpFingerprintType, sshfpFingerprint));
- }
- break;
- case DnsResourceRecordType.TLSA:
- {
- DnsTLSACertificateUsage tlsaCertificateUsage = Enum.Parse<DnsTLSACertificateUsage>(request.GetQueryOrForm("tlsaCertificateUsage").Replace('-', '_'), true);
- DnsTLSASelector tlsaSelector = request.GetQueryOrFormEnum<DnsTLSASelector>("tlsaSelector");
- DnsTLSAMatchingType tlsaMatchingType = Enum.Parse<DnsTLSAMatchingType>(request.GetQueryOrForm("tlsaMatchingType").Replace('-', '_'), true);
- string tlsaCertificateAssociationData = request.GetQueryOrForm("tlsaCertificateAssociationData");
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, new DnsTLSARecordData(tlsaCertificateUsage, tlsaSelector, tlsaMatchingType, tlsaCertificateAssociationData));
- }
- break;
- case DnsResourceRecordType.SVCB:
- case DnsResourceRecordType.HTTPS:
- {
- ushort svcPriority = request.GetQueryOrForm("svcPriority", ushort.Parse);
- string targetName = request.GetQueryOrForm("svcTargetName").TrimEnd('.');
- string strSvcParams = request.GetQueryOrForm("svcParams");
- Dictionary<DnsSvcParamKey, DnsSvcParamValue> svcParams;
- if (strSvcParams.Equals("false", StringComparison.OrdinalIgnoreCase))
- {
- svcParams = new Dictionary<DnsSvcParamKey, DnsSvcParamValue>(0);
- }
- else
- {
- string[] strSvcParamsParts = strSvcParams.Split('|');
- svcParams = new Dictionary<DnsSvcParamKey, DnsSvcParamValue>(strSvcParamsParts.Length / 2);
- for (int i = 0; i < strSvcParamsParts.Length; i += 2)
- {
- DnsSvcParamKey svcParamKey = Enum.Parse<DnsSvcParamKey>(strSvcParamsParts[i].Replace('-', '_'), true);
- DnsSvcParamValue svcParamValue = DnsSvcParamValue.Parse(svcParamKey, strSvcParamsParts[i + 1]);
- svcParams.Add(svcParamKey, svcParamValue);
- }
- }
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, new DnsSVCBRecordData(svcPriority, targetName, svcParams));
- }
- break;
- case DnsResourceRecordType.URI:
- {
- ushort priority = request.GetQueryOrForm("uriPriority", ushort.Parse);
- ushort weight = request.GetQueryOrForm("uriWeight", ushort.Parse);
- Uri uri = request.GetQueryOrForm("uri", delegate (string value) { return new Uri(value); });
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, new DnsURIRecordData(priority, weight, uri));
- }
- break;
- case DnsResourceRecordType.CAA:
- {
- byte flags = request.GetQueryOrForm("flags", byte.Parse);
- string tag = request.GetQueryOrForm("tag");
- string value = request.GetQueryOrForm("value");
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, new DnsCAARecordData(flags, tag, value));
- }
- break;
- case DnsResourceRecordType.ANAME:
- {
- string aname = request.GetQueryOrFormAlt("aname", "value").TrimEnd('.');
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, new DnsANAMERecordData(aname));
- }
- break;
- case DnsResourceRecordType.FWD:
- {
- DnsTransportProtocol protocol = request.GetQueryOrFormEnum("protocol", DnsTransportProtocol.Udp);
- string forwarder = request.GetQueryOrFormAlt("forwarder", "value");
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, DnsForwarderRecordData.CreatePartialRecordData(protocol, forwarder));
- }
- break;
- case DnsResourceRecordType.APP:
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecords(zoneInfo.Name, domain, type);
- break;
- default:
- {
- string strRData = request.GetQueryOrForm("rdata", string.Empty);
- byte[] rdata;
- if (strRData.Contains(':'))
- rdata = strRData.ParseColonHexString();
- else
- rdata = Convert.FromHexString(strRData);
- if (!_dnsWebService.DnsServer.AuthZoneManager.DeleteRecord(zoneInfo.Name, domain, type, new DnsUnknownRecordData(rdata)))
- throw new DnsWebServiceException("Failed to delete the record.");
- }
- break;
- }
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Record was deleted from " + zoneInfo.TypeName + " zone '" + zoneInfo.DisplayName + "' successfully {domain: " + domain + "; type: " + type + ";}");
- _dnsWebService.DnsServer.AuthZoneManager.SaveZoneFile(zoneInfo.Name);
- }
- public void UpdateRecord(HttpContext context)
- {
- HttpRequest request = context.Request;
- string domain = request.GetQueryOrForm("domain").TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(domain))
- domain = DnsClient.ConvertDomainNameToAscii(domain);
- string zoneName = request.QueryOrForm("zone");
- if (zoneName is not null)
- {
- zoneName = zoneName.TrimEnd('.');
- if (DnsClient.IsDomainNameUnicode(zoneName))
- zoneName = DnsClient.ConvertDomainNameToAscii(zoneName);
- }
- AuthZoneInfo zoneInfo = _dnsWebService.DnsServer.AuthZoneManager.FindAuthZoneInfo(string.IsNullOrEmpty(zoneName) ? domain : zoneName);
- if (zoneInfo is null)
- throw new DnsWebServiceException("No such zone was found: " + domain);
- if (zoneInfo.Internal)
- throw new DnsWebServiceException("Access was denied to manage internal DNS Server zone.");
- UserSession session = context.GetCurrentSession();
- if (!_dnsWebService._authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
- string newDomain = request.GetQueryOrForm("newDomain", domain).TrimEnd('.');
- uint ttl = request.GetQueryOrForm("ttl", uint.Parse, _defaultRecordTtl);
- bool disable = request.GetQueryOrForm("disable", bool.Parse, false);
- string comments = request.QueryOrForm("comments");
- uint expiryTtl = request.GetQueryOrForm("expiryTtl", uint.Parse, 0u);
- DnsResourceRecordType type = request.GetQueryOrFormEnum<DnsResourceRecordType>("type");
- DnsResourceRecord oldRecord = null;
- DnsResourceRecord newRecord;
- switch (type)
- {
- case DnsResourceRecordType.A:
- case DnsResourceRecordType.AAAA:
- {
- IPAddress ipAddress = IPAddress.Parse(request.GetQueryOrFormAlt("ipAddress", "value"));
- IPAddress newIpAddress = IPAddress.Parse(request.GetQueryOrFormAlt("newIpAddress", "newValue", ipAddress.ToString()));
- bool ptr = request.GetQueryOrForm("ptr", bool.Parse, false);
- if (ptr)
- {
- string newPtrDomain = Zone.GetReverseZone(newIpAddress, type == DnsResourceRecordType.A ? 32 : 128);
- AuthZoneInfo newReverseZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.FindAuthZoneInfo(newPtrDomain);
- if (newReverseZoneInfo is null)
- {
- bool createPtrZone = request.GetQueryOrForm("createPtrZone", bool.Parse, false);
- if (!createPtrZone)
- throw new DnsWebServiceException("No reverse zone available to add PTR record.");
- string ptrZone = Zone.GetReverseZone(newIpAddress, type == DnsResourceRecordType.A ? 24 : 64);
- newReverseZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.CreatePrimaryZone(ptrZone);
- if (newReverseZoneInfo is null)
- throw new DnsWebServiceException("Failed to create reverse zone to add PTR record: " + ptrZone);
- //set permissions
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, newReverseZoneInfo.Name, session.User, PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, newReverseZoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SetPermission(PermissionSection.Zones, newReverseZoneInfo.Name, _dnsWebService._authManager.GetGroup(Group.DNS_ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _dnsWebService._authManager.SaveConfigFile();
- }
- if (newReverseZoneInfo.Internal)
- throw new DnsWebServiceException("Reverse zone '" + newReverseZoneInfo.DisplayName + "' is an internal zone.");
- if ((newReverseZoneInfo.Type != AuthZoneType.Primary) && (newReverseZoneInfo.Type != AuthZoneType.Forwarder))
- throw new DnsWebServiceException("Reverse zone '" + newReverseZoneInfo.DisplayName + "' is not a primary or forwarder zone.");
- string oldPtrDomain = Zone.GetReverseZone(ipAddress, type == DnsResourceRecordType.A ? 32 : 128);
- AuthZoneInfo oldReverseZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.FindAuthZoneInfo(oldPtrDomain);
- if ((oldReverseZoneInfo is not null) && !oldReverseZoneInfo.Internal && ((oldReverseZoneInfo.Type == AuthZoneType.Primary) || (oldReverseZoneInfo.Type == AuthZoneType.Forwarder)))
- {
- //delete old PTR record if any and save old reverse zone
- _dnsWebService.DnsServer.AuthZoneManager.DeleteRecords(oldReverseZoneInfo.Name, oldPtrDomain, DnsResourceRecordType.PTR);
- _dnsWebService.DnsServer.AuthZoneManager.SaveZoneFile(oldReverseZoneInfo.Name);
- }
- //add new PTR record and save reverse zone
- DnsResourceRecord ptrRecord = new DnsResourceRecord(newPtrDomain, DnsResourceRecordType.PTR, DnsClass.IN, ttl, new DnsPTRRecordData(domain));
- ptrRecord.GetAuthGenericRecordInfo().LastModified = DateTime.UtcNow;
- ptrRecord.GetAuthGenericRecordInfo().ExpiryTtl = expiryTtl;
- _dnsWebService.DnsServer.AuthZoneManager.SetRecord(newReverseZoneInfo.Name, ptrRecord);
- _dnsWebService.DnsServer.AuthZoneManager.SaveZoneFile(newReverseZoneInfo.Name);
- }
- if (type == DnsResourceRecordType.A)
- {
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsARecordData(ipAddress));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsARecordData(newIpAddress));
- }
- else
- {
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsAAAARecordData(ipAddress));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsAAAARecordData(newIpAddress));
- }
- }
- break;
- case DnsResourceRecordType.NS:
- {
- string nameServer = request.GetQueryOrFormAlt("nameServer", "value").TrimEnd('.');
- string newNameServer = request.GetQueryOrFormAlt("newNameServer", "newValue", nameServer).TrimEnd('.');
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsNSRecordData(nameServer));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsNSRecordData(newNameServer));
- if (request.TryGetQueryOrForm("glue", out string glueAddresses))
- newRecord.SetGlueRecords(glueAddresses);
- }
- break;
- case DnsResourceRecordType.CNAME:
- {
- string cname = request.GetQueryOrFormAlt("cname", "value").TrimEnd('.');
- if (cname.Equals(newDomain, StringComparison.OrdinalIgnoreCase))
- throw new DnsWebServiceException("CNAME domain name cannot be same as that of the record name.");
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsCNAMERecordData(cname));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsCNAMERecordData(cname));
- }
- break;
- case DnsResourceRecordType.SOA:
- {
- string primaryNameServer = request.GetQueryOrForm("primaryNameServer").TrimEnd('.');
- string responsiblePerson = request.GetQueryOrForm("responsiblePerson").TrimEnd('.');
- uint serial = request.GetQueryOrForm("serial", uint.Parse);
- uint refresh = request.GetQueryOrForm("refresh", uint.Parse);
- uint retry = request.GetQueryOrForm("retry", uint.Parse);
- uint expire = request.GetQueryOrForm("expire", uint.Parse);
- uint minimum = request.GetQueryOrForm("minimum", uint.Parse);
- newRecord = new DnsResourceRecord(domain, type, DnsClass.IN, ttl, new DnsSOARecordData(primaryNameServer, responsiblePerson, serial, refresh, retry, expire, minimum));
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Forwarder:
- case AuthZoneType.Catalog:
- {
- if (request.TryGetQueryOrForm("useSerialDateScheme", bool.Parse, out bool useSerialDateScheme))
- newRecord.GetAuthSOARecordInfo().UseSoaSerialDateScheme = useSerialDateScheme;
- }
- break;
- }
- }
- break;
- case DnsResourceRecordType.PTR:
- {
- string ptrName = request.GetQueryOrFormAlt("ptrName", "value").TrimEnd('.');
- string newPtrName = request.GetQueryOrFormAlt("newPtrName", "newValue", ptrName).TrimEnd('.');
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsPTRRecordData(ptrName));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsPTRRecordData(newPtrName));
- }
- break;
- case DnsResourceRecordType.MX:
- {
- ushort preference = request.GetQueryOrForm("preference", ushort.Parse);
- ushort newPreference = request.GetQueryOrForm("newPreference", ushort.Parse, preference);
- string exchange = request.GetQueryOrFormAlt("exchange", "value").TrimEnd('.');
- string newExchange = request.GetQueryOrFormAlt("newExchange", "newValue", exchange).TrimEnd('.');
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsMXRecordData(preference, exchange));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsMXRecordData(newPreference, newExchange));
- }
- break;
- case DnsResourceRecordType.TXT:
- {
- string text = request.GetQueryOrFormAlt("text", "value");
- string newText = request.GetQueryOrFormAlt("newText", "newValue", text);
- bool splitText = request.GetQueryOrForm("splitText", bool.Parse, false);
- bool newSplitText = request.GetQueryOrForm("newSplitText", bool.Parse, splitText);
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, splitText ? new DnsTXTRecordData(DecodeCharacterStrings(text)) : new DnsTXTRecordData(text));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, newSplitText ? new DnsTXTRecordData(DecodeCharacterStrings(newText)) : new DnsTXTRecordData(newText));
- }
- break;
- case DnsResourceRecordType.RP:
- {
- string mailbox = request.GetQueryOrForm("mailbox", "").TrimEnd('.');
- string newMailbox = request.GetQueryOrForm("newMailbox", mailbox).TrimEnd('.');
- string txtDomain = request.GetQueryOrForm("txtDomain", "").TrimEnd('.');
- string newTxtDomain = request.GetQueryOrForm("newTxtDomain", txtDomain).TrimEnd('.');
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsRPRecordData(mailbox, txtDomain));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsRPRecordData(newMailbox, newTxtDomain));
- }
- break;
- case DnsResourceRecordType.SRV:
- {
- ushort priority = request.GetQueryOrForm("priority", ushort.Parse);
- ushort newPriority = request.GetQueryOrForm("newPriority", ushort.Parse, priority);
- ushort weight = request.GetQueryOrForm("weight", ushort.Parse);
- ushort newWeight = request.GetQueryOrForm("newWeight", ushort.Parse, weight);
- ushort port = request.GetQueryOrForm("port", ushort.Parse);
- ushort newPort = request.GetQueryOrForm("newPort", ushort.Parse, port);
- string target = request.GetQueryOrFormAlt("target", "value").TrimEnd('.');
- string newTarget = request.GetQueryOrFormAlt("newTarget", "newValue", target).TrimEnd('.');
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsSRVRecordData(priority, weight, port, target));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsSRVRecordData(newPriority, newWeight, newPort, newTarget));
- }
- break;
- case DnsResourceRecordType.NAPTR:
- {
- ushort order = request.GetQueryOrForm("naptrOrder", ushort.Parse);
- ushort newOrder = request.GetQueryOrForm("naptrNewOrder", ushort.Parse, order);
- ushort preference = request.GetQueryOrForm("naptrPreference", ushort.Parse);
- ushort newPreference = request.GetQueryOrForm("naptrNewPreference", ushort.Parse, preference);
- string flags = request.GetQueryOrForm("naptrFlags", "");
- string newFlags = request.GetQueryOrForm("naptrNewFlags", flags);
- string services = request.GetQueryOrForm("naptrServices", "");
- string newServices = request.GetQueryOrForm("naptrNewServices", services);
- string regexp = request.GetQueryOrForm("naptrRegexp", "");
- string newRegexp = request.GetQueryOrForm("naptrNewRegexp", regexp);
- string replacement = request.GetQueryOrForm("naptrReplacement", "").TrimEnd('.');
- string newReplacement = request.GetQueryOrForm("naptrNewReplacement", replacement).TrimEnd('.');
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsNAPTRRecordData(order, preference, flags, services, regexp, replacement));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsNAPTRRecordData(newOrder, newPreference, newFlags, newServices, newRegexp, newReplacement));
- }
- break;
- case DnsResourceRecordType.DNAME:
- {
- string dname = request.GetQueryOrFormAlt("dname", "value").TrimEnd('.');
- if (dname.EndsWith("." + newDomain, StringComparison.OrdinalIgnoreCase))
- throw new DnsWebServiceException("DNAME domain name cannot be a sub domain of the record name.");
- if (dname.Equals(newDomain, StringComparison.OrdinalIgnoreCase))
- throw new DnsWebServiceException("DNAME domain name cannot be same as that of the record name.");
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsDNAMERecordData(dname));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsDNAMERecordData(dname));
- }
- break;
- case DnsResourceRecordType.DS:
- {
- ushort keyTag = request.GetQueryOrForm("keyTag", ushort.Parse);
- ushort newKeyTag = request.GetQueryOrForm("newKeyTag", ushort.Parse, keyTag);
- DnssecAlgorithm algorithm = Enum.Parse<DnssecAlgorithm>(request.GetQueryOrForm("algorithm").Replace('-', '_'), true);
- DnssecAlgorithm newAlgorithm = Enum.Parse<DnssecAlgorithm>(request.GetQueryOrForm("newAlgorithm", algorithm.ToString()).Replace('-', '_'), true);
- DnssecDigestType digestType = Enum.Parse<DnssecDigestType>(request.GetQueryOrForm("digestType").Replace('-', '_'), true);
- DnssecDigestType newDigestType = Enum.Parse<DnssecDigestType>(request.GetQueryOrForm("newDigestType", digestType.ToString()).Replace('-', '_'), true);
- byte[] digest = request.GetQueryOrFormAlt("digest", "value", Convert.FromHexString);
- byte[] newDigest = request.GetQueryOrFormAlt("newDigest", "newValue", Convert.FromHexString, digest);
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsDSRecordData(keyTag, algorithm, digestType, digest));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsDSRecordData(newKeyTag, newAlgorithm, newDigestType, newDigest));
- }
- break;
- case DnsResourceRecordType.SSHFP:
- {
- DnsSSHFPAlgorithm sshfpAlgorithm = request.GetQueryOrFormEnum<DnsSSHFPAlgorithm>("sshfpAlgorithm");
- DnsSSHFPAlgorithm newSshfpAlgorithm = request.GetQueryOrFormEnum("newSshfpAlgorithm", sshfpAlgorithm);
- DnsSSHFPFingerprintType sshfpFingerprintType = request.GetQueryOrFormEnum<DnsSSHFPFingerprintType>("sshfpFingerprintType");
- DnsSSHFPFingerprintType newSshfpFingerprintType = request.GetQueryOrFormEnum("newSshfpFingerprintType", sshfpFingerprintType);
- byte[] sshfpFingerprint = request.GetQueryOrForm("sshfpFingerprint", Convert.FromHexString);
- byte[] newSshfpFingerprint = request.GetQueryOrForm("newSshfpFingerprint", Convert.FromHexString, sshfpFingerprint);
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsSSHFPRecordData(sshfpAlgorithm, sshfpFingerprintType, sshfpFingerprint));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsSSHFPRecordData(newSshfpAlgorithm, newSshfpFingerprintType, newSshfpFingerprint));
- }
- break;
- case DnsResourceRecordType.TLSA:
- {
- DnsTLSACertificateUsage tlsaCertificateUsage = Enum.Parse<DnsTLSACertificateUsage>(request.GetQueryOrForm("tlsaCertificateUsage").Replace('-', '_'), true);
- DnsTLSACertificateUsage newTlsaCertificateUsage = Enum.Parse<DnsTLSACertificateUsage>(request.GetQueryOrForm("newTlsaCertificateUsage", tlsaCertificateUsage.ToString()).Replace('-', '_'), true);
- DnsTLSASelector tlsaSelector = request.GetQueryOrFormEnum<DnsTLSASelector>("tlsaSelector");
- DnsTLSASelector newTlsaSelector = request.GetQueryOrFormEnum("newTlsaSelector", tlsaSelector);
- DnsTLSAMatchingType tlsaMatchingType = Enum.Parse<DnsTLSAMatchingType>(request.GetQueryOrForm("tlsaMatchingType").Replace('-', '_'), true);
- DnsTLSAMatchingType newTlsaMatchingType = Enum.Parse<DnsTLSAMatchingType>(request.GetQueryOrForm("newTlsaMatchingType", tlsaMatchingType.ToString()).Replace('-', '_'), true);
- string tlsaCertificateAssociationData = request.GetQueryOrForm("tlsaCertificateAssociationData");
- string newTlsaCertificateAssociationData = request.GetQueryOrForm("newTlsaCertificateAssociationData", tlsaCertificateAssociationData);
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsTLSARecordData(tlsaCertificateUsage, tlsaSelector, tlsaMatchingType, tlsaCertificateAssociationData));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsTLSARecordData(newTlsaCertificateUsage, newTlsaSelector, newTlsaMatchingType, newTlsaCertificateAssociationData));
- }
- break;
- case DnsResourceRecordType.SVCB:
- case DnsResourceRecordType.HTTPS:
- {
- ushort svcPriority = request.GetQueryOrForm("svcPriority", ushort.Parse);
- ushort newSvcPriority = request.GetQueryOrForm("newSvcPriority", ushort.Parse, svcPriority);
- string targetName = request.GetQueryOrForm("svcTargetName").TrimEnd('.');
- string newTargetName = request.GetQueryOrForm("newSvcTargetName", targetName).TrimEnd('.');
- string strSvcParams = request.GetQueryOrForm("svcParams");
- string strNewSvcParams = request.GetQueryOrForm("newSvcParams", strSvcParams);
- bool autoIpv4Hint = request.GetQueryOrForm("autoIpv4Hint", bool.Parse, false);
- bool autoIpv6Hint = request.GetQueryOrForm("autoIpv6Hint", bool.Parse, false);
- Dictionary<DnsSvcParamKey, DnsSvcParamValue> svcParams;
- if (strSvcParams.Equals("false", StringComparison.OrdinalIgnoreCase))
- {
- svcParams = new Dictionary<DnsSvcParamKey, DnsSvcParamValue>(0);
- }
- else
- {
- string[] strSvcParamsParts = strSvcParams.Split('|');
- svcParams = new Dictionary<DnsSvcParamKey, DnsSvcParamValue>(strSvcParamsParts.Length / 2);
- for (int i = 0; i < strSvcParamsParts.Length; i += 2)
- {
- DnsSvcParamKey svcParamKey = Enum.Parse<DnsSvcParamKey>(strSvcParamsParts[i].Replace('-', '_'), true);
- DnsSvcParamValue svcParamValue = DnsSvcParamValue.Parse(svcParamKey, strSvcParamsParts[i + 1]);
- svcParams.Add(svcParamKey, svcParamValue);
- }
- }
- Dictionary<DnsSvcParamKey, DnsSvcParamValue> newSvcParams;
- if (strNewSvcParams.Equals("false", StringComparison.OrdinalIgnoreCase))
- {
- newSvcParams = new Dictionary<DnsSvcParamKey, DnsSvcParamValue>(0);
- }
- else
- {
- string[] strSvcParamsParts = strNewSvcParams.Split('|');
- newSvcParams = new Dictionary<DnsSvcParamKey, DnsSvcParamValue>(strSvcParamsParts.Length / 2);
- for (int i = 0; i < strSvcParamsParts.Length; i += 2)
- {
- DnsSvcParamKey svcParamKey = Enum.Parse<DnsSvcParamKey>(strSvcParamsParts[i].Replace('-', '_'), true);
- DnsSvcParamValue svcParamValue = DnsSvcParamValue.Parse(svcParamKey, strSvcParamsParts[i + 1]);
- newSvcParams.Add(svcParamKey, svcParamValue);
- }
- }
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsSVCBRecordData(svcPriority, targetName, svcParams));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsSVCBRecordData(newSvcPriority, newTargetName, newSvcParams));
- if (autoIpv4Hint)
- newRecord.GetAuthSVCBRecordInfo().AutoIpv4Hint = true;
- if (autoIpv6Hint)
- newRecord.GetAuthSVCBRecordInfo().AutoIpv6Hint = true;
- if (autoIpv4Hint || autoIpv6Hint)
- ResolveSvcbAutoHints(zoneInfo.Name, newRecord, autoIpv4Hint, autoIpv6Hint, newSvcParams);
- }
- break;
- case DnsResourceRecordType.URI:
- {
- ushort priority = request.GetQueryOrForm("uriPriority", ushort.Parse);
- ushort newPriority = request.GetQueryOrForm("newUriPriority", ushort.Parse, priority);
- ushort weight = request.GetQueryOrForm("uriWeight", ushort.Parse);
- ushort newWeight = request.GetQueryOrForm("newUriWeight", ushort.Parse, weight);
- Uri uri = request.GetQueryOrForm("uri", delegate (string value) { return new Uri(value); });
- Uri newUri = request.GetQueryOrForm("newUri", delegate (string value) { return new Uri(value); }, uri);
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsURIRecordData(priority, weight, uri));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsURIRecordData(newPriority, newWeight, newUri));
- }
- break;
- case DnsResourceRecordType.CAA:
- {
- byte flags = request.GetQueryOrForm("flags", byte.Parse);
- byte newFlags = request.GetQueryOrForm("newFlags", byte.Parse, flags);
- string tag = request.GetQueryOrForm("tag");
- string newTag = request.GetQueryOrForm("newTag", tag);
- string value = request.GetQueryOrForm("value");
- string newValue = request.GetQueryOrForm("newValue", value);
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsCAARecordData(flags, tag, value));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsCAARecordData(newFlags, newTag, newValue));
- }
- break;
- case DnsResourceRecordType.ANAME:
- {
- string aname = request.GetQueryOrFormAlt("aname", "value").TrimEnd('.');
- string newAName = request.GetQueryOrFormAlt("newAName", "newValue", aname).TrimEnd('.');
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsANAMERecordData(aname));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsANAMERecordData(newAName));
- }
- break;
- case DnsResourceRecordType.FWD:
- {
- DnsTransportProtocol protocol = request.GetQueryOrFormEnum("protocol", DnsTransportProtocol.Udp);
- DnsTransportProtocol newProtocol = request.GetQueryOrFormEnum("newProtocol", protocol);
- string forwarder = request.GetQueryOrFormAlt("forwarder", "value");
- string newForwarder = request.GetQueryOrFormAlt("newForwarder", "newValue", forwarder);
- bool dnssecValidation = request.GetQueryOrForm("dnssecValidation", bool.Parse, false);
- DnsForwarderRecordProxyType proxyType = DnsForwarderRecordProxyType.DefaultProxy;
- string proxyAddress = null;
- ushort proxyPort = 0;
- string proxyUsername = null;
- string proxyPassword = null;
- if (!newForwarder.Equals("this-server"))
- {
- proxyType = request.GetQueryOrFormEnum("proxyType", DnsForwarderRecordProxyType.DefaultProxy);
- switch (proxyType)
- {
- case DnsForwarderRecordProxyType.Http:
- case DnsForwarderRecordProxyType.Socks5:
- proxyAddress = request.GetQueryOrForm("proxyAddress");
- proxyPort = request.GetQueryOrForm("proxyPort", ushort.Parse);
- proxyUsername = request.QueryOrForm("proxyUsername");
- proxyPassword = request.QueryOrForm("proxyPassword");
- break;
- }
- }
- byte priority = request.GetQueryOrForm("forwarderPriority", byte.Parse, byte.MinValue);
- if (newProtocol == DnsTransportProtocol.Quic)
- DnsWebService.ValidateQuicSupport();
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, DnsForwarderRecordData.CreatePartialRecordData(protocol, forwarder));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, 0, new DnsForwarderRecordData(newProtocol, newForwarder, dnssecValidation, proxyType, proxyAddress, proxyPort, proxyUsername, proxyPassword, priority));
- }
- break;
- case DnsResourceRecordType.APP:
- {
- string appName = request.GetQueryOrFormAlt("appName", "value");
- string classPath = request.GetQueryOrForm("classPath");
- string recordData = request.GetQueryOrForm("recordData", "");
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsApplicationRecordData(appName, classPath, recordData));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsApplicationRecordData(appName, classPath, recordData));
- }
- break;
- default:
- {
- string strRData = request.GetQueryOrForm("rdata");
- string strNewRData = request.GetQueryOrForm("newRData", strRData);
- byte[] rdata;
- if (strRData.Contains(':'))
- rdata = strRData.ParseColonHexString();
- else
- rdata = Convert.FromHexString(strRData);
- byte[] newRData;
- if (strNewRData.Contains(':'))
- newRData = strNewRData.ParseColonHexString();
- else
- newRData = Convert.FromHexString(strNewRData);
- oldRecord = new DnsResourceRecord(domain, type, DnsClass.IN, 0, new DnsUnknownRecordData(rdata));
- newRecord = new DnsResourceRecord(newDomain, type, DnsClass.IN, ttl, new DnsUnknownRecordData(newRData));
- }
- break;
- }
- //update record info
- GenericRecordInfo recordInfo = newRecord.GetAuthGenericRecordInfo();
- recordInfo.LastModified = DateTime.UtcNow;
- recordInfo.ExpiryTtl = expiryTtl;
- recordInfo.Disabled = disable;
- recordInfo.Comments = comments;
- //update record
- if (type == DnsResourceRecordType.SOA)
- {
- //special SOA case
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- case AuthZoneType.Forwarder:
- case AuthZoneType.Catalog:
- _dnsWebService.DnsServer.AuthZoneManager.SetRecord(zoneInfo.Name, newRecord);
- break;
- }
- //get updated record to return json
- newRecord = zoneInfo.ApexZone.GetRecords(DnsResourceRecordType.SOA)[0];
- }
- else
- {
- _dnsWebService.DnsServer.AuthZoneManager.UpdateRecord(zoneInfo.Name, oldRecord, newRecord);
- }
- //additional processing
- if ((type == DnsResourceRecordType.A) || (type == DnsResourceRecordType.AAAA))
- {
- bool updateSvcbHints = request.GetQueryOrForm("updateSvcbHints", bool.Parse, false);
- if (updateSvcbHints)
- UpdateSvcbAutoHints(zoneInfo.Name, newDomain, type == DnsResourceRecordType.A, type == DnsResourceRecordType.AAAA);
- }
- _dnsWebService._log.Write(context.GetRemoteEndPoint(_dnsWebService._webServiceRealIpHeader), "[" + session.User.Username + "] Record was updated for " + zoneInfo.TypeName + " zone '" + zoneInfo.DisplayName + "' successfully {" + (oldRecord is null ? "" : "oldRecord: " + oldRecord.ToString() + "; ") + "newRecord: " + newRecord.ToString() + "}");
- //save zone
- _dnsWebService.DnsServer.AuthZoneManager.SaveZoneFile(zoneInfo.Name);
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
- jsonWriter.WritePropertyName("zone");
- WriteZoneInfoAsJson(zoneInfo, jsonWriter);
- jsonWriter.WritePropertyName("updatedRecord");
- WriteRecordAsJson(newRecord, jsonWriter, true, zoneInfo);
- }
- #endregion
- #region properties
- public uint DefaultRecordTtl
- {
- get { return _defaultRecordTtl; }
- set { _defaultRecordTtl = value; }
- }
- #endregion
- }
- }
|