mirror of
https://github.com/fergalmoran/DnsServer.git
synced 2025-12-28 12:30:18 +00:00
457 lines
16 KiB
C#
457 lines
16 KiB
C#
/*
|
|
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 <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
using DnsServerCore.Dns.Zones;
|
|
using Newtonsoft.Json;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Threading.Tasks;
|
|
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<string> subZones = new List<string>();
|
|
List<DnsResourceRecord> records = new List<DnsResourceRecord>();
|
|
|
|
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<string> subZones = new List<string>();
|
|
List<DnsResourceRecord> records = new List<DnsResourceRecord>();
|
|
|
|
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<DnsResourceRecord>(records), jsonWriter, false);
|
|
}
|
|
|
|
public async Task ImportAllowedZonesAsync(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 = await sR.ReadToEndAsync();
|
|
}
|
|
|
|
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<AuthZoneInfo> 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<string> subZones = new List<string>();
|
|
List<DnsResourceRecord> records = new List<DnsResourceRecord>();
|
|
|
|
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<DnsResourceRecord>(records), jsonWriter, false);
|
|
}
|
|
|
|
public async Task ImportBlockedZonesAsync(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 = await sR.ReadToEndAsync();
|
|
}
|
|
|
|
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<AuthZoneInfo> 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
|
|
}
|
|
}
|