/*
Technitium DNS Server
Copyright (C) 2022 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 .
*/
using DnsServerCore.Dns.Zones;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Net;
using TechnitiumLibrary.Net.Dns;
using TechnitiumLibrary.Net.Dns.ResourceRecords;
namespace DnsServerCore
{
class WebServiceOtherZonesApi
{
#region variables
readonly DnsWebService _dnsWebService;
#endregion
#region constructor
public WebServiceOtherZonesApi(DnsWebService dnsWebService)
{
_dnsWebService = dnsWebService;
}
#endregion
#region public
#region cache api
public void FlushCache(HttpListenerRequest request)
{
_dnsWebService.DnsServer.CacheZoneManager.Flush();
_dnsWebService.Log.Write(DnsWebService.GetRequestRemoteEndPoint(request), "[" + _dnsWebService.GetSession(request).Username + "] Cache was flushed.");
}
public void ListCachedZones(HttpListenerRequest request, JsonTextWriter jsonWriter)
{
string domain = request.QueryString["domain"];
if (domain == null)
domain = "";
string direction = request.QueryString["direction"];
List subZones = new List();
List records = new List();
while (true)
{
subZones.Clear();
records.Clear();
_dnsWebService.DnsServer.CacheZoneManager.ListSubDomains(domain, subZones);
_dnsWebService.DnsServer.CacheZoneManager.ListAllRecords(domain, records);
if (records.Count > 0)
break;
if (subZones.Count != 1)
break;
if (direction == "up")
{
if (domain.Length == 0)
break;
int i = domain.IndexOf('.');
if (i < 0)
domain = "";
else
domain = domain.Substring(i + 1);
}
else if (domain.Length == 0)
{
domain = subZones[0];
}
else
{
domain = subZones[0] + "." + domain;
}
}
subZones.Sort();
jsonWriter.WritePropertyName("domain");
jsonWriter.WriteValue(domain);
jsonWriter.WritePropertyName("zones");
jsonWriter.WriteStartArray();
if (domain.Length != 0)
domain = "." + domain;
foreach (string subZone in subZones)
jsonWriter.WriteValue(subZone + domain);
jsonWriter.WriteEndArray();
WebServiceZonesApi.WriteRecordsAsJson(records, jsonWriter, false);
}
public void DeleteCachedZone(HttpListenerRequest request)
{
string domain = request.QueryString["domain"];
if (string.IsNullOrEmpty(domain))
throw new DnsWebServiceException("Parameter 'domain' missing.");
if (_dnsWebService.DnsServer.CacheZoneManager.DeleteZone(domain))
_dnsWebService.Log.Write(DnsWebService.GetRequestRemoteEndPoint(request), "[" + _dnsWebService.GetSession(request).Username + "] Cached zone was deleted: " + domain);
}
#endregion
#region allowed zones api
public void ListAllowedZones(HttpListenerRequest request, JsonTextWriter jsonWriter)
{
string domain = request.QueryString["domain"];
if (domain == null)
domain = "";
string direction = request.QueryString["direction"];
List subZones = new List();
List records = new List();
while (true)
{
subZones.Clear();
records.Clear();
_dnsWebService.DnsServer.AllowedZoneManager.ListSubDomains(domain, subZones);
_dnsWebService.DnsServer.AllowedZoneManager.ListAllRecords(domain, records);
if (records.Count > 0)
break;
if (subZones.Count != 1)
break;
if (direction == "up")
{
if (domain.Length == 0)
break;
int i = domain.IndexOf('.');
if (i < 0)
domain = "";
else
domain = domain.Substring(i + 1);
}
else if (domain.Length == 0)
{
domain = subZones[0];
}
else
{
domain = subZones[0] + "." + domain;
}
}
subZones.Sort();
jsonWriter.WritePropertyName("domain");
jsonWriter.WriteValue(domain);
jsonWriter.WritePropertyName("zones");
jsonWriter.WriteStartArray();
if (domain.Length != 0)
domain = "." + domain;
foreach (string subZone in subZones)
jsonWriter.WriteValue(subZone + domain);
jsonWriter.WriteEndArray();
WebServiceZonesApi.WriteRecordsAsJson(new List(records), jsonWriter, false);
}
public void ImportAllowedZones(HttpListenerRequest request)
{
if (!request.ContentType.StartsWith("application/x-www-form-urlencoded"))
throw new DnsWebServiceException("Invalid content type. Expected application/x-www-form-urlencoded.");
string formRequest;
using (StreamReader sR = new StreamReader(request.InputStream, request.ContentEncoding))
{
formRequest = sR.ReadToEnd();
}
string[] formParts = formRequest.Split('&');
foreach (string formPart in formParts)
{
if (formPart.StartsWith("allowedZones="))
{
string[] allowedZones = formPart.Substring(13).Split(',');
bool added = false;
foreach (string allowedZone in allowedZones)
{
if (_dnsWebService.DnsServer.AllowedZoneManager.AllowZone(allowedZone))
added = true;
}
if (added)
{
_dnsWebService.Log.Write(DnsWebService.GetRequestRemoteEndPoint(request), "[" + _dnsWebService.GetSession(request).Username + "] Total " + allowedZones.Length + " zones were imported into allowed zone successfully.");
_dnsWebService.DnsServer.AllowedZoneManager.SaveZoneFile();
}
return;
}
}
throw new DnsWebServiceException("Parameter 'allowedZones' missing.");
}
public void ExportAllowedZones(HttpListenerResponse response)
{
IReadOnlyList zoneInfoList = _dnsWebService.DnsServer.AllowedZoneManager.ListZones();
response.ContentType = "text/plain";
response.AddHeader("Content-Disposition", "attachment;filename=AllowedZones.txt");
using (StreamWriter sW = new StreamWriter(new BufferedStream(response.OutputStream)))
{
foreach (AuthZoneInfo zoneInfo in zoneInfoList)
sW.WriteLine(zoneInfo.Name);
}
}
public void DeleteAllowedZone(HttpListenerRequest request)
{
string domain = request.QueryString["domain"];
if (string.IsNullOrEmpty(domain))
throw new DnsWebServiceException("Parameter 'domain' missing.");
if (_dnsWebService.DnsServer.AllowedZoneManager.DeleteZone(domain))
{
_dnsWebService.Log.Write(DnsWebService.GetRequestRemoteEndPoint(request), "[" + _dnsWebService.GetSession(request).Username + "] Allowed zone was deleted: " + domain);
_dnsWebService.DnsServer.AllowedZoneManager.SaveZoneFile();
}
}
public void FlushAllowedZone(HttpListenerRequest request)
{
_dnsWebService.DnsServer.AllowedZoneManager.Flush();
_dnsWebService.Log.Write(DnsWebService.GetRequestRemoteEndPoint(request), "[" + _dnsWebService.GetSession(request).Username + "] Allowed zone was flushed successfully.");
_dnsWebService.DnsServer.AllowedZoneManager.SaveZoneFile();
}
public void AllowZone(HttpListenerRequest request)
{
string domain = request.QueryString["domain"];
if (string.IsNullOrEmpty(domain))
throw new DnsWebServiceException("Parameter 'domain' missing.");
if (IPAddress.TryParse(domain, out IPAddress ipAddress))
domain = (new DnsQuestionRecord(ipAddress, DnsClass.IN)).Name;
if (_dnsWebService.DnsServer.AllowedZoneManager.AllowZone(domain))
{
_dnsWebService.Log.Write(DnsWebService.GetRequestRemoteEndPoint(request), "[" + _dnsWebService.GetSession(request).Username + "] Zone was allowed: " + domain);
_dnsWebService.DnsServer.AllowedZoneManager.SaveZoneFile();
}
}
#endregion
#region blocked zones api
public void ListBlockedZones(HttpListenerRequest request, JsonTextWriter jsonWriter)
{
string domain = request.QueryString["domain"];
if (domain == null)
domain = "";
string direction = request.QueryString["direction"];
List subZones = new List();
List records = new List();
while (true)
{
subZones.Clear();
records.Clear();
_dnsWebService.DnsServer.BlockedZoneManager.ListSubDomains(domain, subZones);
_dnsWebService.DnsServer.BlockedZoneManager.ListAllRecords(domain, records);
if (records.Count > 0)
break;
if (subZones.Count != 1)
break;
if (direction == "up")
{
if (domain.Length == 0)
break;
int i = domain.IndexOf('.');
if (i < 0)
domain = "";
else
domain = domain.Substring(i + 1);
}
else if (domain.Length == 0)
{
domain = subZones[0];
}
else
{
domain = subZones[0] + "." + domain;
}
}
subZones.Sort();
jsonWriter.WritePropertyName("domain");
jsonWriter.WriteValue(domain);
jsonWriter.WritePropertyName("zones");
jsonWriter.WriteStartArray();
if (domain.Length != 0)
domain = "." + domain;
foreach (string subZone in subZones)
jsonWriter.WriteValue(subZone + domain);
jsonWriter.WriteEndArray();
WebServiceZonesApi.WriteRecordsAsJson(new List(records), jsonWriter, false);
}
public void ImportBlockedZones(HttpListenerRequest request)
{
if (!request.ContentType.StartsWith("application/x-www-form-urlencoded"))
throw new DnsWebServiceException("Invalid content type. Expected application/x-www-form-urlencoded.");
string formRequest;
using (StreamReader sR = new StreamReader(request.InputStream, request.ContentEncoding))
{
formRequest = sR.ReadToEnd();
}
string[] formParts = formRequest.Split('&');
foreach (string formPart in formParts)
{
if (formPart.StartsWith("blockedZones="))
{
string[] blockedZones = formPart.Substring(13).Split(',');
bool added = false;
foreach (string blockedZone in blockedZones)
{
if (_dnsWebService.DnsServer.BlockedZoneManager.BlockZone(blockedZone))
added = true;
}
if (added)
{
_dnsWebService.Log.Write(DnsWebService.GetRequestRemoteEndPoint(request), "[" + _dnsWebService.GetSession(request).Username + "] Total " + blockedZones.Length + " zones were imported into blocked zone successfully.");
_dnsWebService.DnsServer.BlockedZoneManager.SaveZoneFile();
}
return;
}
}
throw new DnsWebServiceException("Parameter 'blockedZones' missing.");
}
public void ExportBlockedZones(HttpListenerResponse response)
{
IReadOnlyList zoneInfoList = _dnsWebService.DnsServer.BlockedZoneManager.ListZones();
response.ContentType = "text/plain";
response.AddHeader("Content-Disposition", "attachment;filename=BlockedZones.txt");
using (StreamWriter sW = new StreamWriter(new BufferedStream(response.OutputStream)))
{
foreach (AuthZoneInfo zoneInfo in zoneInfoList)
sW.WriteLine(zoneInfo.Name);
}
}
public void DeleteBlockedZone(HttpListenerRequest request)
{
string domain = request.QueryString["domain"];
if (string.IsNullOrEmpty(domain))
throw new DnsWebServiceException("Parameter 'domain' missing.");
if (_dnsWebService.DnsServer.BlockedZoneManager.DeleteZone(domain))
{
_dnsWebService.Log.Write(DnsWebService.GetRequestRemoteEndPoint(request), "[" + _dnsWebService.GetSession(request).Username + "] Blocked zone was deleted: " + domain);
_dnsWebService.DnsServer.BlockedZoneManager.SaveZoneFile();
}
}
public void FlushBlockedZone(HttpListenerRequest request)
{
_dnsWebService.DnsServer.BlockedZoneManager.Flush();
_dnsWebService.Log.Write(DnsWebService.GetRequestRemoteEndPoint(request), "[" + _dnsWebService.GetSession(request).Username + "] Blocked zone was flushed successfully.");
_dnsWebService.DnsServer.BlockedZoneManager.SaveZoneFile();
}
public void BlockZone(HttpListenerRequest request)
{
string domain = request.QueryString["domain"];
if (string.IsNullOrEmpty(domain))
throw new DnsWebServiceException("Parameter 'domain' missing.");
if (IPAddress.TryParse(domain, out IPAddress ipAddress))
domain = (new DnsQuestionRecord(ipAddress, DnsClass.IN)).Name;
if (_dnsWebService.DnsServer.BlockedZoneManager.BlockZone(domain))
{
_dnsWebService.Log.Write(DnsWebService.GetRequestRemoteEndPoint(request), "[" + _dnsWebService.GetSession(request).Username + "] Domain was added to blocked zone: " + domain);
_dnsWebService.DnsServer.BlockedZoneManager.SaveZoneFile();
}
}
#endregion
#endregion
}
}