2019-06-15 13:30:03 +05:30
/ *
Technitium DNS Server
2025-01-11 17:44:18 +05:30
Copyright ( C ) 2025 Shreyas Zare ( shreyas @technitium . com )
2019-06-15 13:30:03 +05:30
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/>.
* /
2022-09-18 18:04:28 +05:30
using DnsServerCore.Auth ;
2019-06-15 13:30:03 +05:30
using DnsServerCore.Dhcp ;
using DnsServerCore.Dns ;
2021-08-07 17:28:33 +05:30
using DnsServerCore.Dns.ZoneManagers ;
2020-05-23 17:25:08 +05:30
using DnsServerCore.Dns.Zones ;
2023-01-01 18:48:08 +05:30
using Microsoft.AspNetCore.Builder ;
using Microsoft.AspNetCore.Connections ;
using Microsoft.AspNetCore.Diagnostics ;
using Microsoft.AspNetCore.Hosting ;
using Microsoft.AspNetCore.Http ;
2023-08-12 13:13:22 +05:30
using Microsoft.AspNetCore.Http.Features ;
2023-01-01 18:48:08 +05:30
using Microsoft.AspNetCore.Server.Kestrel.Core ;
using Microsoft.AspNetCore.StaticFiles ;
2023-08-12 13:13:22 +05:30
using Microsoft.Extensions.DependencyInjection ;
2023-01-01 18:48:08 +05:30
using Microsoft.Extensions.FileProviders ;
using Microsoft.Extensions.Logging ;
2019-06-15 13:30:03 +05:30
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Net ;
2024-05-19 16:08:35 +05:30
using System.Net.Mail ;
2023-01-14 14:59:50 +05:30
using System.Net.Quic ;
2023-07-29 13:37:36 +05:30
using System.Net.Security ;
2020-12-25 19:27:36 +05:30
using System.Net.Sockets ;
2019-06-15 13:30:03 +05:30
using System.Reflection ;
using System.Security.Cryptography ;
using System.Security.Cryptography.X509Certificates ;
using System.Text ;
2022-12-24 12:57:53 +05:30
using System.Text.Json ;
2019-06-15 13:30:03 +05:30
using System.Threading ;
2020-08-29 14:40:51 +05:30
using System.Threading.Tasks ;
2022-01-23 18:07:18 +05:30
using TechnitiumLibrary ;
2019-06-15 13:30:03 +05:30
using TechnitiumLibrary.IO ;
using TechnitiumLibrary.Net ;
using TechnitiumLibrary.Net.Dns ;
2023-12-02 16:44:19 +05:30
using TechnitiumLibrary.Net.Dns.ClientConnection ;
2019-06-15 13:30:03 +05:30
using TechnitiumLibrary.Net.Dns.ResourceRecords ;
using TechnitiumLibrary.Net.Proxy ;
namespace DnsServerCore
{
2025-02-15 12:45:41 +05:30
public sealed partial class DnsWebService : IAsyncDisposable , IDisposable
2019-06-15 13:30:03 +05:30
{
#region variables
2024-02-04 18:01:49 +05:30
readonly static char [ ] commaSeparator = new char [ ] { ',' } ;
2025-02-15 12:45:41 +05:30
readonly Version _currentVersion ;
readonly DateTime _uptimestamp = DateTime . UtcNow ;
2019-06-15 13:30:03 +05:30
readonly string _appFolder ;
2025-02-15 12:45:41 +05:30
readonly string _configFolder ;
2019-06-15 13:30:03 +05:30
2025-02-15 12:45:41 +05:30
readonly LogManager _log ;
readonly AuthManager _authManager ;
2022-12-24 17:14:51 +05:30
2023-01-14 14:59:50 +05:30
readonly WebServiceApi _api ;
readonly WebServiceDashboardApi _dashboardApi ;
2025-02-15 12:45:41 +05:30
readonly WebServiceZonesApi _zonesApi ;
2023-01-14 14:59:50 +05:30
readonly WebServiceOtherZonesApi _otherZonesApi ;
2025-02-15 12:45:41 +05:30
readonly WebServiceAppsApi _appsApi ;
2023-01-14 14:59:50 +05:30
readonly WebServiceSettingsApi _settingsApi ;
readonly WebServiceDhcpApi _dhcpApi ;
readonly WebServiceAuthApi _authApi ;
readonly WebServiceLogsApi _logsApi ;
2022-12-24 17:14:51 +05:30
2023-01-14 14:59:50 +05:30
WebApplication _webService ;
2023-07-29 13:37:36 +05:30
X509Certificate2Collection _webServiceCertificateCollection ;
2024-12-21 15:49:16 +05:30
SslServerAuthenticationOptions _webServiceSslServerAuthenticationOptions ;
2023-01-14 14:59:50 +05:30
DnsServer _dnsServer ;
DhcpServer _dhcpServer ;
2022-12-24 17:14:51 +05:30
2023-01-14 14:59:50 +05:30
//web service
2025-02-15 12:45:41 +05:30
IReadOnlyList < IPAddress > _webServiceLocalAddresses = new IPAddress [ ] { IPAddress . Any , IPAddress . IPv6Any } ;
int _webServiceHttpPort = 5380 ;
int _webServiceTlsPort = 53443 ;
bool _webServiceEnableTls ;
bool _webServiceEnableHttp3 ;
bool _webServiceHttpToTlsRedirect ;
bool _webServiceUseSelfSignedTlsCertificate ;
string _webServiceTlsCertificatePath ;
string _webServiceTlsCertificatePassword ;
2023-01-14 14:59:50 +05:30
DateTime _webServiceTlsCertificateLastModifiedOn ;
2025-02-15 12:45:41 +05:30
string _webServiceRealIpHeader = "X-Real-IP" ;
2019-06-15 13:30:03 +05:30
2023-01-14 14:59:50 +05:30
//optional protocols
2025-02-15 12:45:41 +05:30
string _dnsTlsCertificatePath ;
string _dnsTlsCertificatePassword ;
2020-12-25 19:27:36 +05:30
DateTime _dnsTlsCertificateLastModifiedOn ;
2023-01-14 14:59:50 +05:30
//cache
2025-02-15 12:45:41 +05:30
bool _saveCache = true ;
2023-01-14 14:59:50 +05:30
2019-06-15 13:30:03 +05:30
Timer _tlsCertificateUpdateTimer ;
const int TLS_CERTIFICATE_UPDATE_TIMER_INITIAL_INTERVAL = 60000 ;
const int TLS_CERTIFICATE_UPDATE_TIMER_INTERVAL = 60000 ;
List < string > _configDisabledZones ;
2024-05-19 16:08:35 +05:30
readonly object _saveLock = new object ( ) ;
bool _pendingSave ;
readonly Timer _saveTimer ;
const int SAVE_TIMER_INITIAL_INTERVAL = 10000 ;
2019-06-15 13:30:03 +05:30
#endregion
#region constructor
2021-04-10 14:14:28 +05:30
public DnsWebService ( string configFolder = null , Uri updateCheckUri = null , Uri appStoreUri = null )
2019-06-15 13:30:03 +05:30
{
2020-08-29 14:40:51 +05:30
Assembly assembly = Assembly . GetExecutingAssembly ( ) ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
_currentVersion = assembly . GetName ( ) . Version ;
2019-06-15 13:30:03 +05:30
_appFolder = Path . GetDirectoryName ( assembly . Location ) ;
2022-09-18 18:04:28 +05:30
if ( configFolder is null )
2019-06-15 13:30:03 +05:30
_configFolder = Path . Combine ( _appFolder , "config" ) ;
else
_configFolder = configFolder ;
2022-12-24 17:14:51 +05:30
Directory . CreateDirectory ( _configFolder ) ;
Directory . CreateDirectory ( Path . Combine ( _configFolder , "blocklists" ) ) ;
2024-09-14 19:19:59 +05:30
Directory . CreateDirectory ( Path . Combine ( _configFolder , "zones" ) ) ;
2022-12-24 17:14:51 +05:30
2020-12-19 13:32:02 +05:30
_log = new LogManager ( _configFolder ) ;
2022-09-18 18:04:28 +05:30
_authManager = new AuthManager ( _configFolder , _log ) ;
2023-01-14 14:59:50 +05:30
_api = new WebServiceApi ( this , updateCheckUri ) ;
2022-09-18 18:04:28 +05:30
_dashboardApi = new WebServiceDashboardApi ( this ) ;
_zonesApi = new WebServiceZonesApi ( this ) ;
_otherZonesApi = new WebServiceOtherZonesApi ( this ) ;
_appsApi = new WebServiceAppsApi ( this , appStoreUri ) ;
2023-01-14 14:59:50 +05:30
_settingsApi = new WebServiceSettingsApi ( this ) ;
2022-09-18 18:04:28 +05:30
_dhcpApi = new WebServiceDhcpApi ( this ) ;
2023-01-14 14:59:50 +05:30
_authApi = new WebServiceAuthApi ( this ) ;
2022-09-18 18:04:28 +05:30
_logsApi = new WebServiceLogsApi ( this ) ;
2024-05-19 16:08:35 +05:30
_saveTimer = new Timer ( delegate ( object state )
{
lock ( _saveLock )
{
2024-06-01 19:02:42 +05:30
if ( _pendingSave )
2024-05-19 16:08:35 +05:30
{
2024-06-01 19:02:42 +05:30
try
{
SaveConfigFileInternal ( ) ;
_pendingSave = false ;
}
catch ( Exception ex )
{
_log . Write ( ex ) ;
//set timer to retry again
_saveTimer . Change ( SAVE_TIMER_INITIAL_INTERVAL , Timeout . Infinite ) ;
}
2024-05-19 16:08:35 +05:30
}
}
} ) ;
2019-06-15 13:30:03 +05:30
}
#endregion
#region IDisposable
2021-09-18 19:02:40 +05:30
bool _disposed ;
2019-06-15 13:30:03 +05:30
2023-01-01 18:48:08 +05:30
public async ValueTask DisposeAsync ( )
2019-06-15 13:30:03 +05:30
{
if ( _disposed )
return ;
2024-05-19 16:08:35 +05:30
lock ( _saveLock )
{
2024-06-01 19:02:42 +05:30
_saveTimer ? . Dispose ( ) ;
2024-05-19 16:08:35 +05:30
if ( _pendingSave )
{
try
{
SaveConfigFileInternal ( ) ;
}
catch ( Exception ex )
{
_log . Write ( ex ) ;
}
finally
{
_pendingSave = false ;
}
}
}
2023-01-01 18:48:08 +05:30
await StopAsync ( ) ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
if ( _appsApi is not null )
_appsApi . Dispose ( ) ;
2023-01-14 14:59:50 +05:30
if ( _settingsApi is not null )
_settingsApi . Dispose ( ) ;
2019-06-16 21:47:47 +05:30
2022-09-18 18:04:28 +05:30
if ( _authManager is not null )
_authManager . Dispose ( ) ;
if ( _log is not null )
2021-09-18 19:02:40 +05:30
_log . Dispose ( ) ;
2019-06-15 13:30:03 +05:30
_disposed = true ;
}
2023-01-01 18:48:08 +05:30
public void Dispose ( )
{
DisposeAsync ( ) . Sync ( ) ;
}
2019-06-15 13:30:03 +05:30
#endregion
2023-08-12 13:13:22 +05:30
#region internal
2025-02-15 12:45:41 +05:30
private string ConvertToRelativePath ( string path )
2023-08-12 13:13:22 +05:30
{
if ( path . StartsWith ( _configFolder , Environment . OSVersion . Platform = = PlatformID . Win32NT ? StringComparison . OrdinalIgnoreCase : StringComparison . Ordinal ) )
path = path . Substring ( _configFolder . Length ) . TrimStart ( Path . DirectorySeparatorChar ) ;
return path ;
}
2025-02-15 12:45:41 +05:30
private string ConvertToAbsolutePath ( string path )
2023-08-12 13:13:22 +05:30
{
2024-05-19 16:08:35 +05:30
if ( path is null )
return null ;
2023-08-12 13:13:22 +05:30
if ( Path . IsPathRooted ( path ) )
return path ;
return Path . Combine ( _configFolder , path ) ;
}
#endregion
2023-01-14 14:59:50 +05:30
#region server version
2025-02-15 12:45:41 +05:30
private string GetServerVersion ( )
2023-01-14 14:59:50 +05:30
{
return GetCleanVersion ( _currentVersion ) ;
}
2025-02-15 12:45:41 +05:30
private static string GetCleanVersion ( Version version )
2023-01-14 14:59:50 +05:30
{
string strVersion = version . Major + "." + version . Minor ;
if ( version . Build > 0 )
strVersion + = "." + version . Build ;
if ( version . Revision > 0 )
strVersion + = "." + version . Revision ;
return strVersion ;
}
#endregion
2019-06-15 13:30:03 +05:30
2021-02-27 19:18:08 +05:30
#region web service
2025-02-15 12:45:41 +05:30
private async Task TryStartWebServiceAsync ( IReadOnlyList < IPAddress > oldWebServiceLocalAddresses , int oldWebServiceHttpPort , int oldWebServiceTlsPort )
2023-01-14 14:59:50 +05:30
{
try
{
2025-02-15 13:17:10 +05:30
_webServiceLocalAddresses = WebUtilities . GetValidKestrelLocalAddresses ( _webServiceLocalAddresses ) ;
2023-08-26 12:34:52 +05:30
await StartWebServiceAsync ( _webServiceLocalAddresses , _webServiceHttpPort , _webServiceTlsPort , false ) ;
return ;
2023-01-14 14:59:50 +05:30
}
catch ( Exception ex )
{
_log . Write ( "Web Service failed to start: " + ex . ToString ( ) ) ;
2023-08-26 12:34:52 +05:30
}
2023-09-23 18:19:36 +05:30
_log . Write ( "Attempting to revert Web Service end point changes ..." ) ;
2023-01-14 14:59:50 +05:30
2023-09-23 18:19:36 +05:30
try
{
2025-02-15 13:17:10 +05:30
_webServiceLocalAddresses = WebUtilities . GetValidKestrelLocalAddresses ( oldWebServiceLocalAddresses ) ;
2023-09-23 18:19:36 +05:30
_webServiceHttpPort = oldWebServiceHttpPort ;
_webServiceTlsPort = oldWebServiceTlsPort ;
2023-08-26 12:34:52 +05:30
2023-09-23 18:19:36 +05:30
await StartWebServiceAsync ( _webServiceLocalAddresses , _webServiceHttpPort , _webServiceTlsPort , false ) ;
2023-08-26 12:34:52 +05:30
2024-05-19 16:08:35 +05:30
SaveConfigFileInternal ( ) ; //save reverted changes
2023-09-23 18:19:36 +05:30
return ;
}
catch ( Exception ex2 )
{
_log . Write ( "Web Service failed to start: " + ex2 . ToString ( ) ) ;
2023-01-14 14:59:50 +05:30
}
2023-08-26 12:34:52 +05:30
_log . Write ( "Attempting to start Web Service on ANY (0.0.0.0) fallback address..." ) ;
try
{
_webServiceLocalAddresses = new IPAddress [ ] { IPAddress . Any } ;
2025-02-15 12:45:41 +05:30
await StartWebServiceAsync ( _webServiceLocalAddresses , _webServiceHttpPort , _webServiceTlsPort , true ) ;
2023-08-26 12:34:52 +05:30
return ;
}
catch ( Exception ex3 )
{
_log . Write ( "Web Service failed to start: " + ex3 . ToString ( ) ) ;
}
_log . Write ( "Attempting to start Web Service on loopback (127.0.0.1) fallback address..." ) ;
_webServiceLocalAddresses = new IPAddress [ ] { IPAddress . Loopback } ;
await StartWebServiceAsync ( _webServiceLocalAddresses , _webServiceHttpPort , _webServiceTlsPort , true ) ;
2023-01-14 14:59:50 +05:30
}
2025-02-15 12:45:41 +05:30
private async Task StartWebServiceAsync ( IReadOnlyList < IPAddress > webServiceLocalAddresses , int webServiceHttpPort , int webServiceTlsPort , bool httpOnlyMode )
2019-06-15 13:30:03 +05:30
{
2023-01-01 18:48:08 +05:30
WebApplicationBuilder builder = WebApplication . CreateBuilder ( ) ;
2020-12-25 19:27:36 +05:30
2023-01-01 18:48:08 +05:30
builder . Environment . ContentRootFileProvider = new PhysicalFileProvider ( _appFolder )
2020-12-25 19:27:36 +05:30
{
2023-01-01 18:48:08 +05:30
UseActivePolling = true ,
UsePollingFileWatcher = true
} ;
2020-12-25 19:27:36 +05:30
2023-01-01 18:48:08 +05:30
builder . Environment . WebRootFileProvider = new PhysicalFileProvider ( Path . Combine ( _appFolder , "www" ) )
2019-06-15 13:30:03 +05:30
{
2023-01-01 18:48:08 +05:30
UseActivePolling = true ,
UsePollingFileWatcher = true
} ;
2020-12-25 19:27:36 +05:30
2023-01-01 18:48:08 +05:30
builder . WebHost . ConfigureKestrel ( delegate ( WebHostBuilderContext context , KestrelServerOptions serverOptions )
2020-12-25 19:27:36 +05:30
{
2023-01-01 18:48:08 +05:30
//http
2023-08-26 12:34:52 +05:30
foreach ( IPAddress webServiceLocalAddress in webServiceLocalAddresses )
serverOptions . Listen ( webServiceLocalAddress , webServiceHttpPort ) ;
2023-01-01 18:48:08 +05:30
//https
2025-02-15 12:45:41 +05:30
if ( ! httpOnlyMode & & _webServiceEnableTls & & ( _webServiceCertificateCollection is not null ) )
2020-12-25 19:27:36 +05:30
{
2023-08-26 12:34:52 +05:30
foreach ( IPAddress webServiceLocalAddress in webServiceLocalAddresses )
2023-01-01 18:48:08 +05:30
{
2023-08-26 12:34:52 +05:30
serverOptions . Listen ( webServiceLocalAddress , webServiceTlsPort , delegate ( ListenOptions listenOptions )
2023-01-01 18:48:08 +05:30
{
2024-11-30 13:16:44 +05:30
if ( _webServiceEnableHttp3 )
listenOptions . Protocols = HttpProtocols . Http1AndHttp2AndHttp3 ;
2024-12-21 15:49:16 +05:30
else if ( IsHttp2Supported ( ) )
2024-11-30 13:16:44 +05:30
listenOptions . Protocols = HttpProtocols . Http1AndHttp2 ;
else
listenOptions . Protocols = HttpProtocols . Http1 ;
2023-07-29 13:37:36 +05:30
listenOptions . UseHttps ( delegate ( SslStream stream , SslClientHelloInfo clientHelloInfo , object state , CancellationToken cancellationToken )
{
2024-12-21 15:49:16 +05:30
return ValueTask . FromResult ( _webServiceSslServerAuthenticationOptions ) ;
2023-07-29 13:37:36 +05:30
} , null ) ;
2023-01-01 18:48:08 +05:30
} ) ;
}
2020-12-25 19:27:36 +05:30
}
2023-01-01 18:48:08 +05:30
serverOptions . AddServerHeader = false ;
2023-08-12 13:13:22 +05:30
serverOptions . Limits . MaxRequestBodySize = int . MaxValue ;
} ) ;
builder . Services . Configure ( delegate ( FormOptions options )
{
options . MultipartBodyLengthLimit = int . MaxValue ;
2023-01-01 18:48:08 +05:30
} ) ;
2020-12-25 19:27:36 +05:30
2023-01-01 18:48:08 +05:30
builder . Logging . ClearProviders ( ) ;
2020-12-25 19:27:36 +05:30
2023-01-01 18:48:08 +05:30
_webService = builder . Build ( ) ;
2020-12-25 19:27:36 +05:30
2025-02-15 12:45:41 +05:30
if ( _webServiceHttpToTlsRedirect & & ! httpOnlyMode & & _webServiceEnableTls & & ( _webServiceCertificateCollection is not null ) )
2024-05-19 16:08:35 +05:30
_webService . Use ( WebServiceHttpsRedirectionMiddleware ) ;
2021-03-27 19:12:48 +05:30
2023-01-01 18:48:08 +05:30
_webService . UseDefaultFiles ( ) ;
_webService . UseStaticFiles ( new StaticFileOptions ( )
{
OnPrepareResponse = delegate ( StaticFileResponseContext ctx )
2021-03-27 19:12:48 +05:30
{
2024-02-04 18:01:49 +05:30
ctx . Context . Response . Headers [ "X-Robots-Tag" ] = "noindex, nofollow" ;
2024-11-09 19:47:25 +05:30
ctx . Context . Response . Headers . CacheControl = "no-cache" ;
2023-04-23 16:28:27 +05:30
} ,
ServeUnknownFileTypes = true
2023-01-01 18:48:08 +05:30
} ) ;
2021-03-27 19:12:48 +05:30
2023-01-01 18:48:08 +05:30
ConfigureWebServiceRoutes ( ) ;
2021-03-27 19:12:48 +05:30
2023-01-14 14:59:50 +05:30
try
{
await _webService . StartAsync ( ) ;
2023-08-26 12:34:52 +05:30
foreach ( IPAddress webServiceLocalAddress in webServiceLocalAddresses )
2023-01-14 14:59:50 +05:30
{
2023-08-26 12:34:52 +05:30
_log ? . Write ( new IPEndPoint ( webServiceLocalAddress , webServiceHttpPort ) , "Http" , "Web Service was bound successfully." ) ;
2023-01-14 14:59:50 +05:30
2025-02-15 12:45:41 +05:30
if ( ! httpOnlyMode & & _webServiceEnableTls & & ( _webServiceCertificateCollection is not null ) )
2023-08-26 12:34:52 +05:30
_log ? . Write ( new IPEndPoint ( webServiceLocalAddress , webServiceTlsPort ) , "Https" , "Web Service was bound successfully." ) ;
2023-01-14 14:59:50 +05:30
}
}
catch
{
await StopWebServiceAsync ( ) ;
2021-03-27 19:12:48 +05:30
2023-08-26 12:34:52 +05:30
foreach ( IPAddress webServiceLocalAddress in webServiceLocalAddresses )
2023-01-14 14:59:50 +05:30
{
2023-08-26 12:34:52 +05:30
_log ? . Write ( new IPEndPoint ( webServiceLocalAddress , webServiceHttpPort ) , "Http" , "Web Service failed to bind." ) ;
2023-01-14 14:59:50 +05:30
2025-02-15 12:45:41 +05:30
if ( ! httpOnlyMode & & _webServiceEnableTls & & ( _webServiceCertificateCollection is not null ) )
2023-08-26 12:34:52 +05:30
_log ? . Write ( new IPEndPoint ( webServiceLocalAddress , webServiceTlsPort ) , "Https" , "Web Service failed to bind." ) ;
2023-01-14 14:59:50 +05:30
}
throw ;
}
2023-01-01 18:48:08 +05:30
}
2021-03-27 19:12:48 +05:30
2025-02-15 12:45:41 +05:30
private async Task StopWebServiceAsync ( )
2023-01-01 18:48:08 +05:30
{
2023-01-14 14:59:50 +05:30
if ( _webService is not null )
{
await _webService . DisposeAsync ( ) ;
_webService = null ;
}
2023-01-01 18:48:08 +05:30
}
2020-12-25 19:27:36 +05:30
2024-12-21 15:49:16 +05:30
private bool IsHttp2Supported ( )
{
if ( _webServiceEnableHttp3 )
return true ;
switch ( Environment . OSVersion . Platform )
{
case PlatformID . Win32NT :
return Environment . OSVersion . Version . Major > = 10 ; //http/2 supported on Windows Server 2016/Windows 10 or later
case PlatformID . Unix :
return true ; //http/2 supported on Linux with OpenSSL 1.0.2 or later (for example, Ubuntu 16.04 or later)
default :
return false ;
}
}
2023-01-01 18:48:08 +05:30
private void ConfigureWebServiceRoutes ( )
{
_webService . UseExceptionHandler ( WebServiceExceptionHandler ) ;
_webService . Use ( WebServiceApiMiddleware ) ;
_webService . UseRouting ( ) ;
//user auth
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/user/login" , delegate ( HttpContext context ) { return _authApi . LoginAsync ( context , UserSessionType . Standard ) ; } ) ;
_webService . MapGetAndPost ( "/api/user/createToken" , delegate ( HttpContext context ) { return _authApi . LoginAsync ( context , UserSessionType . ApiToken ) ; } ) ;
_webService . MapGetAndPost ( "/api/user/logout" , _authApi . Logout ) ;
2023-01-01 18:48:08 +05:30
//user
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/user/session/get" , _authApi . GetCurrentSessionDetails ) ;
_webService . MapGetAndPost ( "/api/user/session/delete" , delegate ( HttpContext context ) { _authApi . DeleteSession ( context , false ) ; } ) ;
_webService . MapGetAndPost ( "/api/user/changePassword" , _authApi . ChangePassword ) ;
_webService . MapGetAndPost ( "/api/user/profile/get" , _authApi . GetProfile ) ;
_webService . MapGetAndPost ( "/api/user/profile/set" , _authApi . SetProfile ) ;
_webService . MapGetAndPost ( "/api/user/checkForUpdate" , _api . CheckForUpdateAsync ) ;
2023-01-01 18:48:08 +05:30
//dashboard
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/dashboard/stats/get" , _dashboardApi . GetStats ) ;
_webService . MapGetAndPost ( "/api/dashboard/stats/getTop" , _dashboardApi . GetTopStats ) ;
_webService . MapGetAndPost ( "/api/dashboard/stats/deleteAll" , _logsApi . DeleteAllStats ) ;
2023-01-01 18:48:08 +05:30
//zones
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/zones/list" , _zonesApi . ListZones ) ;
2024-09-14 19:19:59 +05:30
_webService . MapGetAndPost ( "/api/zones/catalogs/list" , _zonesApi . ListCatalogZones ) ;
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/zones/create" , _zonesApi . CreateZoneAsync ) ;
2023-10-29 19:16:36 +05:30
_webService . MapGetAndPost ( "/api/zones/import" , _zonesApi . ImportZoneAsync ) ;
_webService . MapGetAndPost ( "/api/zones/export" , _zonesApi . ExportZoneAsync ) ;
2023-09-24 16:37:12 +05:30
_webService . MapGetAndPost ( "/api/zones/clone" , _zonesApi . CloneZone ) ;
2023-06-25 19:14:41 +05:30
_webService . MapGetAndPost ( "/api/zones/convert" , _zonesApi . ConvertZone ) ;
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/zones/enable" , _zonesApi . EnableZone ) ;
_webService . MapGetAndPost ( "/api/zones/disable" , _zonesApi . DisableZone ) ;
_webService . MapGetAndPost ( "/api/zones/delete" , _zonesApi . DeleteZone ) ;
_webService . MapGetAndPost ( "/api/zones/resync" , _zonesApi . ResyncZone ) ;
_webService . MapGetAndPost ( "/api/zones/options/get" , _zonesApi . GetZoneOptions ) ;
_webService . MapGetAndPost ( "/api/zones/options/set" , _zonesApi . SetZoneOptions ) ;
_webService . MapGetAndPost ( "/api/zones/permissions/get" , delegate ( HttpContext context ) { _authApi . GetPermissionDetails ( context , PermissionSection . Zones ) ; } ) ;
_webService . MapGetAndPost ( "/api/zones/permissions/set" , delegate ( HttpContext context ) { _authApi . SetPermissionsDetails ( context , PermissionSection . Zones ) ; } ) ;
_webService . MapGetAndPost ( "/api/zones/dnssec/sign" , _zonesApi . SignPrimaryZone ) ;
_webService . MapGetAndPost ( "/api/zones/dnssec/unsign" , _zonesApi . UnsignPrimaryZone ) ;
2023-10-29 20:19:28 +05:30
_webService . MapGetAndPost ( "/api/zones/dnssec/viewDS" , _zonesApi . GetPrimaryZoneDsInfo ) ;
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/zones/dnssec/properties/get" , _zonesApi . GetPrimaryZoneDnssecProperties ) ;
_webService . MapGetAndPost ( "/api/zones/dnssec/properties/convertToNSEC" , _zonesApi . ConvertPrimaryZoneToNSEC ) ;
_webService . MapGetAndPost ( "/api/zones/dnssec/properties/convertToNSEC3" , _zonesApi . ConvertPrimaryZoneToNSEC3 ) ;
_webService . MapGetAndPost ( "/api/zones/dnssec/properties/updateNSEC3Params" , _zonesApi . UpdatePrimaryZoneNSEC3Parameters ) ;
_webService . MapGetAndPost ( "/api/zones/dnssec/properties/updateDnsKeyTtl" , _zonesApi . UpdatePrimaryZoneDnssecDnsKeyTtl ) ;
2025-03-29 19:12:54 +05:30
_webService . MapGetAndPost ( "/api/zones/dnssec/properties/generatePrivateKey" , _zonesApi . AddPrimaryZoneDnssecPrivateKey ) ;
_webService . MapGetAndPost ( "/api/zones/dnssec/properties/addPrivateKey" , _zonesApi . AddPrimaryZoneDnssecPrivateKey ) ;
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/zones/dnssec/properties/updatePrivateKey" , _zonesApi . UpdatePrimaryZoneDnssecPrivateKey ) ;
_webService . MapGetAndPost ( "/api/zones/dnssec/properties/deletePrivateKey" , _zonesApi . DeletePrimaryZoneDnssecPrivateKey ) ;
_webService . MapGetAndPost ( "/api/zones/dnssec/properties/publishAllPrivateKeys" , _zonesApi . PublishAllGeneratedPrimaryZoneDnssecPrivateKeys ) ;
_webService . MapGetAndPost ( "/api/zones/dnssec/properties/rolloverDnsKey" , _zonesApi . RolloverPrimaryZoneDnsKey ) ;
2025-03-29 19:12:54 +05:30
_webService . MapGetAndPost ( "/api/zones/dnssec/properties/retireDnsKey" , _zonesApi . RetirePrimaryZoneDnsKeyAsync ) ;
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/zones/records/add" , _zonesApi . AddRecord ) ;
_webService . MapGetAndPost ( "/api/zones/records/get" , _zonesApi . GetRecords ) ;
_webService . MapGetAndPost ( "/api/zones/records/update" , _zonesApi . UpdateRecord ) ;
_webService . MapGetAndPost ( "/api/zones/records/delete" , _zonesApi . DeleteRecord ) ;
2023-01-01 18:48:08 +05:30
//cache
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/cache/list" , _otherZonesApi . ListCachedZones ) ;
_webService . MapGetAndPost ( "/api/cache/delete" , _otherZonesApi . DeleteCachedZone ) ;
_webService . MapGetAndPost ( "/api/cache/flush" , _otherZonesApi . FlushCache ) ;
2023-01-01 18:48:08 +05:30
//allowed
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/allowed/list" , _otherZonesApi . ListAllowedZones ) ;
_webService . MapGetAndPost ( "/api/allowed/add" , _otherZonesApi . AllowZone ) ;
_webService . MapGetAndPost ( "/api/allowed/delete" , _otherZonesApi . DeleteAllowedZone ) ;
_webService . MapGetAndPost ( "/api/allowed/flush" , _otherZonesApi . FlushAllowedZone ) ;
_webService . MapGetAndPost ( "/api/allowed/import" , _otherZonesApi . ImportAllowedZones ) ;
_webService . MapGetAndPost ( "/api/allowed/export" , _otherZonesApi . ExportAllowedZonesAsync ) ;
2023-01-01 18:48:08 +05:30
//blocked
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/blocked/list" , _otherZonesApi . ListBlockedZones ) ;
_webService . MapGetAndPost ( "/api/blocked/add" , _otherZonesApi . BlockZone ) ;
_webService . MapGetAndPost ( "/api/blocked/delete" , _otherZonesApi . DeleteBlockedZone ) ;
_webService . MapGetAndPost ( "/api/blocked/flush" , _otherZonesApi . FlushBlockedZone ) ;
_webService . MapGetAndPost ( "/api/blocked/import" , _otherZonesApi . ImportBlockedZones ) ;
_webService . MapGetAndPost ( "/api/blocked/export" , _otherZonesApi . ExportBlockedZonesAsync ) ;
2023-01-01 18:48:08 +05:30
//apps
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/apps/list" , _appsApi . ListInstalledAppsAsync ) ;
_webService . MapGetAndPost ( "/api/apps/listStoreApps" , _appsApi . ListStoreApps ) ;
_webService . MapGetAndPost ( "/api/apps/downloadAndInstall" , _appsApi . DownloadAndInstallAppAsync ) ;
_webService . MapGetAndPost ( "/api/apps/downloadAndUpdate" , _appsApi . DownloadAndUpdateAppAsync ) ;
2023-01-01 18:48:08 +05:30
_webService . MapPost ( "/api/apps/install" , _appsApi . InstallAppAsync ) ;
_webService . MapPost ( "/api/apps/update" , _appsApi . UpdateAppAsync ) ;
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/apps/uninstall" , _appsApi . UninstallApp ) ;
_webService . MapGetAndPost ( "/api/apps/config/get" , _appsApi . GetAppConfigAsync ) ;
_webService . MapGetAndPost ( "/api/apps/config/set" , _appsApi . SetAppConfigAsync ) ;
2023-01-01 18:48:08 +05:30
//dns client
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/dnsClient/resolve" , _api . ResolveQueryAsync ) ;
2023-01-01 18:48:08 +05:30
//settings
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/settings/get" , _settingsApi . GetDnsSettings ) ;
2025-01-11 17:44:18 +05:30
_webService . MapGetAndPost ( "/api/settings/set" , _settingsApi . SetDnsSettingsAsync ) ;
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/settings/getTsigKeyNames" , _settingsApi . GetTsigKeyNames ) ;
_webService . MapGetAndPost ( "/api/settings/forceUpdateBlockLists" , _settingsApi . ForceUpdateBlockLists ) ;
_webService . MapGetAndPost ( "/api/settings/temporaryDisableBlocking" , _settingsApi . TemporaryDisableBlocking ) ;
_webService . MapGetAndPost ( "/api/settings/backup" , _settingsApi . BackupSettingsAsync ) ;
2023-01-01 18:48:08 +05:30
_webService . MapPost ( "/api/settings/restore" , _settingsApi . RestoreSettingsAsync ) ;
//dhcp
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/dhcp/leases/list" , _dhcpApi . ListDhcpLeases ) ;
_webService . MapGetAndPost ( "/api/dhcp/leases/remove" , _dhcpApi . RemoveDhcpLease ) ;
_webService . MapGetAndPost ( "/api/dhcp/leases/convertToReserved" , _dhcpApi . ConvertToReservedLease ) ;
_webService . MapGetAndPost ( "/api/dhcp/leases/convertToDynamic" , _dhcpApi . ConvertToDynamicLease ) ;
_webService . MapGetAndPost ( "/api/dhcp/scopes/list" , _dhcpApi . ListDhcpScopes ) ;
_webService . MapGetAndPost ( "/api/dhcp/scopes/get" , _dhcpApi . GetDhcpScope ) ;
_webService . MapGetAndPost ( "/api/dhcp/scopes/set" , _dhcpApi . SetDhcpScopeAsync ) ;
_webService . MapGetAndPost ( "/api/dhcp/scopes/addReservedLease" , _dhcpApi . AddReservedLease ) ;
_webService . MapGetAndPost ( "/api/dhcp/scopes/removeReservedLease" , _dhcpApi . RemoveReservedLease ) ;
_webService . MapGetAndPost ( "/api/dhcp/scopes/enable" , _dhcpApi . EnableDhcpScopeAsync ) ;
_webService . MapGetAndPost ( "/api/dhcp/scopes/disable" , _dhcpApi . DisableDhcpScope ) ;
_webService . MapGetAndPost ( "/api/dhcp/scopes/delete" , _dhcpApi . DeleteDhcpScope ) ;
2023-01-01 18:48:08 +05:30
//administration
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/admin/sessions/list" , _authApi . ListSessions ) ;
_webService . MapGetAndPost ( "/api/admin/sessions/createToken" , _authApi . CreateApiToken ) ;
_webService . MapGetAndPost ( "/api/admin/sessions/delete" , delegate ( HttpContext context ) { _authApi . DeleteSession ( context , true ) ; } ) ;
_webService . MapGetAndPost ( "/api/admin/users/list" , _authApi . ListUsers ) ;
_webService . MapGetAndPost ( "/api/admin/users/create" , _authApi . CreateUser ) ;
_webService . MapGetAndPost ( "/api/admin/users/get" , _authApi . GetUserDetails ) ;
_webService . MapGetAndPost ( "/api/admin/users/set" , _authApi . SetUserDetails ) ;
_webService . MapGetAndPost ( "/api/admin/users/delete" , _authApi . DeleteUser ) ;
_webService . MapGetAndPost ( "/api/admin/groups/list" , _authApi . ListGroups ) ;
_webService . MapGetAndPost ( "/api/admin/groups/create" , _authApi . CreateGroup ) ;
_webService . MapGetAndPost ( "/api/admin/groups/get" , _authApi . GetGroupDetails ) ;
_webService . MapGetAndPost ( "/api/admin/groups/set" , _authApi . SetGroupDetails ) ;
_webService . MapGetAndPost ( "/api/admin/groups/delete" , _authApi . DeleteGroup ) ;
_webService . MapGetAndPost ( "/api/admin/permissions/list" , _authApi . ListPermissions ) ;
_webService . MapGetAndPost ( "/api/admin/permissions/get" , delegate ( HttpContext context ) { _authApi . GetPermissionDetails ( context , PermissionSection . Unknown ) ; } ) ;
_webService . MapGetAndPost ( "/api/admin/permissions/set" , delegate ( HttpContext context ) { _authApi . SetPermissionsDetails ( context , PermissionSection . Unknown ) ; } ) ;
2023-01-01 18:48:08 +05:30
//logs
2023-01-14 14:59:50 +05:30
_webService . MapGetAndPost ( "/api/logs/list" , _logsApi . ListLogs ) ;
_webService . MapGetAndPost ( "/api/logs/download" , _logsApi . DownloadLogAsync ) ;
_webService . MapGetAndPost ( "/api/logs/delete" , _logsApi . DeleteLog ) ;
_webService . MapGetAndPost ( "/api/logs/deleteAll" , _logsApi . DeleteAllLogs ) ;
_webService . MapGetAndPost ( "/api/logs/query" , _logsApi . QueryLogsAsync ) ;
2025-01-11 17:44:18 +05:30
_webService . MapGetAndPost ( "/api/logs/export" , _logsApi . ExportLogsAsync ) ;
2019-06-15 13:30:03 +05:30
}
2024-05-19 16:08:35 +05:30
private Task WebServiceHttpsRedirectionMiddleware ( HttpContext context , RequestDelegate next )
{
if ( context . Request . IsHttps )
return next ( context ) ;
context . Response . Redirect ( "https://" + ( context . Request . Host . HasValue ? context . Request . Host . Host : _dnsServer . ServerDomain ) + ( _webServiceTlsPort = = 443 ? "" : ":" + _webServiceTlsPort ) + context . Request . Path + ( context . Request . QueryString . HasValue ? context . Request . QueryString . Value : "" ) , false , true ) ;
return Task . CompletedTask ;
}
2023-01-01 18:48:08 +05:30
private async Task WebServiceApiMiddleware ( HttpContext context , RequestDelegate next )
2019-06-15 13:30:03 +05:30
{
2023-01-01 18:48:08 +05:30
bool needsJsonResponseObject ;
2019-06-15 13:30:03 +05:30
2023-01-01 18:48:08 +05:30
switch ( context . Request . Path )
2019-06-15 13:30:03 +05:30
{
2023-01-01 18:48:08 +05:30
case "/api/user/login" :
case "/api/user/createToken" :
case "/api/user/logout" :
needsJsonResponseObject = false ;
break ;
2019-06-15 13:30:03 +05:30
2023-01-01 18:48:08 +05:30
case "/api/user/session/get" :
2019-06-15 13:30:03 +05:30
{
2023-01-01 18:48:08 +05:30
if ( ! TryGetSession ( context , out UserSession session ) )
throw new InvalidTokenWebServiceException ( "Invalid token or session expired." ) ;
2019-06-15 13:30:03 +05:30
2023-01-01 18:48:08 +05:30
context . Items [ "session" ] = session ;
2022-09-18 18:04:28 +05:30
2023-01-01 18:48:08 +05:30
needsJsonResponseObject = false ;
}
break ;
2022-09-18 18:04:28 +05:30
2023-10-29 19:16:36 +05:30
case "/api/zones/export" :
2023-01-01 18:48:08 +05:30
case "/api/allowed/export" :
case "/api/blocked/export" :
case "/api/settings/backup" :
case "/api/logs/download" :
2025-01-11 17:44:18 +05:30
case "/api/logs/export" :
2023-01-01 18:48:08 +05:30
{
if ( ! TryGetSession ( context , out UserSession session ) )
throw new InvalidTokenWebServiceException ( "Invalid token or session expired." ) ;
2022-09-18 18:04:28 +05:30
2023-01-01 18:48:08 +05:30
context . Items [ "session" ] = session ;
2022-09-18 18:04:28 +05:30
2023-01-01 18:48:08 +05:30
await next ( context ) ;
}
return ;
2022-09-18 18:04:28 +05:30
2023-01-01 18:48:08 +05:30
default :
2025-04-19 15:51:47 +05:30
if ( context . Request . Path . Value . StartsWith ( "/api/" , StringComparison . OrdinalIgnoreCase ) )
2023-01-01 18:48:08 +05:30
{
if ( ! TryGetSession ( context , out UserSession session ) )
throw new InvalidTokenWebServiceException ( "Invalid token or session expired." ) ;
2022-09-18 18:04:28 +05:30
2023-01-01 18:48:08 +05:30
context . Items [ "session" ] = session ;
needsJsonResponseObject = true ;
}
2025-04-19 15:51:47 +05:30
else
{
context . Response . StatusCode = StatusCodes . Status404NotFound ;
context . Response . ContentLength = 0 ;
return ;
}
2023-01-01 18:48:08 +05:30
break ;
}
2022-09-18 18:04:28 +05:30
2024-02-04 18:01:49 +05:30
using ( MemoryStream mS = new MemoryStream ( 4096 ) )
2023-01-01 18:48:08 +05:30
{
Utf8JsonWriter jsonWriter = new Utf8JsonWriter ( mS ) ;
context . Items [ "jsonWriter" ] = jsonWriter ;
2022-09-18 18:04:28 +05:30
2023-01-01 18:48:08 +05:30
jsonWriter . WriteStartObject ( ) ;
2022-09-18 18:04:28 +05:30
2023-01-01 18:48:08 +05:30
if ( needsJsonResponseObject )
{
jsonWriter . WritePropertyName ( "response" ) ;
jsonWriter . WriteStartObject ( ) ;
2022-09-18 18:04:28 +05:30
2023-01-01 18:48:08 +05:30
await next ( context ) ;
2022-09-18 18:04:28 +05:30
2023-01-01 18:48:08 +05:30
jsonWriter . WriteEndObject ( ) ;
}
else
{
await next ( context ) ;
}
2022-09-18 18:04:28 +05:30
2023-01-01 18:48:08 +05:30
jsonWriter . WriteString ( "status" , "ok" ) ;
2022-09-18 18:04:28 +05:30
2023-01-01 18:48:08 +05:30
jsonWriter . WriteEndObject ( ) ;
jsonWriter . Flush ( ) ;
2022-09-18 18:04:28 +05:30
2023-01-01 18:48:08 +05:30
mS . Position = 0 ;
2022-09-18 18:04:28 +05:30
2023-01-01 18:48:08 +05:30
HttpResponse response = context . Response ;
2022-09-18 18:04:28 +05:30
2023-01-01 18:48:08 +05:30
response . StatusCode = StatusCodes . Status200OK ;
response . ContentType = "application/json; charset=utf-8" ;
response . ContentLength = mS . Length ;
2022-09-18 18:04:28 +05:30
2023-01-01 18:48:08 +05:30
await mS . CopyToAsync ( response . Body ) ;
}
}
2022-09-18 18:04:28 +05:30
2024-02-04 18:01:49 +05:30
private void WebServiceExceptionHandler ( IApplicationBuilder exceptionHandlerApp )
2023-01-01 18:48:08 +05:30
{
exceptionHandlerApp . Run ( async delegate ( HttpContext context )
{
IExceptionHandlerPathFeature exceptionHandlerPathFeature = context . Features . Get < IExceptionHandlerPathFeature > ( ) ;
if ( exceptionHandlerPathFeature . Path . StartsWith ( "/api/" ) )
{
Exception ex = exceptionHandlerPathFeature . Error ;
2021-02-06 18:19:28 +05:30
2023-01-01 18:48:08 +05:30
context . Response . StatusCode = StatusCodes . Status200OK ;
context . Response . ContentType = "application/json; charset=utf-8" ;
2019-06-15 13:30:03 +05:30
2023-01-01 18:48:08 +05:30
await using ( Utf8JsonWriter jsonWriter = new Utf8JsonWriter ( context . Response . Body ) )
{
jsonWriter . WriteStartObject ( ) ;
2019-06-15 13:30:03 +05:30
2023-01-01 18:48:08 +05:30
if ( ex is InvalidTokenWebServiceException )
2019-06-15 13:30:03 +05:30
{
2022-12-24 12:57:53 +05:30
jsonWriter . WriteString ( "status" , "invalid-token" ) ;
jsonWriter . WriteString ( "errorMessage" , ex . Message ) ;
2019-06-15 13:30:03 +05:30
}
2023-01-01 18:48:08 +05:30
else
2019-06-15 13:30:03 +05:30
{
2022-12-24 12:57:53 +05:30
jsonWriter . WriteString ( "status" , "error" ) ;
jsonWriter . WriteString ( "errorMessage" , ex . Message ) ;
jsonWriter . WriteString ( "stackTrace" , ex . StackTrace ) ;
2019-06-15 13:30:03 +05:30
2022-12-24 12:57:53 +05:30
if ( ex . InnerException is not null )
jsonWriter . WriteString ( "innerErrorMessage" , ex . InnerException . Message ) ;
2019-06-15 13:30:03 +05:30
}
2023-01-01 18:48:08 +05:30
jsonWriter . WriteEndObject ( ) ;
2019-06-15 13:30:03 +05:30
}
2024-02-04 18:01:49 +05:30
2024-10-19 17:01:05 +05:30
_log . Write ( context . GetRemoteEndPoint ( _webServiceRealIpHeader ) , ex ) ;
2019-06-15 13:30:03 +05:30
}
2023-01-01 18:48:08 +05:30
} ) ;
2019-06-15 13:30:03 +05:30
}
2023-01-01 18:48:08 +05:30
private bool TryGetSession ( HttpContext context , out UserSession session )
2019-06-15 13:30:03 +05:30
{
2023-01-14 14:59:50 +05:30
string token = context . Request . GetQueryOrForm ( "token" ) ;
2023-01-01 18:48:08 +05:30
session = _authManager . GetSession ( token ) ;
2022-12-24 17:14:51 +05:30
if ( ( session is null ) | | session . User . Disabled )
return false ;
2021-07-10 13:44:49 +05:30
2022-12-24 17:14:51 +05:30
if ( session . HasExpired ( ) )
{
_authManager . DeleteSession ( session . Token ) ;
_authManager . SaveConfigFile ( ) ;
return false ;
}
2021-03-06 17:48:21 +05:30
2024-10-19 17:01:05 +05:30
IPEndPoint remoteEP = context . GetRemoteEndPoint ( _webServiceRealIpHeader ) ;
2021-03-06 17:48:21 +05:30
2023-01-01 18:48:08 +05:30
session . UpdateLastSeen ( remoteEP . Address , context . Request . Headers . UserAgent ) ;
2022-12-24 17:14:51 +05:30
return true ;
}
2021-03-06 17:48:21 +05:30
2022-12-24 17:14:51 +05:30
#endregion
2021-03-06 17:48:21 +05:30
2021-02-27 19:18:08 +05:30
#region tls
2025-02-15 12:45:41 +05:30
private void StartTlsCertificateUpdateTimer ( )
2019-06-15 13:30:03 +05:30
{
2023-01-14 14:59:50 +05:30
if ( _tlsCertificateUpdateTimer is null )
2019-06-15 13:30:03 +05:30
{
_tlsCertificateUpdateTimer = new Timer ( delegate ( object state )
{
2020-12-25 19:27:36 +05:30
if ( ! string . IsNullOrEmpty ( _webServiceTlsCertificatePath ) )
2019-06-15 13:30:03 +05:30
{
2023-08-12 13:13:22 +05:30
string webServiceTlsCertificatePath = ConvertToAbsolutePath ( _webServiceTlsCertificatePath ) ;
2020-12-25 19:27:36 +05:30
try
{
2023-08-12 13:13:22 +05:30
FileInfo fileInfo = new FileInfo ( webServiceTlsCertificatePath ) ;
2019-06-15 13:30:03 +05:30
2020-12-25 19:27:36 +05:30
if ( fileInfo . Exists & & ( fileInfo . LastWriteTimeUtc ! = _webServiceTlsCertificateLastModifiedOn ) )
2023-08-12 13:13:22 +05:30
LoadWebServiceTlsCertificate ( webServiceTlsCertificatePath , _webServiceTlsCertificatePassword ) ;
2020-12-25 19:27:36 +05:30
}
catch ( Exception ex )
{
2023-08-12 13:13:22 +05:30
_log . Write ( "DNS Server encountered an error while updating Web Service TLS Certificate: " + webServiceTlsCertificatePath + "\r\n" + ex . ToString ( ) ) ;
2020-12-25 19:27:36 +05:30
}
2019-06-15 13:30:03 +05:30
}
2020-12-25 19:27:36 +05:30
if ( ! string . IsNullOrEmpty ( _dnsTlsCertificatePath ) )
2019-06-15 13:30:03 +05:30
{
2023-08-12 13:13:22 +05:30
string dnsTlsCertificatePath = ConvertToAbsolutePath ( _dnsTlsCertificatePath ) ;
2020-12-25 19:27:36 +05:30
try
{
2023-08-12 13:13:22 +05:30
FileInfo fileInfo = new FileInfo ( dnsTlsCertificatePath ) ;
2020-12-25 19:27:36 +05:30
if ( fileInfo . Exists & & ( fileInfo . LastWriteTimeUtc ! = _dnsTlsCertificateLastModifiedOn ) )
2023-08-12 13:13:22 +05:30
LoadDnsTlsCertificate ( dnsTlsCertificatePath , _dnsTlsCertificatePassword ) ;
2020-12-25 19:27:36 +05:30
}
catch ( Exception ex )
{
2023-08-12 13:13:22 +05:30
_log . Write ( "DNS Server encountered an error while updating DNS Server TLS Certificate: " + dnsTlsCertificatePath + "\r\n" + ex . ToString ( ) ) ;
2020-12-25 19:27:36 +05:30
}
2019-06-15 13:30:03 +05:30
}
} , null , TLS_CERTIFICATE_UPDATE_TIMER_INITIAL_INTERVAL , TLS_CERTIFICATE_UPDATE_TIMER_INTERVAL ) ;
}
}
2025-02-15 12:45:41 +05:30
private void StopTlsCertificateUpdateTimer ( )
2019-06-15 13:30:03 +05:30
{
2023-01-14 14:59:50 +05:30
if ( _tlsCertificateUpdateTimer is not null )
2019-06-15 13:30:03 +05:30
{
_tlsCertificateUpdateTimer . Dispose ( ) ;
_tlsCertificateUpdateTimer = null ;
}
}
2025-02-15 12:45:41 +05:30
private void LoadWebServiceTlsCertificate ( string tlsCertificatePath , string tlsCertificatePassword )
2019-06-15 13:30:03 +05:30
{
FileInfo fileInfo = new FileInfo ( tlsCertificatePath ) ;
if ( ! fileInfo . Exists )
2020-12-25 19:27:36 +05:30
throw new ArgumentException ( "Web Service TLS certificate file does not exists: " + tlsCertificatePath ) ;
2019-06-15 13:30:03 +05:30
2024-05-19 16:08:35 +05:30
switch ( Path . GetExtension ( tlsCertificatePath ) . ToLowerInvariant ( ) )
{
case ".pfx" :
case ".p12" :
break ;
default :
throw new ArgumentException ( "Web Service TLS certificate file must be PKCS #12 formatted with .pfx or .p12 extension: " + tlsCertificatePath ) ;
}
2019-06-15 13:30:03 +05:30
2023-07-29 13:37:36 +05:30
X509Certificate2Collection certificateCollection = new X509Certificate2Collection ( ) ;
certificateCollection . Import ( tlsCertificatePath , tlsCertificatePassword , X509KeyStorageFlags . PersistKeySet ) ;
X509Certificate2 serverCertificate = null ;
foreach ( X509Certificate2 certificate in certificateCollection )
{
if ( certificate . HasPrivateKey )
{
serverCertificate = certificate ;
break ;
}
}
if ( serverCertificate is null )
throw new ArgumentException ( "Web Service TLS certificate file must contain a certificate with private key." ) ;
_webServiceCertificateCollection = certificateCollection ;
2020-12-25 19:27:36 +05:30
_webServiceTlsCertificateLastModifiedOn = fileInfo . LastWriteTimeUtc ;
2024-12-21 15:49:16 +05:30
List < SslApplicationProtocol > applicationProtocols = new List < SslApplicationProtocol > ( ) ;
if ( _webServiceEnableHttp3 )
applicationProtocols . Add ( new SslApplicationProtocol ( "h3" ) ) ;
if ( IsHttp2Supported ( ) )
applicationProtocols . Add ( new SslApplicationProtocol ( "h2" ) ) ;
applicationProtocols . Add ( new SslApplicationProtocol ( "http/1.1" ) ) ;
_webServiceSslServerAuthenticationOptions = new SslServerAuthenticationOptions
{
ApplicationProtocols = applicationProtocols ,
ServerCertificateContext = SslStreamCertificateContext . Create ( serverCertificate , _webServiceCertificateCollection , false )
} ;
2020-12-25 19:27:36 +05:30
_log . Write ( "Web Service TLS certificate was loaded: " + tlsCertificatePath ) ;
}
2025-02-15 12:45:41 +05:30
private void LoadDnsTlsCertificate ( string tlsCertificatePath , string tlsCertificatePassword )
2020-12-25 19:27:36 +05:30
{
FileInfo fileInfo = new FileInfo ( tlsCertificatePath ) ;
if ( ! fileInfo . Exists )
throw new ArgumentException ( "DNS Server TLS certificate file does not exists: " + tlsCertificatePath ) ;
2024-05-19 16:08:35 +05:30
switch ( Path . GetExtension ( tlsCertificatePath ) . ToLowerInvariant ( ) )
{
case ".pfx" :
case ".p12" :
break ;
default :
throw new ArgumentException ( "DNS Server TLS certificate file must be PKCS #12 formatted with .pfx or .p12 extension: " + tlsCertificatePath ) ;
}
2020-12-25 19:27:36 +05:30
2023-07-29 13:37:36 +05:30
X509Certificate2Collection certificateCollection = new X509Certificate2Collection ( ) ;
certificateCollection . Import ( tlsCertificatePath , tlsCertificatePassword , X509KeyStorageFlags . PersistKeySet ) ;
_dnsServer . CertificateCollection = certificateCollection ;
2020-12-25 19:27:36 +05:30
_dnsTlsCertificateLastModifiedOn = fileInfo . LastWriteTimeUtc ;
2019-06-15 13:30:03 +05:30
_log . Write ( "DNS Server TLS certificate was loaded: " + tlsCertificatePath ) ;
}
2025-02-15 12:45:41 +05:30
private void SelfSignedCertCheck ( bool generateNew , bool throwException )
2022-12-24 17:14:51 +05:30
{
2024-05-19 16:08:35 +05:30
string selfSignedCertificateFilePath = Path . Combine ( _configFolder , "self-signed-cert.pfx" ) ;
2022-12-24 17:14:51 +05:30
if ( _webServiceUseSelfSignedTlsCertificate )
{
2024-05-19 16:08:35 +05:30
string oldSelfSignedCertificateFilePath = Path . Combine ( _configFolder , "cert.pfx" ) ;
if ( ! oldSelfSignedCertificateFilePath . Equals ( ConvertToAbsolutePath ( _webServiceTlsCertificatePath ) , Environment . OSVersion . Platform = = PlatformID . Win32NT ? StringComparison . OrdinalIgnoreCase : StringComparison . Ordinal ) & & File . Exists ( oldSelfSignedCertificateFilePath ) & & ! File . Exists ( selfSignedCertificateFilePath ) )
File . Move ( oldSelfSignedCertificateFilePath , selfSignedCertificateFilePath ) ;
2022-12-24 17:14:51 +05:30
if ( generateNew | | ! File . Exists ( selfSignedCertificateFilePath ) )
{
RSA rsa = RSA . Create ( 2048 ) ;
CertificateRequest req = new CertificateRequest ( "cn=" + _dnsServer . ServerDomain , rsa , HashAlgorithmName . SHA256 , RSASignaturePadding . Pkcs1 ) ;
2024-12-21 15:49:16 +05:30
SubjectAlternativeNameBuilder san = new SubjectAlternativeNameBuilder ( ) ;
bool sanAdded = false ;
foreach ( IPAddress localAddress in _webServiceLocalAddresses )
{
if ( localAddress . Equals ( IPAddress . IPv6Any ) | | localAddress . Equals ( IPAddress . Any ) )
continue ;
san . AddIpAddress ( localAddress ) ;
sanAdded = true ;
}
if ( sanAdded )
req . CertificateExtensions . Add ( san . Build ( ) ) ;
2022-12-24 17:14:51 +05:30
X509Certificate2 cert = req . CreateSelfSigned ( DateTimeOffset . UtcNow , DateTimeOffset . UtcNow . AddYears ( 5 ) ) ;
File . WriteAllBytes ( selfSignedCertificateFilePath , cert . Export ( X509ContentType . Pkcs12 , null as string ) ) ;
}
if ( _webServiceEnableTls & & string . IsNullOrEmpty ( _webServiceTlsCertificatePath ) )
{
try
{
LoadWebServiceTlsCertificate ( selfSignedCertificateFilePath , null ) ;
2025-01-11 17:44:18 +05:30
if ( ! generateNew )
{
if ( _webServiceSslServerAuthenticationOptions . ServerCertificateContext . TargetCertificate . NotAfter < DateTime . UtcNow . AddYears ( 1 ) )
{
_log . Write ( "Web Service TLS self signed certificate is nearing expiration and will be regenerated." ) ;
SelfSignedCertCheck ( true , throwException ) ; //force generate new cert
}
}
2022-12-24 17:14:51 +05:30
}
catch ( Exception ex )
{
_log . Write ( "DNS Server encountered an error while loading self signed Web Service TLS certificate: " + selfSignedCertificateFilePath + "\r\n" + ex . ToString ( ) ) ;
if ( throwException )
throw ;
}
}
}
else
{
File . Delete ( selfSignedCertificateFilePath ) ;
}
}
2021-02-27 19:18:08 +05:30
#endregion
2023-01-14 14:59:50 +05:30
#region quic
2025-02-15 12:45:41 +05:30
private static void ValidateQuicSupport ( string protocolName = "DNS-over-QUIC" )
2023-01-14 14:59:50 +05:30
{
#pragma warning disable CA2252 // This API requires opting into preview features
#pragma warning disable CA1416 // Validate platform compatibility
if ( ! QuicConnection . IsSupported )
2023-10-29 19:16:36 +05:30
throw new DnsWebServiceException ( protocolName + " is supported only on Windows 11, Windows Server 2022, and Linux. On Linux, you must install 'libmsquic' manually." ) ;
#pragma warning restore CA1416 // Validate platform compatibility
#pragma warning restore CA2252 // This API requires opting into preview features
}
2025-02-15 12:45:41 +05:30
private static bool IsQuicSupported ( )
2023-10-29 19:16:36 +05:30
{
#pragma warning disable CA2252 // This API requires opting into preview features
#pragma warning disable CA1416 // Validate platform compatibility
return QuicConnection . IsSupported ;
2023-01-14 14:59:50 +05:30
#pragma warning restore CA1416 // Validate platform compatibility
#pragma warning restore CA2252 // This API requires opting into preview features
}
#endregion
2021-02-27 19:18:08 +05:30
#region config
2025-02-15 12:45:41 +05:30
private void LoadConfigFile ( )
2019-06-15 13:30:03 +05:30
{
string configFile = Path . Combine ( _configFolder , "dns.config" ) ;
try
{
2022-09-24 16:06:19 +05:30
int version ;
2022-09-18 18:04:28 +05:30
using ( FileStream fS = new FileStream ( configFile , FileMode . Open , FileAccess . Read ) )
2019-06-15 13:30:03 +05:30
{
2022-09-24 16:06:19 +05:30
version = ReadConfigFrom ( new BinaryReader ( fS ) ) ;
2019-06-15 13:30:03 +05:30
}
2022-09-18 18:04:28 +05:30
_log . Write ( "DNS Server config file was loaded: " + configFile ) ;
2022-09-24 16:06:19 +05:30
if ( version < = 27 )
2024-05-19 16:08:35 +05:30
SaveConfigFileInternal ( ) ; //save as new config version to avoid loading old version next time
2022-09-18 18:04:28 +05:30
}
catch ( FileNotFoundException )
{
_log . Write ( "DNS Server config file was not found: " + configFile ) ;
_log . Write ( "DNS Server is restoring default config file." ) ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
//general
string serverDomain = Environment . GetEnvironmentVariable ( "DNS_SERVER_DOMAIN" ) ;
if ( ! string . IsNullOrEmpty ( serverDomain ) )
_dnsServer . ServerDomain = serverDomain ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
_appsApi . EnableAutomaticUpdate = true ;
2020-12-25 19:27:36 +05:30
2022-09-18 18:04:28 +05:30
string strPreferIPv6 = Environment . GetEnvironmentVariable ( "DNS_SERVER_PREFER_IPV6" ) ;
if ( ! string . IsNullOrEmpty ( strPreferIPv6 ) )
_dnsServer . PreferIPv6 = bool . Parse ( strPreferIPv6 ) ;
2020-12-25 19:27:36 +05:30
2022-09-18 18:04:28 +05:30
_dnsServer . DnssecValidation = true ;
CreateForwarderZoneToDisableDnssecForNTP ( ) ;
2020-12-25 19:27:36 +05:30
2023-04-23 16:28:27 +05:30
//web service
2024-03-16 14:00:11 +05:30
string strWebServiceLocalAddresses = Environment . GetEnvironmentVariable ( "DNS_SERVER_WEB_SERVICE_LOCAL_ADDRESSES" ) ;
if ( ! string . IsNullOrEmpty ( strWebServiceLocalAddresses ) )
_webServiceLocalAddresses = strWebServiceLocalAddresses . Split ( IPAddress . Parse , commaSeparator ) ;
2023-04-23 16:28:27 +05:30
string strWebServiceHttpPort = Environment . GetEnvironmentVariable ( "DNS_SERVER_WEB_SERVICE_HTTP_PORT" ) ;
if ( ! string . IsNullOrEmpty ( strWebServiceHttpPort ) )
_webServiceHttpPort = int . Parse ( strWebServiceHttpPort ) ;
string webServiceTlsPort = Environment . GetEnvironmentVariable ( "DNS_SERVER_WEB_SERVICE_HTTPS_PORT" ) ;
if ( ! string . IsNullOrEmpty ( webServiceTlsPort ) )
_webServiceTlsPort = int . Parse ( webServiceTlsPort ) ;
string webServiceEnableTls = Environment . GetEnvironmentVariable ( "DNS_SERVER_WEB_SERVICE_ENABLE_HTTPS" ) ;
if ( ! string . IsNullOrEmpty ( webServiceEnableTls ) )
_webServiceEnableTls = bool . Parse ( webServiceEnableTls ) ;
string webServiceUseSelfSignedTlsCertificate = Environment . GetEnvironmentVariable ( "DNS_SERVER_WEB_SERVICE_USE_SELF_SIGNED_CERT" ) ;
if ( ! string . IsNullOrEmpty ( webServiceUseSelfSignedTlsCertificate ) )
_webServiceUseSelfSignedTlsCertificate = bool . Parse ( webServiceUseSelfSignedTlsCertificate ) ;
2022-09-18 18:04:28 +05:30
//optional protocols
string strDnsOverHttp = Environment . GetEnvironmentVariable ( "DNS_SERVER_OPTIONAL_PROTOCOL_DNS_OVER_HTTP" ) ;
if ( ! string . IsNullOrEmpty ( strDnsOverHttp ) )
_dnsServer . EnableDnsOverHttp = bool . Parse ( strDnsOverHttp ) ;
2020-12-25 19:27:36 +05:30
2022-09-18 18:04:28 +05:30
//recursion
string strRecursion = Environment . GetEnvironmentVariable ( "DNS_SERVER_RECURSION" ) ;
if ( ! string . IsNullOrEmpty ( strRecursion ) )
_dnsServer . Recursion = Enum . Parse < DnsServerRecursion > ( strRecursion , true ) ;
else
_dnsServer . Recursion = DnsServerRecursion . AllowOnlyForPrivateNetworks ; //default for security reasons
2020-12-25 19:27:36 +05:30
2024-09-14 19:19:59 +05:30
string strRecursionNetworkACL = Environment . GetEnvironmentVariable ( "DNS_SERVER_RECURSION_NETWORK_ACL" ) ;
if ( ! string . IsNullOrEmpty ( strRecursionNetworkACL ) )
{
_dnsServer . RecursionNetworkACL = strRecursionNetworkACL . Split ( NetworkAccessControl . Parse , ',' ) ;
}
else
{
NetworkAddress [ ] recursionDeniedNetworks = null ;
NetworkAddress [ ] recursionAllowedNetworks = null ;
string strRecursionDeniedNetworks = Environment . GetEnvironmentVariable ( "DNS_SERVER_RECURSION_DENIED_NETWORKS" ) ;
if ( ! string . IsNullOrEmpty ( strRecursionDeniedNetworks ) )
recursionDeniedNetworks = strRecursionDeniedNetworks . Split ( NetworkAddress . Parse , ',' ) ;
2019-06-15 13:30:03 +05:30
2024-09-14 19:19:59 +05:30
string strRecursionAllowedNetworks = Environment . GetEnvironmentVariable ( "DNS_SERVER_RECURSION_ALLOWED_NETWORKS" ) ;
if ( ! string . IsNullOrEmpty ( strRecursionAllowedNetworks ) )
recursionAllowedNetworks = strRecursionAllowedNetworks . Split ( NetworkAddress . Parse , ',' ) ;
2021-01-17 17:54:25 +05:30
2024-09-14 19:19:59 +05:30
_dnsServer . RecursionNetworkACL = AuthZoneInfo . ConvertDenyAllowToACL ( recursionDeniedNetworks , recursionAllowedNetworks ) ;
}
_dnsServer . RandomizeName = false ; //default false to allow resolving from bad name servers
2022-09-18 18:04:28 +05:30
_dnsServer . QnameMinimization = true ; //default true to enable privacy feature
2021-05-16 17:11:04 +05:30
2022-09-18 18:04:28 +05:30
//cache
_dnsServer . CacheZoneManager . MaximumEntries = 10000 ;
2021-05-16 17:11:04 +05:30
2022-09-18 18:04:28 +05:30
//blocking
string strEnableBlocking = Environment . GetEnvironmentVariable ( "DNS_SERVER_ENABLE_BLOCKING" ) ;
if ( ! string . IsNullOrEmpty ( strEnableBlocking ) )
_dnsServer . EnableBlocking = bool . Parse ( strEnableBlocking ) ;
2021-05-16 17:11:04 +05:30
2022-09-18 18:04:28 +05:30
string strAllowTxtBlockingReport = Environment . GetEnvironmentVariable ( "DNS_SERVER_ALLOW_TXT_BLOCKING_REPORT" ) ;
if ( ! string . IsNullOrEmpty ( strAllowTxtBlockingReport ) )
_dnsServer . AllowTxtBlockingReport = bool . Parse ( strAllowTxtBlockingReport ) ;
2021-05-16 17:11:04 +05:30
2022-09-18 18:04:28 +05:30
string strBlockListUrls = Environment . GetEnvironmentVariable ( "DNS_SERVER_BLOCK_LIST_URLS" ) ;
if ( ! string . IsNullOrEmpty ( strBlockListUrls ) )
{
2024-02-04 18:01:49 +05:30
string [ ] strBlockListUrlList = strBlockListUrls . Split ( commaSeparator , StringSplitOptions . RemoveEmptyEntries ) ;
2021-05-23 18:35:35 +05:30
2022-09-18 18:04:28 +05:30
foreach ( string strBlockListUrl in strBlockListUrlList )
{
2023-02-25 13:12:06 +05:30
if ( strBlockListUrl . StartsWith ( '!' ) )
2022-09-18 18:04:28 +05:30
{
Uri allowListUrl = new Uri ( strBlockListUrl . Substring ( 1 ) ) ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
if ( ! _dnsServer . BlockListZoneManager . AllowListUrls . Contains ( allowListUrl ) )
_dnsServer . BlockListZoneManager . AllowListUrls . Add ( allowListUrl ) ;
}
else
{
Uri blockListUrl = new Uri ( strBlockListUrl ) ;
2021-05-16 17:11:04 +05:30
2022-09-18 18:04:28 +05:30
if ( ! _dnsServer . BlockListZoneManager . BlockListUrls . Contains ( blockListUrl ) )
_dnsServer . BlockListZoneManager . BlockListUrls . Add ( blockListUrl ) ;
}
}
}
2021-05-16 17:11:04 +05:30
2022-09-18 18:04:28 +05:30
//proxy & forwarders
string strForwarders = Environment . GetEnvironmentVariable ( "DNS_SERVER_FORWARDERS" ) ;
if ( ! string . IsNullOrEmpty ( strForwarders ) )
{
DnsTransportProtocol forwarderProtocol ;
2021-05-16 17:11:04 +05:30
2022-09-18 18:04:28 +05:30
string strForwarderProtocol = Environment . GetEnvironmentVariable ( "DNS_SERVER_FORWARDER_PROTOCOL" ) ;
if ( string . IsNullOrEmpty ( strForwarderProtocol ) )
2022-12-24 12:57:53 +05:30
{
2022-09-18 18:04:28 +05:30
forwarderProtocol = DnsTransportProtocol . Udp ;
2022-12-24 12:57:53 +05:30
}
2022-09-18 18:04:28 +05:30
else
2022-12-24 12:57:53 +05:30
{
2022-09-18 18:04:28 +05:30
forwarderProtocol = Enum . Parse < DnsTransportProtocol > ( strForwarderProtocol , true ) ;
2022-12-24 12:57:53 +05:30
if ( forwarderProtocol = = DnsTransportProtocol . HttpsJson )
forwarderProtocol = DnsTransportProtocol . Https ;
}
2019-06-15 13:30:03 +05:30
2023-01-01 18:48:08 +05:30
_dnsServer . Forwarders = strForwarders . Split ( delegate ( string value )
2022-11-26 11:55:11 +05:30
{
2023-01-01 18:48:08 +05:30
NameServerAddress forwarder = NameServerAddress . Parse ( value ) ;
2022-11-26 11:55:11 +05:30
if ( forwarder . Protocol ! = forwarderProtocol )
forwarder = forwarder . ChangeProtocol ( forwarderProtocol ) ;
2023-01-01 18:48:08 +05:30
return forwarder ;
} , ',' ) ;
2022-09-18 18:04:28 +05:30
}
2021-05-23 18:35:35 +05:30
2022-09-18 18:04:28 +05:30
//logging
2023-12-02 16:44:19 +05:30
_dnsServer . ResolverLogManager = _log ;
2022-09-18 18:04:28 +05:30
string strUseLocalTime = Environment . GetEnvironmentVariable ( "DNS_SERVER_LOG_USING_LOCAL_TIME" ) ;
if ( ! string . IsNullOrEmpty ( strUseLocalTime ) )
_log . UseLocalTime = bool . Parse ( strUseLocalTime ) ;
2020-12-19 13:32:02 +05:30
2024-02-04 18:01:49 +05:30
_dnsServer . StatsManager . EnableInMemoryStats = false ;
2024-10-26 17:31:28 +05:30
_dnsServer . StatsManager . MaxStatFileDays = 365 ;
2024-02-04 18:01:49 +05:30
2024-05-19 16:08:35 +05:30
SaveConfigFileInternal ( ) ;
2022-09-18 18:04:28 +05:30
}
catch ( Exception ex )
{
_log . Write ( "DNS Server encountered an error while loading config file: " + configFile + "\r\n" + ex . ToString ( ) ) ;
_log . Write ( "Note: You may try deleting the config file to fix this issue. However, you will lose DNS settings but, zone data wont be affected." ) ;
throw ;
}
2023-12-02 16:44:19 +05:30
//exclude web service TLS port to prevent socket pool from occupying it
UdpClientConnection . SocketPoolExcludedPorts = new int [ ] { _webServiceTlsPort } ;
2022-09-18 18:04:28 +05:30
}
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
private void CreateForwarderZoneToDisableDnssecForNTP ( )
{
if ( Environment . OSVersion . Platform = = PlatformID . Unix )
{
//adding a conditional forwarder zone for disabling DNSSEC validation for ntp.org so that systems with no real-time clock can sync time
string ntpDomain = "ntp.org" ;
string fwdRecordComments = "This forwarder zone was automatically created to disable DNSSEC validation for ntp.org to allow systems with no real-time clock (e.g. Raspberry Pi) to sync time via NTP when booting." ;
2023-09-23 18:19:36 +05:30
if ( _dnsServer . AuthZoneManager . CreateForwarderZone ( ntpDomain , DnsTransportProtocol . Udp , "this-server" , false , DnsForwarderRecordProxyType . DefaultProxy , null , 0 , null , null , fwdRecordComments ) is not null )
2022-09-18 18:04:28 +05:30
{
//set permissions
_authManager . SetPermission ( PermissionSection . Zones , ntpDomain , _authManager . GetGroup ( Group . ADMINISTRATORS ) , PermissionFlag . ViewModifyDelete ) ;
_authManager . SetPermission ( PermissionSection . Zones , ntpDomain , _authManager . GetGroup ( Group . DNS_ADMINISTRATORS ) , PermissionFlag . ViewModifyDelete ) ;
_authManager . SaveConfigFile ( ) ;
}
}
}
2019-06-15 13:30:03 +05:30
2024-05-19 16:08:35 +05:30
private void SaveConfigFileInternal ( )
2022-09-18 18:04:28 +05:30
{
string configFile = Path . Combine ( _configFolder , "dns.config" ) ;
2019-12-15 18:35:36 +05:30
2022-09-18 18:04:28 +05:30
using ( MemoryStream mS = new MemoryStream ( ) )
{
//serialize config
WriteConfigTo ( new BinaryWriter ( mS ) ) ;
2019-12-15 18:35:36 +05:30
2022-09-18 18:04:28 +05:30
//write config
mS . Position = 0 ;
2021-02-13 17:25:34 +05:30
2022-09-18 18:04:28 +05:30
using ( FileStream fS = new FileStream ( configFile , FileMode . Create , FileAccess . Write ) )
{
mS . CopyTo ( fS ) ;
}
}
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
_log . Write ( "DNS Server config file was saved: " + configFile ) ;
}
2019-06-15 13:30:03 +05:30
2025-02-15 12:45:41 +05:30
public void SaveConfigFile ( )
2024-05-19 16:08:35 +05:30
{
lock ( _saveLock )
{
if ( _pendingSave )
return ;
_pendingSave = true ;
_saveTimer . Change ( SAVE_TIMER_INITIAL_INTERVAL , Timeout . Infinite ) ;
}
}
2025-02-15 12:45:41 +05:30
private void InspectAndFixZonePermissions ( )
2022-09-18 18:04:28 +05:30
{
Permission permission = _authManager . GetPermission ( PermissionSection . Zones ) ;
2024-02-04 18:01:49 +05:30
if ( permission is null )
throw new DnsWebServiceException ( "Failed to read 'Zones' permissions: auth.config file is probably corrupt." ) ;
2022-09-18 18:04:28 +05:30
IReadOnlyDictionary < string , Permission > subItemPermissions = permission . SubItemPermissions ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
//remove ghost permissions
foreach ( KeyValuePair < string , Permission > subItemPermission in subItemPermissions )
{
string zoneName = subItemPermission . Key ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
if ( _dnsServer . AuthZoneManager . GetAuthZoneInfo ( zoneName ) is null )
permission . RemoveAllSubItemPermissions ( zoneName ) ; //no such zone exists; remove permissions
}
2020-06-06 16:52:36 +05:30
2022-09-18 18:04:28 +05:30
//add missing admin permissions
2023-02-12 13:15:13 +05:30
IReadOnlyList < AuthZoneInfo > zones = _dnsServer . AuthZoneManager . GetAllZones ( ) ;
2022-09-18 18:04:28 +05:30
Group admins = _authManager . GetGroup ( Group . ADMINISTRATORS ) ;
2024-02-04 18:01:49 +05:30
if ( admins is null )
throw new DnsWebServiceException ( "Failed to find 'Administrators' group: auth.config file is probably corrupt." ) ;
2022-09-18 18:04:28 +05:30
Group dnsAdmins = _authManager . GetGroup ( Group . DNS_ADMINISTRATORS ) ;
2024-02-04 18:01:49 +05:30
if ( dnsAdmins is null )
throw new DnsWebServiceException ( "Failed to find 'DNS Administrators' group: auth.config file is probably corrupt." ) ;
2020-06-06 16:52:36 +05:30
2022-09-18 18:04:28 +05:30
foreach ( AuthZoneInfo zone in zones )
{
if ( zone . Internal )
{
_authManager . SetPermission ( PermissionSection . Zones , zone . Name , admins , PermissionFlag . View ) ;
_authManager . SetPermission ( PermissionSection . Zones , zone . Name , dnsAdmins , PermissionFlag . View ) ;
}
else
{
_authManager . SetPermission ( PermissionSection . Zones , zone . Name , admins , PermissionFlag . ViewModifyDelete ) ;
_authManager . SetPermission ( PermissionSection . Zones , zone . Name , dnsAdmins , PermissionFlag . ViewModifyDelete ) ;
}
}
2020-06-06 16:52:36 +05:30
2022-09-18 18:04:28 +05:30
_authManager . SaveConfigFile ( ) ;
}
2019-06-15 13:30:03 +05:30
2022-09-24 16:06:19 +05:30
private int ReadConfigFrom ( BinaryReader bR )
2022-09-18 18:04:28 +05:30
{
if ( Encoding . ASCII . GetString ( bR . ReadBytes ( 2 ) ) ! = "DS" ) //format
throw new InvalidDataException ( "DNS Server config file format is invalid." ) ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
int version = bR . ReadByte ( ) ;
2019-06-15 13:30:03 +05:30
2025-03-29 19:12:54 +05:30
if ( ( version > = 28 ) & & ( version < = 41 ) )
2022-09-18 18:04:28 +05:30
{
ReadConfigFrom ( bR , version ) ;
}
else if ( ( version > = 2 ) & & ( version < = 27 ) )
{
ReadOldConfigFrom ( bR , version ) ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
//new default settings
2024-02-04 18:01:49 +05:30
DnsClientConnection . IPv4SourceAddresses = null ;
DnsClientConnection . IPv6SourceAddresses = null ;
2024-12-21 15:49:16 +05:30
_dnsServer . MaxConcurrentResolutionsPerCore = 100 ;
2024-09-14 19:19:59 +05:30
_appsApi . EnableAutomaticUpdate = true ;
2023-10-29 19:16:36 +05:30
_webServiceEnableHttp3 = _webServiceEnableTls & & IsQuicSupported ( ) ;
2024-09-14 19:19:59 +05:30
_dnsServer . EnableDnsOverHttp3 = _dnsServer . EnableDnsOverHttps & & IsQuicSupported ( ) ;
2024-10-19 17:01:05 +05:30
_webServiceRealIpHeader = "X-Real-IP" ;
_dnsServer . DnsOverHttpRealIpHeader = "X-Real-IP" ;
2024-05-19 16:08:35 +05:30
_dnsServer . ResponsiblePersonInternal = null ;
2023-10-29 19:16:36 +05:30
_dnsServer . AuthZoneManager . UseSoaSerialDateScheme = false ;
2024-12-21 15:49:16 +05:30
_dnsServer . AuthZoneManager . MinSoaRefresh = 300 ;
_dnsServer . AuthZoneManager . MinSoaRetry = 300 ;
2023-10-29 19:16:36 +05:30
_dnsServer . ZoneTransferAllowedNetworks = null ;
2024-02-04 18:01:49 +05:30
_dnsServer . NotifyAllowedNetworks = null ;
2024-03-16 15:50:11 +05:30
_dnsServer . EDnsClientSubnet = false ;
_dnsServer . EDnsClientSubnetIPv4PrefixLength = 24 ;
_dnsServer . EDnsClientSubnetIPv6PrefixLength = 56 ;
_dnsServer . EDnsClientSubnetIpv4Override = null ;
_dnsServer . EDnsClientSubnetIpv6Override = null ;
2024-02-04 18:01:49 +05:30
_dnsServer . QpmLimitBypassList = null ;
2024-11-16 13:43:33 +05:30
if ( _dnsServer . EnableDnsOverUdpProxy | | _dnsServer . EnableDnsOverTcpProxy | | _dnsServer . EnableDnsOverHttp )
{
_dnsServer . ReverseProxyNetworkACL =
[
new NetworkAccessControl ( IPAddress . Parse ( "127.0.0.0" ) , 8 ) ,
new NetworkAccessControl ( IPAddress . Parse ( "10.0.0.0" ) , 8 ) ,
new NetworkAccessControl ( IPAddress . Parse ( "100.64.0.0" ) , 10 ) ,
new NetworkAccessControl ( IPAddress . Parse ( "169.254.0.0" ) , 16 ) ,
new NetworkAccessControl ( IPAddress . Parse ( "172.16.0.0" ) , 12 ) ,
new NetworkAccessControl ( IPAddress . Parse ( "192.168.0.0" ) , 16 ) ,
new NetworkAccessControl ( IPAddress . Parse ( "2000::" ) , 3 , true ) ,
new NetworkAccessControl ( IPAddress . IPv6Any , 0 )
] ;
}
2023-10-29 19:16:36 +05:30
_dnsServer . BlockingBypassList = null ;
2024-10-19 17:01:05 +05:30
_dnsServer . BlockingAnswerTtl = 30 ;
2024-09-14 19:19:59 +05:30
_dnsServer . ResolverConcurrency = 2 ;
2024-05-19 16:08:35 +05:30
_dnsServer . CacheZoneManager . ServeStaleAnswerTtl = CacheZoneManager . SERVE_STALE_ANSWER_TTL ;
_dnsServer . CacheZoneManager . ServeStaleResetTtl = CacheZoneManager . SERVE_STALE_RESET_TTL ;
_dnsServer . ServeStaleMaxWaitTime = DnsServer . SERVE_STALE_MAX_WAIT_TIME ;
2024-09-14 19:19:59 +05:30
_dnsServer . ConcurrentForwarding = true ;
2023-10-29 19:16:36 +05:30
_dnsServer . ResolverLogManager = _log ;
2024-02-04 18:01:49 +05:30
_dnsServer . StatsManager . EnableInMemoryStats = false ;
2022-09-18 18:04:28 +05:30
}
else
{
throw new InvalidDataException ( "DNS Server config version not supported." ) ;
}
2022-09-24 16:06:19 +05:30
return version ;
2022-09-18 18:04:28 +05:30
}
2021-05-29 13:17:22 +05:30
2022-09-18 18:04:28 +05:30
private void ReadConfigFrom ( BinaryReader bR , int version )
{
//web service
{
_webServiceHttpPort = bR . ReadInt32 ( ) ;
_webServiceTlsPort = bR . ReadInt32 ( ) ;
2021-05-29 13:17:22 +05:30
2022-09-18 18:04:28 +05:30
{
int count = bR . ReadByte ( ) ;
if ( count > 0 )
{
IPAddress [ ] localAddresses = new IPAddress [ count ] ;
2021-05-29 13:17:22 +05:30
2022-09-18 18:04:28 +05:30
for ( int i = 0 ; i < count ; i + + )
2023-02-05 16:32:28 +05:30
localAddresses [ i ] = IPAddressExtensions . ReadFrom ( bR ) ;
2021-05-29 13:17:22 +05:30
2022-09-18 18:04:28 +05:30
_webServiceLocalAddresses = localAddresses ;
}
2023-08-12 13:13:22 +05:30
else
{
_webServiceLocalAddresses = new IPAddress [ ] { IPAddress . Any , IPAddress . IPv6Any } ;
}
2022-09-18 18:04:28 +05:30
}
2021-05-29 13:17:22 +05:30
2022-09-18 18:04:28 +05:30
_webServiceEnableTls = bR . ReadBoolean ( ) ;
2023-10-29 19:16:36 +05:30
if ( version > = 33 )
_webServiceEnableHttp3 = bR . ReadBoolean ( ) ;
else
_webServiceEnableHttp3 = _webServiceEnableTls & & IsQuicSupported ( ) ;
2022-09-18 18:04:28 +05:30
_webServiceHttpToTlsRedirect = bR . ReadBoolean ( ) ;
_webServiceUseSelfSignedTlsCertificate = bR . ReadBoolean ( ) ;
2021-04-11 17:43:20 +05:30
2022-09-18 18:04:28 +05:30
_webServiceTlsCertificatePath = bR . ReadShortString ( ) ;
_webServiceTlsCertificatePassword = bR . ReadShortString ( ) ;
2022-09-24 11:49:35 +05:30
if ( _webServiceTlsCertificatePath . Length = = 0 )
_webServiceTlsCertificatePath = null ;
2023-08-12 13:13:22 +05:30
if ( _webServiceTlsCertificatePath is not null )
2022-09-24 11:49:35 +05:30
{
2023-08-12 13:13:22 +05:30
string webServiceTlsCertificatePath = ConvertToAbsolutePath ( _webServiceTlsCertificatePath ) ;
2022-09-24 11:49:35 +05:30
try
{
2023-08-12 13:13:22 +05:30
LoadWebServiceTlsCertificate ( webServiceTlsCertificatePath , _webServiceTlsCertificatePassword ) ;
2022-09-24 11:49:35 +05:30
}
catch ( Exception ex )
{
2023-08-12 13:13:22 +05:30
_log . Write ( "DNS Server encountered an error while loading Web Service TLS certificate: " + webServiceTlsCertificatePath + "\r\n" + ex . ToString ( ) ) ;
2022-09-24 11:49:35 +05:30
}
StartTlsCertificateUpdateTimer ( ) ;
}
SelfSignedCertCheck ( false , false ) ;
2024-10-19 17:01:05 +05:30
if ( version > = 38 )
_webServiceRealIpHeader = bR . ReadShortString ( ) ;
else
_webServiceRealIpHeader = "X-Real-IP" ;
2022-09-18 18:04:28 +05:30
}
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
//dns
{
//general
_dnsServer . ServerDomain = bR . ReadShortString ( ) ;
2021-03-21 20:05:06 +05:30
2022-09-18 18:04:28 +05:30
{
int count = bR . ReadByte ( ) ;
if ( count > 0 )
{
IPEndPoint [ ] localEndPoints = new IPEndPoint [ count ] ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
for ( int i = 0 ; i < count ; i + + )
2023-02-05 16:32:28 +05:30
localEndPoints [ i ] = ( IPEndPoint ) EndPointExtensions . ReadFrom ( bR ) ;
2020-12-19 13:32:02 +05:30
2022-09-18 18:04:28 +05:30
_dnsServer . LocalEndPoints = localEndPoints ;
}
2023-08-12 13:13:22 +05:30
else
{
_dnsServer . LocalEndPoints = new IPEndPoint [ ] { new IPEndPoint ( IPAddress . Any , 53 ) , new IPEndPoint ( IPAddress . IPv6Any , 53 ) } ;
}
2022-09-18 18:04:28 +05:30
}
2024-02-04 18:01:49 +05:30
if ( version > = 34 )
{
2024-09-14 19:19:59 +05:30
DnsClientConnection . IPv4SourceAddresses = AuthZoneInfo . ReadNetworkAddressesFrom ( bR ) ;
DnsClientConnection . IPv6SourceAddresses = AuthZoneInfo . ReadNetworkAddressesFrom ( bR ) ;
2024-02-04 18:01:49 +05:30
}
else
{
DnsClientConnection . IPv4SourceAddresses = null ;
DnsClientConnection . IPv6SourceAddresses = null ;
}
2022-09-18 18:04:28 +05:30
_zonesApi . DefaultRecordTtl = bR . ReadUInt32 ( ) ;
2023-10-29 19:16:36 +05:30
2024-05-19 16:08:35 +05:30
if ( version > = 36 )
{
string rp = bR . ReadString ( ) ;
if ( rp . Length = = 0 )
_dnsServer . ResponsiblePersonInternal = null ;
else
_dnsServer . ResponsiblePersonInternal = new MailAddress ( rp ) ;
}
else
{
_dnsServer . ResponsiblePersonInternal = null ;
}
2023-10-29 19:16:36 +05:30
if ( version > = 33 )
_dnsServer . AuthZoneManager . UseSoaSerialDateScheme = bR . ReadBoolean ( ) ;
2024-12-21 15:49:16 +05:30
else
_dnsServer . AuthZoneManager . UseSoaSerialDateScheme = false ;
if ( version > = 40 )
{
_dnsServer . AuthZoneManager . MinSoaRefresh = bR . ReadUInt32 ( ) ;
_dnsServer . AuthZoneManager . MinSoaRetry = bR . ReadUInt32 ( ) ;
2023-10-29 19:16:36 +05:30
}
else
{
2024-12-21 15:49:16 +05:30
_dnsServer . AuthZoneManager . MinSoaRefresh = 300 ;
_dnsServer . AuthZoneManager . MinSoaRetry = 300 ;
2023-10-29 19:16:36 +05:30
}
2024-12-21 15:49:16 +05:30
if ( version > = 33 )
_dnsServer . ZoneTransferAllowedNetworks = AuthZoneInfo . ReadNetworkAddressesFrom ( bR ) ;
else
_dnsServer . ZoneTransferAllowedNetworks = null ;
2024-02-04 18:01:49 +05:30
if ( version > = 34 )
2024-09-14 19:19:59 +05:30
_dnsServer . NotifyAllowedNetworks = AuthZoneInfo . ReadNetworkAddressesFrom ( bR ) ;
2024-02-04 18:01:49 +05:30
else
_dnsServer . NotifyAllowedNetworks = null ;
2022-09-18 18:04:28 +05:30
_appsApi . EnableAutomaticUpdate = bR . ReadBoolean ( ) ;
_dnsServer . PreferIPv6 = bR . ReadBoolean ( ) ;
_dnsServer . UdpPayloadSize = bR . ReadUInt16 ( ) ;
_dnsServer . DnssecValidation = bR . ReadBoolean ( ) ;
2022-11-20 16:30:03 +05:30
if ( version > = 29 )
{
_dnsServer . EDnsClientSubnet = bR . ReadBoolean ( ) ;
_dnsServer . EDnsClientSubnetIPv4PrefixLength = bR . ReadByte ( ) ;
_dnsServer . EDnsClientSubnetIPv6PrefixLength = bR . ReadByte ( ) ;
}
else
{
_dnsServer . EDnsClientSubnet = false ;
_dnsServer . EDnsClientSubnetIPv4PrefixLength = 24 ;
_dnsServer . EDnsClientSubnetIPv6PrefixLength = 56 ;
}
2024-03-16 15:50:11 +05:30
if ( version > = 35 )
{
if ( bR . ReadBoolean ( ) )
_dnsServer . EDnsClientSubnetIpv4Override = NetworkAddress . ReadFrom ( bR ) ;
else
_dnsServer . EDnsClientSubnetIpv4Override = null ;
if ( bR . ReadBoolean ( ) )
_dnsServer . EDnsClientSubnetIpv6Override = NetworkAddress . ReadFrom ( bR ) ;
else
_dnsServer . EDnsClientSubnetIpv6Override = null ;
}
else
{
_dnsServer . EDnsClientSubnetIpv4Override = null ;
_dnsServer . EDnsClientSubnetIpv6Override = null ;
}
2022-09-18 18:04:28 +05:30
_dnsServer . QpmLimitRequests = bR . ReadInt32 ( ) ;
_dnsServer . QpmLimitErrors = bR . ReadInt32 ( ) ;
_dnsServer . QpmLimitSampleMinutes = bR . ReadInt32 ( ) ;
_dnsServer . QpmLimitIPv4PrefixLength = bR . ReadInt32 ( ) ;
_dnsServer . QpmLimitIPv6PrefixLength = bR . ReadInt32 ( ) ;
2024-02-04 18:01:49 +05:30
if ( version > = 34 )
2024-09-14 19:19:59 +05:30
_dnsServer . QpmLimitBypassList = AuthZoneInfo . ReadNetworkAddressesFrom ( bR ) ;
2024-02-04 18:01:49 +05:30
else
_dnsServer . QpmLimitBypassList = null ;
2022-09-18 18:04:28 +05:30
_dnsServer . ClientTimeout = bR . ReadInt32 ( ) ;
2024-02-04 18:01:49 +05:30
if ( version < 34 )
{
if ( _dnsServer . ClientTimeout = = 4000 )
_dnsServer . ClientTimeout = 2000 ;
}
2022-09-18 18:04:28 +05:30
_dnsServer . TcpSendTimeout = bR . ReadInt32 ( ) ;
_dnsServer . TcpReceiveTimeout = bR . ReadInt32 ( ) ;
2023-01-14 14:59:50 +05:30
if ( version > = 30 )
{
_dnsServer . QuicIdleTimeout = bR . ReadInt32 ( ) ;
_dnsServer . QuicMaxInboundStreams = bR . ReadInt32 ( ) ;
_dnsServer . ListenBacklog = bR . ReadInt32 ( ) ;
}
else
{
_dnsServer . QuicIdleTimeout = 60000 ;
_dnsServer . QuicMaxInboundStreams = 100 ;
_dnsServer . ListenBacklog = 100 ;
}
2024-12-21 15:49:16 +05:30
if ( version > = 40 )
_dnsServer . MaxConcurrentResolutionsPerCore = bR . ReadUInt16 ( ) ;
else
_dnsServer . MaxConcurrentResolutionsPerCore = 100 ;
2022-09-18 18:04:28 +05:30
//optional protocols
2023-08-12 13:13:22 +05:30
if ( version > = 32 )
{
_dnsServer . EnableDnsOverUdpProxy = bR . ReadBoolean ( ) ;
_dnsServer . EnableDnsOverTcpProxy = bR . ReadBoolean ( ) ;
}
else
{
_dnsServer . EnableDnsOverUdpProxy = false ;
_dnsServer . EnableDnsOverTcpProxy = false ;
}
2022-09-18 18:04:28 +05:30
_dnsServer . EnableDnsOverHttp = bR . ReadBoolean ( ) ;
_dnsServer . EnableDnsOverTls = bR . ReadBoolean ( ) ;
_dnsServer . EnableDnsOverHttps = bR . ReadBoolean ( ) ;
2024-09-14 19:19:59 +05:30
if ( version > = 37 )
_dnsServer . EnableDnsOverHttp3 = bR . ReadBoolean ( ) ;
else
_dnsServer . EnableDnsOverHttp3 = _dnsServer . EnableDnsOverHttps & & IsQuicSupported ( ) ;
2023-08-12 13:13:22 +05:30
if ( version > = 32 )
{
_dnsServer . EnableDnsOverQuic = bR . ReadBoolean ( ) ;
_dnsServer . DnsOverUdpProxyPort = bR . ReadInt32 ( ) ;
_dnsServer . DnsOverTcpProxyPort = bR . ReadInt32 ( ) ;
_dnsServer . DnsOverHttpPort = bR . ReadInt32 ( ) ;
_dnsServer . DnsOverTlsPort = bR . ReadInt32 ( ) ;
_dnsServer . DnsOverHttpsPort = bR . ReadInt32 ( ) ;
_dnsServer . DnsOverQuicPort = bR . ReadInt32 ( ) ;
}
else if ( version > = 31 )
2023-02-12 13:15:13 +05:30
{
_dnsServer . EnableDnsOverQuic = bR . ReadBoolean ( ) ;
_dnsServer . DnsOverHttpPort = bR . ReadInt32 ( ) ;
_dnsServer . DnsOverTlsPort = bR . ReadInt32 ( ) ;
_dnsServer . DnsOverHttpsPort = bR . ReadInt32 ( ) ;
_dnsServer . DnsOverQuicPort = bR . ReadInt32 ( ) ;
}
else if ( version > = 30 )
2023-01-14 14:59:50 +05:30
{
2023-02-12 13:15:13 +05:30
_ = bR . ReadBoolean ( ) ; //removed EnableDnsOverHttpPort80 value
2023-01-14 14:59:50 +05:30
_dnsServer . EnableDnsOverQuic = bR . ReadBoolean ( ) ;
_dnsServer . DnsOverHttpPort = bR . ReadInt32 ( ) ;
_dnsServer . DnsOverTlsPort = bR . ReadInt32 ( ) ;
_dnsServer . DnsOverHttpsPort = bR . ReadInt32 ( ) ;
_dnsServer . DnsOverQuicPort = bR . ReadInt32 ( ) ;
}
else
{
_dnsServer . EnableDnsOverQuic = false ;
2023-08-12 13:13:22 +05:30
_dnsServer . DnsOverUdpProxyPort = 538 ;
_dnsServer . DnsOverTcpProxyPort = 538 ;
2023-02-12 13:15:13 +05:30
if ( _dnsServer . EnableDnsOverHttps )
{
_dnsServer . EnableDnsOverHttp = true ;
_dnsServer . DnsOverHttpPort = 80 ;
}
else if ( _dnsServer . EnableDnsOverHttp )
{
_dnsServer . DnsOverHttpPort = 8053 ;
}
else
{
_dnsServer . DnsOverHttpPort = 80 ;
}
2023-01-14 14:59:50 +05:30
_dnsServer . DnsOverTlsPort = 853 ;
_dnsServer . DnsOverHttpsPort = 443 ;
_dnsServer . DnsOverQuicPort = 853 ;
}
2024-11-16 13:43:33 +05:30
if ( version > = 39 )
{
_dnsServer . ReverseProxyNetworkACL = AuthZoneInfo . ReadNetworkACLFrom ( bR ) ;
}
else
{
if ( _dnsServer . EnableDnsOverUdpProxy | | _dnsServer . EnableDnsOverTcpProxy | | _dnsServer . EnableDnsOverHttp )
{
_dnsServer . ReverseProxyNetworkACL =
[
new NetworkAccessControl ( IPAddress . Parse ( "127.0.0.0" ) , 8 ) ,
new NetworkAccessControl ( IPAddress . Parse ( "10.0.0.0" ) , 8 ) ,
new NetworkAccessControl ( IPAddress . Parse ( "100.64.0.0" ) , 10 ) ,
new NetworkAccessControl ( IPAddress . Parse ( "169.254.0.0" ) , 16 ) ,
new NetworkAccessControl ( IPAddress . Parse ( "172.16.0.0" ) , 12 ) ,
new NetworkAccessControl ( IPAddress . Parse ( "192.168.0.0" ) , 16 ) ,
new NetworkAccessControl ( IPAddress . Parse ( "2000::" ) , 3 , true ) ,
new NetworkAccessControl ( IPAddress . IPv6Any , 0 )
] ;
}
}
2022-09-18 18:04:28 +05:30
_dnsTlsCertificatePath = bR . ReadShortString ( ) ;
_dnsTlsCertificatePassword = bR . ReadShortString ( ) ;
if ( _dnsTlsCertificatePath . Length = = 0 )
_dnsTlsCertificatePath = null ;
if ( _dnsTlsCertificatePath ! = null )
{
2023-08-12 13:13:22 +05:30
string dnsTlsCertificatePath = ConvertToAbsolutePath ( _dnsTlsCertificatePath ) ;
2022-09-18 18:04:28 +05:30
try
{
2023-08-12 13:13:22 +05:30
LoadDnsTlsCertificate ( dnsTlsCertificatePath , _dnsTlsCertificatePassword ) ;
2022-09-18 18:04:28 +05:30
}
catch ( Exception ex )
{
2023-08-12 13:13:22 +05:30
_log . Write ( "DNS Server encountered an error while loading DNS Server TLS certificate: " + dnsTlsCertificatePath + "\r\n" + ex . ToString ( ) ) ;
2022-09-18 18:04:28 +05:30
}
StartTlsCertificateUpdateTimer ( ) ;
}
2024-10-19 17:01:05 +05:30
if ( version > = 38 )
_dnsServer . DnsOverHttpRealIpHeader = bR . ReadShortString ( ) ;
else
_dnsServer . DnsOverHttpRealIpHeader = "X-Real-IP" ;
2022-09-18 18:04:28 +05:30
//tsig
{
int count = bR . ReadByte ( ) ;
Dictionary < string , TsigKey > tsigKeys = new Dictionary < string , TsigKey > ( count ) ;
for ( int i = 0 ; i < count ; i + + )
{
string keyName = bR . ReadShortString ( ) ;
string sharedSecret = bR . ReadShortString ( ) ;
TsigAlgorithm algorithm = ( TsigAlgorithm ) bR . ReadByte ( ) ;
tsigKeys . Add ( keyName , new TsigKey ( keyName , sharedSecret , algorithm ) ) ;
}
_dnsServer . TsigKeys = tsigKeys ;
}
//recursion
_dnsServer . Recursion = ( DnsServerRecursion ) bR . ReadByte ( ) ;
2024-09-14 19:19:59 +05:30
if ( version > = 37 )
{
_dnsServer . RecursionNetworkACL = AuthZoneInfo . ReadNetworkACLFrom ( bR ) ;
}
else
{
NetworkAddress [ ] recursionDeniedNetworks = AuthZoneInfo . ReadNetworkAddressesFrom ( bR ) ;
NetworkAddress [ ] recursionAllowedNetworks = AuthZoneInfo . ReadNetworkAddressesFrom ( bR ) ;
_dnsServer . RecursionNetworkACL = AuthZoneInfo . ConvertDenyAllowToACL ( recursionDeniedNetworks , recursionAllowedNetworks ) ;
}
2022-09-18 18:04:28 +05:30
_dnsServer . RandomizeName = bR . ReadBoolean ( ) ;
_dnsServer . QnameMinimization = bR . ReadBoolean ( ) ;
2025-03-29 19:12:54 +05:30
if ( version < = 40 )
_ = bR . ReadBoolean ( ) ; //removed NsRevalidation option
2022-09-18 18:04:28 +05:30
_dnsServer . ResolverRetries = bR . ReadInt32 ( ) ;
_dnsServer . ResolverTimeout = bR . ReadInt32 ( ) ;
2024-09-14 19:19:59 +05:30
if ( version > = 37 )
_dnsServer . ResolverConcurrency = bR . ReadInt32 ( ) ;
else
_dnsServer . ResolverConcurrency = 2 ;
2022-09-18 18:04:28 +05:30
_dnsServer . ResolverMaxStackCount = bR . ReadInt32 ( ) ;
//cache
2023-01-14 14:59:50 +05:30
if ( version > = 30 )
_saveCache = bR . ReadBoolean ( ) ;
else
2023-04-23 16:28:27 +05:30
_saveCache = true ;
2023-01-14 14:59:50 +05:30
2022-09-18 18:04:28 +05:30
_dnsServer . ServeStale = bR . ReadBoolean ( ) ;
_dnsServer . CacheZoneManager . ServeStaleTtl = bR . ReadUInt32 ( ) ;
2024-05-19 16:08:35 +05:30
if ( version > = 36 )
{
_dnsServer . CacheZoneManager . ServeStaleAnswerTtl = bR . ReadUInt32 ( ) ;
_dnsServer . CacheZoneManager . ServeStaleResetTtl = bR . ReadUInt32 ( ) ;
_dnsServer . ServeStaleMaxWaitTime = bR . ReadInt32 ( ) ;
}
else
{
_dnsServer . CacheZoneManager . ServeStaleAnswerTtl = CacheZoneManager . SERVE_STALE_ANSWER_TTL ;
_dnsServer . CacheZoneManager . ServeStaleResetTtl = CacheZoneManager . SERVE_STALE_RESET_TTL ;
_dnsServer . ServeStaleMaxWaitTime = DnsServer . SERVE_STALE_MAX_WAIT_TIME ;
}
2022-09-18 18:04:28 +05:30
_dnsServer . CacheZoneManager . MaximumEntries = bR . ReadInt64 ( ) ;
_dnsServer . CacheZoneManager . MinimumRecordTtl = bR . ReadUInt32 ( ) ;
_dnsServer . CacheZoneManager . MaximumRecordTtl = bR . ReadUInt32 ( ) ;
_dnsServer . CacheZoneManager . NegativeRecordTtl = bR . ReadUInt32 ( ) ;
_dnsServer . CacheZoneManager . FailureRecordTtl = bR . ReadUInt32 ( ) ;
_dnsServer . CachePrefetchEligibility = bR . ReadInt32 ( ) ;
_dnsServer . CachePrefetchTrigger = bR . ReadInt32 ( ) ;
_dnsServer . CachePrefetchSampleIntervalInMinutes = bR . ReadInt32 ( ) ;
_dnsServer . CachePrefetchSampleEligibilityHitsPerHour = bR . ReadInt32 ( ) ;
//blocking
_dnsServer . EnableBlocking = bR . ReadBoolean ( ) ;
_dnsServer . AllowTxtBlockingReport = bR . ReadBoolean ( ) ;
2023-10-29 19:16:36 +05:30
if ( version > = 33 )
2024-09-14 19:19:59 +05:30
_dnsServer . BlockingBypassList = AuthZoneInfo . ReadNetworkAddressesFrom ( bR ) ;
2023-10-29 19:16:36 +05:30
else
_dnsServer . BlockingBypassList = null ;
2022-09-18 18:04:28 +05:30
_dnsServer . BlockingType = ( DnsServerBlockingType ) bR . ReadByte ( ) ;
2024-10-19 17:01:05 +05:30
if ( version > = 38 )
_dnsServer . BlockingAnswerTtl = bR . ReadUInt32 ( ) ;
else
_dnsServer . BlockingAnswerTtl = 30 ;
2022-09-18 18:04:28 +05:30
{
//read custom blocking addresses
int count = bR . ReadByte ( ) ;
if ( count > 0 )
{
List < DnsARecordData > dnsARecords = new List < DnsARecordData > ( ) ;
List < DnsAAAARecordData > dnsAAAARecords = new List < DnsAAAARecordData > ( ) ;
for ( int i = 0 ; i < count ; i + + )
{
2023-02-05 16:32:28 +05:30
IPAddress customAddress = IPAddressExtensions . ReadFrom ( bR ) ;
2022-09-18 18:04:28 +05:30
switch ( customAddress . AddressFamily )
2021-08-07 17:28:33 +05:30
{
2022-09-18 18:04:28 +05:30
case AddressFamily . InterNetwork :
dnsARecords . Add ( new DnsARecordData ( customAddress ) ) ;
break ;
case AddressFamily . InterNetworkV6 :
dnsAAAARecords . Add ( new DnsAAAARecordData ( customAddress ) ) ;
break ;
2021-08-07 17:28:33 +05:30
}
2022-09-18 18:04:28 +05:30
}
_dnsServer . CustomBlockingARecords = dnsARecords ;
_dnsServer . CustomBlockingAAAARecords = dnsAAAARecords ;
}
2023-08-12 13:13:22 +05:30
else
{
_dnsServer . CustomBlockingARecords = null ;
_dnsServer . CustomBlockingAAAARecords = null ;
}
2022-09-18 18:04:28 +05:30
}
{
//read block list urls
int count = bR . ReadByte ( ) ;
2023-08-12 13:13:22 +05:30
_dnsServer . BlockListZoneManager . AllowListUrls . Clear ( ) ;
_dnsServer . BlockListZoneManager . BlockListUrls . Clear ( ) ;
2022-09-18 18:04:28 +05:30
for ( int i = 0 ; i < count ; i + + )
{
string listUrl = bR . ReadShortString ( ) ;
2023-02-25 13:12:06 +05:30
if ( listUrl . StartsWith ( '!' ) )
2022-09-18 18:04:28 +05:30
_dnsServer . BlockListZoneManager . AllowListUrls . Add ( new Uri ( listUrl . Substring ( 1 ) ) ) ;
else
_dnsServer . BlockListZoneManager . BlockListUrls . Add ( new Uri ( listUrl ) ) ;
}
2022-12-24 17:14:51 +05:30
_settingsApi . BlockListUpdateIntervalHours = bR . ReadInt32 ( ) ;
_settingsApi . BlockListLastUpdatedOn = bR . ReadDateTime ( ) ;
2022-09-18 18:04:28 +05:30
}
//proxy & forwarders
NetProxyType proxyType = ( NetProxyType ) bR . ReadByte ( ) ;
if ( proxyType ! = NetProxyType . None )
{
string address = bR . ReadShortString ( ) ;
int port = bR . ReadInt32 ( ) ;
NetworkCredential credential = null ;
if ( bR . ReadBoolean ( ) ) //credential set
credential = new NetworkCredential ( bR . ReadShortString ( ) , bR . ReadShortString ( ) ) ;
_dnsServer . Proxy = NetProxy . CreateProxy ( proxyType , address , port , credential ) ;
int count = bR . ReadByte ( ) ;
List < NetProxyBypassItem > bypassList = new List < NetProxyBypassItem > ( count ) ;
for ( int i = 0 ; i < count ; i + + )
bypassList . Add ( new NetProxyBypassItem ( bR . ReadShortString ( ) ) ) ;
_dnsServer . Proxy . BypassList = bypassList ;
}
else
{
_dnsServer . Proxy = null ;
}
{
int count = bR . ReadByte ( ) ;
if ( count > 0 )
{
NameServerAddress [ ] forwarders = new NameServerAddress [ count ] ;
for ( int i = 0 ; i < count ; i + + )
2022-12-24 12:57:53 +05:30
{
2022-09-18 18:04:28 +05:30
forwarders [ i ] = new NameServerAddress ( bR ) ;
2022-12-24 12:57:53 +05:30
if ( forwarders [ i ] . Protocol = = DnsTransportProtocol . HttpsJson )
forwarders [ i ] = forwarders [ i ] . ChangeProtocol ( DnsTransportProtocol . Https ) ;
}
2022-09-18 18:04:28 +05:30
_dnsServer . Forwarders = forwarders ;
}
2023-08-12 13:13:22 +05:30
else
{
_dnsServer . Forwarders = null ;
}
2022-09-18 18:04:28 +05:30
}
2024-09-14 19:19:59 +05:30
if ( version > = 37 )
_dnsServer . ConcurrentForwarding = bR . ReadBoolean ( ) ;
else
_dnsServer . ConcurrentForwarding = true ;
2022-09-18 18:04:28 +05:30
_dnsServer . ForwarderRetries = bR . ReadInt32 ( ) ;
_dnsServer . ForwarderTimeout = bR . ReadInt32 ( ) ;
_dnsServer . ForwarderConcurrency = bR . ReadInt32 ( ) ;
//logging
2023-10-29 19:16:36 +05:30
if ( version > = 33 )
{
if ( bR . ReadBoolean ( ) ) //ignore resolver logs
_dnsServer . ResolverLogManager = null ;
else
_dnsServer . ResolverLogManager = _log ;
}
else
{
_dnsServer . ResolverLogManager = _log ;
}
2022-09-18 18:04:28 +05:30
if ( bR . ReadBoolean ( ) ) //log all queries
_dnsServer . QueryLogManager = _log ;
else
_dnsServer . QueryLogManager = null ;
2024-02-04 18:01:49 +05:30
if ( version > = 34 )
_dnsServer . StatsManager . EnableInMemoryStats = bR . ReadBoolean ( ) ;
else
_dnsServer . StatsManager . EnableInMemoryStats = false ;
2024-10-26 17:31:28 +05:30
{
int maxStatFileDays = bR . ReadInt32 ( ) ;
if ( maxStatFileDays < 0 )
maxStatFileDays = 0 ;
_dnsServer . StatsManager . MaxStatFileDays = maxStatFileDays ;
}
2022-09-18 18:04:28 +05:30
}
2022-09-24 11:49:35 +05:30
if ( ( _webServiceTlsCertificatePath = = null ) & & ( _dnsTlsCertificatePath = = null ) )
StopTlsCertificateUpdateTimer ( ) ;
2022-09-18 18:04:28 +05:30
}
private void ReadOldConfigFrom ( BinaryReader bR , int version )
{
_dnsServer . ServerDomain = bR . ReadShortString ( ) ;
_webServiceHttpPort = bR . ReadInt32 ( ) ;
if ( version > = 13 )
{
{
int count = bR . ReadByte ( ) ;
if ( count > 0 )
{
IPAddress [ ] localAddresses = new IPAddress [ count ] ;
for ( int i = 0 ; i < count ; i + + )
2023-02-05 16:32:28 +05:30
localAddresses [ i ] = IPAddressExtensions . ReadFrom ( bR ) ;
2022-09-18 18:04:28 +05:30
_webServiceLocalAddresses = localAddresses ;
}
2023-08-12 13:13:22 +05:30
else
{
_webServiceLocalAddresses = new IPAddress [ ] { IPAddress . Any , IPAddress . IPv6Any } ;
}
2022-09-18 18:04:28 +05:30
}
_webServiceTlsPort = bR . ReadInt32 ( ) ;
_webServiceEnableTls = bR . ReadBoolean ( ) ;
_webServiceHttpToTlsRedirect = bR . ReadBoolean ( ) ;
_webServiceTlsCertificatePath = bR . ReadShortString ( ) ;
_webServiceTlsCertificatePassword = bR . ReadShortString ( ) ;
if ( _webServiceTlsCertificatePath . Length = = 0 )
_webServiceTlsCertificatePath = null ;
if ( _webServiceTlsCertificatePath ! = null )
{
2023-08-12 13:13:22 +05:30
string webServiceTlsCertificatePath = ConvertToAbsolutePath ( _webServiceTlsCertificatePath ) ;
2022-09-18 18:04:28 +05:30
try
{
2023-08-12 13:13:22 +05:30
LoadWebServiceTlsCertificate ( webServiceTlsCertificatePath , _webServiceTlsCertificatePassword ) ;
2022-09-18 18:04:28 +05:30
}
catch ( Exception ex )
{
2023-08-12 13:13:22 +05:30
_log . Write ( "DNS Server encountered an error while loading Web Service TLS certificate: " + webServiceTlsCertificatePath + "\r\n" + ex . ToString ( ) ) ;
2022-09-18 18:04:28 +05:30
}
StartTlsCertificateUpdateTimer ( ) ;
}
}
else
{
_webServiceLocalAddresses = new IPAddress [ ] { IPAddress . Any , IPAddress . IPv6Any } ;
_webServiceTlsPort = 53443 ;
_webServiceEnableTls = false ;
_webServiceHttpToTlsRedirect = false ;
_webServiceTlsCertificatePath = string . Empty ;
_webServiceTlsCertificatePassword = string . Empty ;
}
_dnsServer . PreferIPv6 = bR . ReadBoolean ( ) ;
if ( bR . ReadBoolean ( ) ) //logQueries
_dnsServer . QueryLogManager = _log ;
if ( version > = 14 )
2024-10-26 17:31:28 +05:30
{
int maxStatFileDays = bR . ReadInt32 ( ) ;
if ( maxStatFileDays < 0 )
maxStatFileDays = 0 ;
_dnsServer . StatsManager . MaxStatFileDays = maxStatFileDays ;
}
2022-09-18 18:04:28 +05:30
else
2024-10-26 17:31:28 +05:30
{
2022-09-18 18:04:28 +05:30
_dnsServer . StatsManager . MaxStatFileDays = 0 ;
2024-10-26 17:31:28 +05:30
}
2022-09-18 18:04:28 +05:30
if ( version > = 17 )
{
_dnsServer . Recursion = ( DnsServerRecursion ) bR . ReadByte ( ) ;
2024-09-14 19:19:59 +05:30
NetworkAddress [ ] recursionDeniedNetworks = null ;
2022-09-18 18:04:28 +05:30
{
int count = bR . ReadByte ( ) ;
if ( count > 0 )
{
NetworkAddress [ ] networks = new NetworkAddress [ count ] ;
for ( int i = 0 ; i < count ; i + + )
networks [ i ] = NetworkAddress . ReadFrom ( bR ) ;
2024-09-14 19:19:59 +05:30
recursionDeniedNetworks = networks ;
2022-09-18 18:04:28 +05:30
}
2023-08-12 13:13:22 +05:30
else
{
2024-09-14 19:19:59 +05:30
recursionDeniedNetworks = null ;
2023-08-12 13:13:22 +05:30
}
2022-09-18 18:04:28 +05:30
}
2024-09-14 19:19:59 +05:30
NetworkAddress [ ] recursionAllowedNetworks = null ;
2022-09-18 18:04:28 +05:30
{
int count = bR . ReadByte ( ) ;
if ( count > 0 )
{
NetworkAddress [ ] networks = new NetworkAddress [ count ] ;
for ( int i = 0 ; i < count ; i + + )
networks [ i ] = NetworkAddress . ReadFrom ( bR ) ;
2024-09-14 19:19:59 +05:30
recursionAllowedNetworks = networks ;
2022-09-18 18:04:28 +05:30
}
2023-08-12 13:13:22 +05:30
else
{
2024-09-14 19:19:59 +05:30
recursionAllowedNetworks = null ;
2023-08-12 13:13:22 +05:30
}
2022-09-18 18:04:28 +05:30
}
2024-09-14 19:19:59 +05:30
_dnsServer . RecursionNetworkACL = AuthZoneInfo . ConvertDenyAllowToACL ( recursionDeniedNetworks , recursionAllowedNetworks ) ;
2022-09-18 18:04:28 +05:30
}
else
{
bool allowRecursion = bR . ReadBoolean ( ) ;
bool allowRecursionOnlyForPrivateNetworks ;
if ( version > = 4 )
allowRecursionOnlyForPrivateNetworks = bR . ReadBoolean ( ) ;
else
allowRecursionOnlyForPrivateNetworks = true ; //default true for security reasons
if ( allowRecursion )
{
if ( allowRecursionOnlyForPrivateNetworks )
_dnsServer . Recursion = DnsServerRecursion . AllowOnlyForPrivateNetworks ;
else
_dnsServer . Recursion = DnsServerRecursion . Allow ;
}
else
{
_dnsServer . Recursion = DnsServerRecursion . Deny ;
}
}
if ( version > = 12 )
_dnsServer . RandomizeName = bR . ReadBoolean ( ) ;
else
2024-09-14 19:19:59 +05:30
_dnsServer . RandomizeName = false ; //default false to allow resolving from bad name servers
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 15 )
_dnsServer . QnameMinimization = bR . ReadBoolean ( ) ;
else
_dnsServer . QnameMinimization = true ; //default true to enable privacy feature
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 20 )
{
_dnsServer . QpmLimitRequests = bR . ReadInt32 ( ) ;
_dnsServer . QpmLimitErrors = bR . ReadInt32 ( ) ;
_dnsServer . QpmLimitSampleMinutes = bR . ReadInt32 ( ) ;
_dnsServer . QpmLimitIPv4PrefixLength = bR . ReadInt32 ( ) ;
_dnsServer . QpmLimitIPv6PrefixLength = bR . ReadInt32 ( ) ;
}
else if ( version > = 17 )
{
_dnsServer . QpmLimitRequests = bR . ReadInt32 ( ) ;
_dnsServer . QpmLimitSampleMinutes = bR . ReadInt32 ( ) ;
_ = bR . ReadInt32 ( ) ; //read obsolete value _dnsServer.QpmLimitSamplingIntervalInMinutes
}
else
{
_dnsServer . QpmLimitRequests = 0 ;
_dnsServer . QpmLimitErrors = 0 ;
_dnsServer . QpmLimitSampleMinutes = 1 ;
_dnsServer . QpmLimitIPv4PrefixLength = 24 ;
_dnsServer . QpmLimitIPv6PrefixLength = 56 ;
}
2020-06-06 16:52:36 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 13 )
{
_dnsServer . ServeStale = bR . ReadBoolean ( ) ;
_dnsServer . CacheZoneManager . ServeStaleTtl = bR . ReadUInt32 ( ) ;
}
else
{
_dnsServer . ServeStale = true ;
_dnsServer . CacheZoneManager . ServeStaleTtl = CacheZoneManager . SERVE_STALE_TTL ;
}
2020-06-06 16:52:36 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 9 )
{
_dnsServer . CachePrefetchEligibility = bR . ReadInt32 ( ) ;
_dnsServer . CachePrefetchTrigger = bR . ReadInt32 ( ) ;
_dnsServer . CachePrefetchSampleIntervalInMinutes = bR . ReadInt32 ( ) ;
_dnsServer . CachePrefetchSampleEligibilityHitsPerHour = bR . ReadInt32 ( ) ;
}
else
{
_dnsServer . CachePrefetchEligibility = 2 ;
_dnsServer . CachePrefetchTrigger = 9 ;
_dnsServer . CachePrefetchSampleIntervalInMinutes = 5 ;
_dnsServer . CachePrefetchSampleEligibilityHitsPerHour = 30 ;
}
2020-06-06 16:52:36 +05:30
2022-09-18 18:04:28 +05:30
NetProxyType proxyType = ( NetProxyType ) bR . ReadByte ( ) ;
if ( proxyType ! = NetProxyType . None )
{
string address = bR . ReadShortString ( ) ;
int port = bR . ReadInt32 ( ) ;
NetworkCredential credential = null ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
if ( bR . ReadBoolean ( ) ) //credential set
credential = new NetworkCredential ( bR . ReadShortString ( ) , bR . ReadShortString ( ) ) ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
_dnsServer . Proxy = NetProxy . CreateProxy ( proxyType , address , port , credential ) ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 10 )
{
int count = bR . ReadByte ( ) ;
List < NetProxyBypassItem > bypassList = new List < NetProxyBypassItem > ( count ) ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
for ( int i = 0 ; i < count ; i + + )
bypassList . Add ( new NetProxyBypassItem ( bR . ReadShortString ( ) ) ) ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
_dnsServer . Proxy . BypassList = bypassList ;
}
else
{
_dnsServer . Proxy . BypassList = null ;
}
}
else
{
_dnsServer . Proxy = null ;
}
2021-06-19 14:33:40 +05:30
2022-09-18 18:04:28 +05:30
{
int count = bR . ReadByte ( ) ;
if ( count > 0 )
{
NameServerAddress [ ] forwarders = new NameServerAddress [ count ] ;
2021-08-14 11:50:33 +05:30
2022-09-18 18:04:28 +05:30
for ( int i = 0 ; i < count ; i + + )
2022-12-24 12:57:53 +05:30
{
2022-09-18 18:04:28 +05:30
forwarders [ i ] = new NameServerAddress ( bR ) ;
2022-12-24 12:57:53 +05:30
if ( forwarders [ i ] . Protocol = = DnsTransportProtocol . HttpsJson )
forwarders [ i ] = forwarders [ i ] . ChangeProtocol ( DnsTransportProtocol . Https ) ;
}
2021-08-14 11:50:33 +05:30
2022-09-18 18:04:28 +05:30
_dnsServer . Forwarders = forwarders ;
}
2023-08-12 13:13:22 +05:30
else
{
_dnsServer . Forwarders = null ;
}
2022-09-18 18:04:28 +05:30
}
2021-08-14 11:50:33 +05:30
2022-09-18 18:04:28 +05:30
if ( version < = 10 )
{
DnsTransportProtocol forwarderProtocol = ( DnsTransportProtocol ) bR . ReadByte ( ) ;
2022-12-24 12:57:53 +05:30
if ( forwarderProtocol = = DnsTransportProtocol . HttpsJson )
forwarderProtocol = DnsTransportProtocol . Https ;
2021-08-07 12:49:57 +05:30
2022-09-18 18:04:28 +05:30
if ( _dnsServer . Forwarders ! = null )
{
List < NameServerAddress > forwarders = new List < NameServerAddress > ( ) ;
2021-08-07 12:49:57 +05:30
2022-09-18 18:04:28 +05:30
foreach ( NameServerAddress forwarder in _dnsServer . Forwarders )
{
if ( forwarder . Protocol = = forwarderProtocol )
forwarders . Add ( forwarder ) ;
else
forwarders . Add ( forwarder . ChangeProtocol ( forwarderProtocol ) ) ;
}
2021-08-07 12:49:57 +05:30
2022-09-18 18:04:28 +05:30
_dnsServer . Forwarders = forwarders ;
}
}
2021-08-07 12:49:57 +05:30
2022-09-18 18:04:28 +05:30
{
int count = bR . ReadByte ( ) ;
if ( count > 0 )
{
if ( version > 2 )
{
for ( int i = 0 ; i < count ; i + + )
{
string username = bR . ReadShortString ( ) ;
string passwordHash = bR . ReadShortString ( ) ;
2021-08-21 12:20:24 +05:30
2022-09-18 18:04:28 +05:30
if ( username . Equals ( "admin" , StringComparison . OrdinalIgnoreCase ) )
2021-09-25 13:50:27 +05:30
{
2022-09-18 18:04:28 +05:30
_authManager . LoadOldConfig ( passwordHash , true ) ;
break ;
2021-09-25 13:50:27 +05:30
}
2022-09-18 18:04:28 +05:30
}
}
else
{
for ( int i = 0 ; i < count ; i + + )
{
string username = bR . ReadShortString ( ) ;
string password = bR . ReadShortString ( ) ;
2021-09-25 13:50:27 +05:30
2022-09-18 18:04:28 +05:30
if ( username . Equals ( "admin" , StringComparison . OrdinalIgnoreCase ) )
2021-10-16 15:04:06 +05:30
{
2022-09-18 18:04:28 +05:30
_authManager . LoadOldConfig ( password , false ) ;
break ;
2021-10-16 15:04:06 +05:30
}
2022-09-18 18:04:28 +05:30
}
}
}
}
2021-10-16 15:04:06 +05:30
2022-09-18 18:04:28 +05:30
if ( version < = 6 )
{
int count = bR . ReadInt32 ( ) ;
_configDisabledZones = new List < string > ( count ) ;
2021-10-30 12:22:26 +05:30
2022-09-18 18:04:28 +05:30
for ( int i = 0 ; i < count ; i + + )
{
string domain = bR . ReadShortString ( ) ;
_configDisabledZones . Add ( domain ) ;
}
}
2022-03-12 15:49:42 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 18 )
_dnsServer . EnableBlocking = bR . ReadBoolean ( ) ;
else
_dnsServer . EnableBlocking = true ;
2022-03-12 15:49:42 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 18 )
_dnsServer . BlockingType = ( DnsServerBlockingType ) bR . ReadByte ( ) ;
else if ( version > = 16 )
_dnsServer . BlockingType = bR . ReadBoolean ( ) ? DnsServerBlockingType . NxDomain : DnsServerBlockingType . AnyAddress ;
else
_dnsServer . BlockingType = DnsServerBlockingType . AnyAddress ;
2022-03-12 15:49:42 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 18 )
{
//read custom blocking addresses
int count = bR . ReadByte ( ) ;
if ( count > 0 )
{
List < DnsARecordData > dnsARecords = new List < DnsARecordData > ( ) ;
List < DnsAAAARecordData > dnsAAAARecords = new List < DnsAAAARecordData > ( ) ;
2022-03-12 15:49:42 +05:30
2022-09-18 18:04:28 +05:30
for ( int i = 0 ; i < count ; i + + )
{
2023-02-05 16:32:28 +05:30
IPAddress customAddress = IPAddressExtensions . ReadFrom ( bR ) ;
2022-03-12 15:49:42 +05:30
2022-09-18 18:04:28 +05:30
switch ( customAddress . AddressFamily )
{
case AddressFamily . InterNetwork :
dnsARecords . Add ( new DnsARecordData ( customAddress ) ) ;
break ;
2022-03-12 15:49:42 +05:30
2022-09-18 18:04:28 +05:30
case AddressFamily . InterNetworkV6 :
dnsAAAARecords . Add ( new DnsAAAARecordData ( customAddress ) ) ;
break ;
}
}
2022-01-23 18:07:18 +05:30
2022-09-18 18:04:28 +05:30
_dnsServer . CustomBlockingARecords = dnsARecords ;
_dnsServer . CustomBlockingAAAARecords = dnsAAAARecords ;
}
2023-08-12 13:13:22 +05:30
else
{
_dnsServer . CustomBlockingARecords = null ;
_dnsServer . CustomBlockingAAAARecords = null ;
}
2022-09-18 18:04:28 +05:30
}
else
{
_dnsServer . CustomBlockingARecords = null ;
_dnsServer . CustomBlockingAAAARecords = null ;
}
2022-04-23 18:00:12 +05:30
2022-09-18 18:04:28 +05:30
if ( version > 4 )
{
//read block list urls
int count = bR . ReadByte ( ) ;
2019-06-15 13:30:03 +05:30
2023-08-12 13:13:22 +05:30
_dnsServer . BlockListZoneManager . AllowListUrls . Clear ( ) ;
_dnsServer . BlockListZoneManager . BlockListUrls . Clear ( ) ;
2022-09-18 18:04:28 +05:30
for ( int i = 0 ; i < count ; i + + )
{
string listUrl = bR . ReadShortString ( ) ;
2023-02-25 13:12:06 +05:30
if ( listUrl . StartsWith ( '!' ) )
2022-09-18 18:04:28 +05:30
_dnsServer . BlockListZoneManager . AllowListUrls . Add ( new Uri ( listUrl . Substring ( 1 ) ) ) ;
else
_dnsServer . BlockListZoneManager . BlockListUrls . Add ( new Uri ( listUrl ) ) ;
2019-06-15 13:30:03 +05:30
}
2022-12-24 17:14:51 +05:30
_settingsApi . BlockListLastUpdatedOn = bR . ReadDateTime ( ) ;
2022-09-18 18:04:28 +05:30
if ( version > = 13 )
2022-12-24 17:14:51 +05:30
_settingsApi . BlockListUpdateIntervalHours = bR . ReadInt32 ( ) ;
2022-09-18 18:04:28 +05:30
}
else
{
_dnsServer . BlockListZoneManager . AllowListUrls . Clear ( ) ;
_dnsServer . BlockListZoneManager . BlockListUrls . Clear ( ) ;
2022-12-24 17:14:51 +05:30
_settingsApi . BlockListLastUpdatedOn = DateTime . MinValue ;
_settingsApi . BlockListUpdateIntervalHours = 24 ;
2022-09-18 18:04:28 +05:30
}
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 11 )
{
int count = bR . ReadByte ( ) ;
if ( count > 0 )
2019-06-15 13:30:03 +05:30
{
2022-09-18 18:04:28 +05:30
IPEndPoint [ ] localEndPoints = new IPEndPoint [ count ] ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
for ( int i = 0 ; i < count ; i + + )
2023-02-05 16:32:28 +05:30
localEndPoints [ i ] = ( IPEndPoint ) EndPointExtensions . ReadFrom ( bR ) ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
_dnsServer . LocalEndPoints = localEndPoints ;
2019-06-15 13:30:03 +05:30
}
2023-08-12 13:13:22 +05:30
else
{
_dnsServer . LocalEndPoints = new IPEndPoint [ ] { new IPEndPoint ( IPAddress . Any , 53 ) , new IPEndPoint ( IPAddress . IPv6Any , 53 ) } ;
}
2022-09-18 18:04:28 +05:30
}
else if ( version > = 6 )
{
int count = bR . ReadByte ( ) ;
if ( count > 0 )
{
IPEndPoint [ ] localEndPoints = new IPEndPoint [ count ] ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
for ( int i = 0 ; i < count ; i + + )
2023-02-05 16:32:28 +05:30
localEndPoints [ i ] = new IPEndPoint ( IPAddressExtensions . ReadFrom ( bR ) , 53 ) ;
2022-09-18 18:04:28 +05:30
_dnsServer . LocalEndPoints = localEndPoints ;
}
2023-08-12 13:13:22 +05:30
else
{
_dnsServer . LocalEndPoints = new IPEndPoint [ ] { new IPEndPoint ( IPAddress . Any , 53 ) , new IPEndPoint ( IPAddress . IPv6Any , 53 ) } ;
}
2019-06-15 13:30:03 +05:30
}
2022-09-18 18:04:28 +05:30
else
2019-06-15 13:30:03 +05:30
{
2022-09-18 18:04:28 +05:30
_dnsServer . LocalEndPoints = new IPEndPoint [ ] { new IPEndPoint ( IPAddress . Any , 53 ) , new IPEndPoint ( IPAddress . IPv6Any , 53 ) } ;
}
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 8 )
{
_dnsServer . EnableDnsOverHttp = bR . ReadBoolean ( ) ;
_dnsServer . EnableDnsOverTls = bR . ReadBoolean ( ) ;
_dnsServer . EnableDnsOverHttps = bR . ReadBoolean ( ) ;
_dnsTlsCertificatePath = bR . ReadShortString ( ) ;
_dnsTlsCertificatePassword = bR . ReadShortString ( ) ;
2021-09-25 14:55:16 +05:30
2022-09-18 18:04:28 +05:30
if ( _dnsTlsCertificatePath . Length = = 0 )
_dnsTlsCertificatePath = null ;
2021-10-16 16:14:28 +05:30
2022-09-18 18:04:28 +05:30
if ( _dnsTlsCertificatePath ! = null )
2021-09-25 14:55:16 +05:30
{
2023-08-12 13:13:22 +05:30
string dnsTlsCertificatePath = ConvertToAbsolutePath ( _dnsTlsCertificatePath ) ;
2021-09-25 14:55:16 +05:30
try
{
2023-08-12 13:13:22 +05:30
LoadDnsTlsCertificate ( dnsTlsCertificatePath , _dnsTlsCertificatePassword ) ;
2021-09-25 14:55:16 +05:30
}
catch ( Exception ex )
{
2023-08-12 13:13:22 +05:30
_log . Write ( "DNS Server encountered an error while loading DNS Server TLS certificate: " + dnsTlsCertificatePath + "\r\n" + ex . ToString ( ) ) ;
2021-09-25 14:55:16 +05:30
}
2022-09-18 18:04:28 +05:30
StartTlsCertificateUpdateTimer ( ) ;
}
}
else
{
_dnsServer . EnableDnsOverHttp = false ;
_dnsServer . EnableDnsOverTls = false ;
_dnsServer . EnableDnsOverHttps = false ;
_dnsTlsCertificatePath = string . Empty ;
_dnsTlsCertificatePassword = string . Empty ;
}
2021-10-16 15:29:37 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 19 )
{
_dnsServer . CacheZoneManager . MinimumRecordTtl = bR . ReadUInt32 ( ) ;
_dnsServer . CacheZoneManager . MaximumRecordTtl = bR . ReadUInt32 ( ) ;
_dnsServer . CacheZoneManager . NegativeRecordTtl = bR . ReadUInt32 ( ) ;
_dnsServer . CacheZoneManager . FailureRecordTtl = bR . ReadUInt32 ( ) ;
}
else
{
_dnsServer . CacheZoneManager . MinimumRecordTtl = CacheZoneManager . MINIMUM_RECORD_TTL ;
_dnsServer . CacheZoneManager . MaximumRecordTtl = CacheZoneManager . MAXIMUM_RECORD_TTL ;
_dnsServer . CacheZoneManager . NegativeRecordTtl = CacheZoneManager . NEGATIVE_RECORD_TTL ;
_dnsServer . CacheZoneManager . FailureRecordTtl = CacheZoneManager . FAILURE_RECORD_TTL ;
}
2021-09-26 17:12:00 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 21 )
{
int count = bR . ReadByte ( ) ;
Dictionary < string , TsigKey > tsigKeys = new Dictionary < string , TsigKey > ( count ) ;
2021-10-16 15:29:37 +05:30
2022-09-18 18:04:28 +05:30
for ( int i = 0 ; i < count ; i + + )
2021-10-16 15:29:37 +05:30
{
2022-09-18 18:04:28 +05:30
string keyName = bR . ReadShortString ( ) ;
string sharedSecret = bR . ReadShortString ( ) ;
TsigAlgorithm algorithm = ( TsigAlgorithm ) bR . ReadByte ( ) ;
2021-10-16 15:29:37 +05:30
2022-09-18 18:04:28 +05:30
tsigKeys . Add ( keyName , new TsigKey ( keyName , sharedSecret , algorithm ) ) ;
2021-10-16 15:29:37 +05:30
}
2022-09-18 18:04:28 +05:30
_dnsServer . TsigKeys = tsigKeys ;
}
else if ( version > = 20 )
{
int count = bR . ReadByte ( ) ;
Dictionary < string , TsigKey > tsigKeys = new Dictionary < string , TsigKey > ( count ) ;
2021-10-16 15:29:37 +05:30
2022-09-18 18:04:28 +05:30
for ( int i = 0 ; i < count ; i + + )
{
string keyName = bR . ReadShortString ( ) ;
string sharedSecret = bR . ReadShortString ( ) ;
2021-10-16 15:29:37 +05:30
2022-09-18 18:04:28 +05:30
tsigKeys . Add ( keyName , new TsigKey ( keyName , sharedSecret , TsigAlgorithm . HMAC_SHA256 ) ) ;
2021-10-16 15:29:37 +05:30
}
2022-09-18 18:04:28 +05:30
_dnsServer . TsigKeys = tsigKeys ;
}
else
{
_dnsServer . TsigKeys = null ;
}
2021-10-16 15:29:37 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 22 )
2025-03-29 19:12:54 +05:30
_ = bR . ReadBoolean ( ) ; //removed NsRevalidation option
2021-10-16 15:29:37 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 23 )
{
_dnsServer . AllowTxtBlockingReport = bR . ReadBoolean ( ) ;
_zonesApi . DefaultRecordTtl = bR . ReadUInt32 ( ) ;
}
else
{
_dnsServer . AllowTxtBlockingReport = true ;
_zonesApi . DefaultRecordTtl = 3600 ;
}
2021-09-25 14:55:16 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 24 )
{
_webServiceUseSelfSignedTlsCertificate = bR . ReadBoolean ( ) ;
2021-09-25 14:55:16 +05:30
2022-09-18 18:04:28 +05:30
SelfSignedCertCheck ( false , false ) ;
}
else
{
_webServiceUseSelfSignedTlsCertificate = false ;
}
2021-09-25 14:55:16 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 25 )
_dnsServer . UdpPayloadSize = bR . ReadUInt16 ( ) ;
else
_dnsServer . UdpPayloadSize = DnsDatagram . EDNS_DEFAULT_UDP_PAYLOAD_SIZE ;
2021-09-25 14:55:16 +05:30
2022-09-18 18:04:28 +05:30
if ( version > = 26 )
{
_dnsServer . DnssecValidation = bR . ReadBoolean ( ) ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
_dnsServer . ResolverRetries = bR . ReadInt32 ( ) ;
_dnsServer . ResolverTimeout = bR . ReadInt32 ( ) ;
_dnsServer . ResolverMaxStackCount = bR . ReadInt32 ( ) ;
2022-04-09 17:40:27 +05:30
2022-09-18 18:04:28 +05:30
_dnsServer . ForwarderRetries = bR . ReadInt32 ( ) ;
_dnsServer . ForwarderTimeout = bR . ReadInt32 ( ) ;
_dnsServer . ForwarderConcurrency = bR . ReadInt32 ( ) ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
_dnsServer . ClientTimeout = bR . ReadInt32 ( ) ;
2024-02-04 18:01:49 +05:30
if ( _dnsServer . ClientTimeout = = 4000 )
_dnsServer . ClientTimeout = 2000 ;
2022-09-18 18:04:28 +05:30
_dnsServer . TcpSendTimeout = bR . ReadInt32 ( ) ;
_dnsServer . TcpReceiveTimeout = bR . ReadInt32 ( ) ;
}
else
{
2022-03-26 12:09:49 +05:30
_dnsServer . DnssecValidation = true ;
CreateForwarderZoneToDisableDnssecForNTP ( ) ;
2022-09-18 18:04:28 +05:30
_dnsServer . ResolverRetries = 2 ;
2024-02-04 18:01:49 +05:30
_dnsServer . ResolverTimeout = 1500 ;
2022-09-18 18:04:28 +05:30
_dnsServer . ResolverMaxStackCount = 16 ;
2022-05-28 12:26:48 +05:30
2022-09-18 18:04:28 +05:30
_dnsServer . ForwarderRetries = 3 ;
_dnsServer . ForwarderTimeout = 2000 ;
_dnsServer . ForwarderConcurrency = 2 ;
2019-06-15 13:30:03 +05:30
2024-02-04 18:01:49 +05:30
_dnsServer . ClientTimeout = 2000 ;
2022-09-18 18:04:28 +05:30
_dnsServer . TcpSendTimeout = 10000 ;
_dnsServer . TcpReceiveTimeout = 10000 ;
2022-03-26 12:09:49 +05:30
}
2022-09-18 18:04:28 +05:30
if ( version > = 27 )
_dnsServer . CacheZoneManager . MaximumEntries = bR . ReadInt32 ( ) ;
else
_dnsServer . CacheZoneManager . MaximumEntries = 10000 ;
2022-03-26 12:09:49 +05:30
}
2022-09-18 18:04:28 +05:30
private void WriteConfigTo ( BinaryWriter bW )
2019-06-15 13:30:03 +05:30
{
2022-09-18 18:04:28 +05:30
bW . Write ( Encoding . ASCII . GetBytes ( "DS" ) ) ; //format
2025-03-29 19:12:54 +05:30
bW . Write ( ( byte ) 41 ) ; //version
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
//web service
2019-06-15 13:30:03 +05:30
{
2020-12-25 19:27:36 +05:30
bW . Write ( _webServiceHttpPort ) ;
2022-09-18 18:04:28 +05:30
bW . Write ( _webServiceTlsPort ) ;
2020-12-25 19:27:36 +05:30
{
bW . Write ( Convert . ToByte ( _webServiceLocalAddresses . Count ) ) ;
foreach ( IPAddress localAddress in _webServiceLocalAddresses )
localAddress . WriteTo ( bW ) ;
}
bW . Write ( _webServiceEnableTls ) ;
2023-10-29 19:16:36 +05:30
bW . Write ( _webServiceEnableHttp3 ) ;
2020-12-25 19:27:36 +05:30
bW . Write ( _webServiceHttpToTlsRedirect ) ;
2022-09-18 18:04:28 +05:30
bW . Write ( _webServiceUseSelfSignedTlsCertificate ) ;
2020-12-25 19:27:36 +05:30
2022-09-18 18:04:28 +05:30
if ( _webServiceTlsCertificatePath is null )
2020-12-25 19:27:36 +05:30
bW . WriteShortString ( string . Empty ) ;
else
bW . WriteShortString ( _webServiceTlsCertificatePath ) ;
2022-09-18 18:04:28 +05:30
if ( _webServiceTlsCertificatePassword is null )
2020-12-25 19:27:36 +05:30
bW . WriteShortString ( string . Empty ) ;
else
bW . WriteShortString ( _webServiceTlsCertificatePassword ) ;
2024-10-19 17:01:05 +05:30
bW . WriteShortString ( _webServiceRealIpHeader ) ;
2022-09-18 18:04:28 +05:30
}
//dns
{
//general
bW . WriteShortString ( _dnsServer . ServerDomain ) ;
{
bW . Write ( Convert . ToByte ( _dnsServer . LocalEndPoints . Count ) ) ;
foreach ( IPEndPoint localEP in _dnsServer . LocalEndPoints )
localEP . WriteTo ( bW ) ;
}
2024-09-14 19:19:59 +05:30
AuthZoneInfo . WriteNetworkAddressesTo ( DnsClientConnection . IPv4SourceAddresses , bW ) ;
AuthZoneInfo . WriteNetworkAddressesTo ( DnsClientConnection . IPv6SourceAddresses , bW ) ;
2024-02-04 18:01:49 +05:30
2022-09-18 18:04:28 +05:30
bW . Write ( _zonesApi . DefaultRecordTtl ) ;
2024-05-19 16:08:35 +05:30
if ( _dnsServer . ResponsiblePersonInternal is null )
bW . WriteShortString ( "" ) ;
else
bW . WriteShortString ( _dnsServer . ResponsiblePersonInternal . Address ) ;
2023-10-29 19:16:36 +05:30
bW . Write ( _dnsServer . AuthZoneManager . UseSoaSerialDateScheme ) ;
2024-12-21 15:49:16 +05:30
bW . Write ( _dnsServer . AuthZoneManager . MinSoaRefresh ) ;
bW . Write ( _dnsServer . AuthZoneManager . MinSoaRetry ) ;
2023-10-29 19:16:36 +05:30
2024-09-14 19:19:59 +05:30
AuthZoneInfo . WriteNetworkAddressesTo ( _dnsServer . ZoneTransferAllowedNetworks , bW ) ;
AuthZoneInfo . WriteNetworkAddressesTo ( _dnsServer . NotifyAllowedNetworks , bW ) ;
2023-10-29 19:16:36 +05:30
2022-09-18 18:04:28 +05:30
bW . Write ( _appsApi . EnableAutomaticUpdate ) ;
2019-06-15 13:30:03 +05:30
bW . Write ( _dnsServer . PreferIPv6 ) ;
2022-09-18 18:04:28 +05:30
bW . Write ( _dnsServer . UdpPayloadSize ) ;
bW . Write ( _dnsServer . DnssecValidation ) ;
2020-10-04 21:07:13 +05:30
2022-11-20 16:30:03 +05:30
bW . Write ( _dnsServer . EDnsClientSubnet ) ;
bW . Write ( _dnsServer . EDnsClientSubnetIPv4PrefixLength ) ;
bW . Write ( _dnsServer . EDnsClientSubnetIPv6PrefixLength ) ;
2024-03-16 15:50:11 +05:30
if ( _dnsServer . EDnsClientSubnetIpv4Override is null )
{
bW . Write ( false ) ;
}
else
{
bW . Write ( true ) ;
_dnsServer . EDnsClientSubnetIpv4Override . WriteTo ( bW ) ;
}
if ( _dnsServer . EDnsClientSubnetIpv6Override is null )
{
bW . Write ( false ) ;
}
else
{
bW . Write ( true ) ;
_dnsServer . EDnsClientSubnetIpv6Override . WriteTo ( bW ) ;
}
2022-09-18 18:04:28 +05:30
bW . Write ( _dnsServer . QpmLimitRequests ) ;
bW . Write ( _dnsServer . QpmLimitErrors ) ;
bW . Write ( _dnsServer . QpmLimitSampleMinutes ) ;
bW . Write ( _dnsServer . QpmLimitIPv4PrefixLength ) ;
bW . Write ( _dnsServer . QpmLimitIPv6PrefixLength ) ;
2024-09-14 19:19:59 +05:30
AuthZoneInfo . WriteNetworkAddressesTo ( _dnsServer . QpmLimitBypassList , bW ) ;
2024-02-04 18:01:49 +05:30
2022-09-18 18:04:28 +05:30
bW . Write ( _dnsServer . ClientTimeout ) ;
bW . Write ( _dnsServer . TcpSendTimeout ) ;
bW . Write ( _dnsServer . TcpReceiveTimeout ) ;
2023-01-14 14:59:50 +05:30
bW . Write ( _dnsServer . QuicIdleTimeout ) ;
bW . Write ( _dnsServer . QuicMaxInboundStreams ) ;
bW . Write ( _dnsServer . ListenBacklog ) ;
2024-12-21 15:49:16 +05:30
bW . Write ( _dnsServer . MaxConcurrentResolutionsPerCore ) ;
2022-09-18 18:04:28 +05:30
//optional protocols
2023-08-12 13:13:22 +05:30
bW . Write ( _dnsServer . EnableDnsOverUdpProxy ) ;
bW . Write ( _dnsServer . EnableDnsOverTcpProxy ) ;
2022-09-18 18:04:28 +05:30
bW . Write ( _dnsServer . EnableDnsOverHttp ) ;
bW . Write ( _dnsServer . EnableDnsOverTls ) ;
bW . Write ( _dnsServer . EnableDnsOverHttps ) ;
2024-09-14 19:19:59 +05:30
bW . Write ( _dnsServer . EnableDnsOverHttp3 ) ;
2023-01-14 14:59:50 +05:30
bW . Write ( _dnsServer . EnableDnsOverQuic ) ;
2023-08-12 13:13:22 +05:30
bW . Write ( _dnsServer . DnsOverUdpProxyPort ) ;
bW . Write ( _dnsServer . DnsOverTcpProxyPort ) ;
2023-01-14 14:59:50 +05:30
bW . Write ( _dnsServer . DnsOverHttpPort ) ;
bW . Write ( _dnsServer . DnsOverTlsPort ) ;
bW . Write ( _dnsServer . DnsOverHttpsPort ) ;
bW . Write ( _dnsServer . DnsOverQuicPort ) ;
2022-09-18 18:04:28 +05:30
2024-11-16 13:43:33 +05:30
AuthZoneInfo . WriteNetworkACLTo ( _dnsServer . ReverseProxyNetworkACL , bW ) ;
2022-09-18 18:04:28 +05:30
if ( _dnsTlsCertificatePath = = null )
bW . WriteShortString ( string . Empty ) ;
else
bW . WriteShortString ( _dnsTlsCertificatePath ) ;
if ( _dnsTlsCertificatePassword = = null )
bW . WriteShortString ( string . Empty ) ;
else
bW . WriteShortString ( _dnsTlsCertificatePassword ) ;
2024-10-19 17:01:05 +05:30
bW . WriteShortString ( _dnsServer . DnsOverHttpRealIpHeader ) ;
2022-09-18 18:04:28 +05:30
//tsig
if ( _dnsServer . TsigKeys is null )
{
bW . Write ( ( byte ) 0 ) ;
}
else
{
bW . Write ( Convert . ToByte ( _dnsServer . TsigKeys . Count ) ) ;
foreach ( KeyValuePair < string , TsigKey > tsigKey in _dnsServer . TsigKeys )
{
bW . WriteShortString ( tsigKey . Key ) ;
bW . WriteShortString ( tsigKey . Value . SharedSecret ) ;
bW . Write ( ( byte ) tsigKey . Value . Algorithm ) ;
}
}
2020-10-04 21:07:13 +05:30
2022-09-18 18:04:28 +05:30
//recursion
2021-05-16 17:11:04 +05:30
bW . Write ( ( byte ) _dnsServer . Recursion ) ;
2024-09-14 19:19:59 +05:30
AuthZoneInfo . WriteNetworkACLTo ( _dnsServer . RecursionNetworkACL , bW ) ;
2021-05-16 17:11:04 +05:30
2020-10-04 21:07:13 +05:30
bW . Write ( _dnsServer . RandomizeName ) ;
2021-02-27 19:18:08 +05:30
bW . Write ( _dnsServer . QnameMinimization ) ;
2019-06-15 13:30:03 +05:30
2022-09-18 18:04:28 +05:30
bW . Write ( _dnsServer . ResolverRetries ) ;
bW . Write ( _dnsServer . ResolverTimeout ) ;
2024-09-14 19:19:59 +05:30
bW . Write ( _dnsServer . ResolverConcurrency ) ;
2022-09-18 18:04:28 +05:30
bW . Write ( _dnsServer . ResolverMaxStackCount ) ;
2021-05-23 18:35:35 +05:30
2022-09-18 18:04:28 +05:30
//cache
2023-01-14 14:59:50 +05:30
bW . Write ( _saveCache ) ;
2020-12-19 13:32:02 +05:30
bW . Write ( _dnsServer . ServeStale ) ;
bW . Write ( _dnsServer . CacheZoneManager . ServeStaleTtl ) ;
2024-05-19 16:08:35 +05:30
bW . Write ( _dnsServer . CacheZoneManager . ServeStaleAnswerTtl ) ;
bW . Write ( _dnsServer . CacheZoneManager . ServeStaleResetTtl ) ;
bW . Write ( _dnsServer . ServeStaleMaxWaitTime ) ;
2020-12-19 13:32:02 +05:30
2022-09-18 18:04:28 +05:30
bW . Write ( _dnsServer . CacheZoneManager . MaximumEntries ) ;
bW . Write ( _dnsServer . CacheZoneManager . MinimumRecordTtl ) ;
bW . Write ( _dnsServer . CacheZoneManager . MaximumRecordTtl ) ;
bW . Write ( _dnsServer . CacheZoneManager . NegativeRecordTtl ) ;
bW . Write ( _dnsServer . CacheZoneManager . FailureRecordTtl ) ;
2019-06-15 13:30:03 +05:30
bW . Write ( _dnsServer . CachePrefetchEligibility ) ;
bW . Write ( _dnsServer . CachePrefetchTrigger ) ;
bW . Write ( _dnsServer . CachePrefetchSampleIntervalInMinutes ) ;
bW . Write ( _dnsServer . CachePrefetchSampleEligibilityHitsPerHour ) ;
2022-09-18 18:04:28 +05:30
//blocking
bW . Write ( _dnsServer . EnableBlocking ) ;
bW . Write ( _dnsServer . AllowTxtBlockingReport ) ;
2024-09-14 19:19:59 +05:30
AuthZoneInfo . WriteNetworkAddressesTo ( _dnsServer . BlockingBypassList , bW ) ;
2023-10-29 19:16:36 +05:30
2022-09-18 18:04:28 +05:30
bW . Write ( ( byte ) _dnsServer . BlockingType ) ;
2024-10-19 17:01:05 +05:30
bW . Write ( _dnsServer . BlockingAnswerTtl ) ;
2022-09-18 18:04:28 +05:30
{
bW . Write ( Convert . ToByte ( _dnsServer . CustomBlockingARecords . Count + _dnsServer . CustomBlockingAAAARecords . Count ) ) ;
foreach ( DnsARecordData record in _dnsServer . CustomBlockingARecords )
record . Address . WriteTo ( bW ) ;
foreach ( DnsAAAARecordData record in _dnsServer . CustomBlockingAAAARecords )
record . Address . WriteTo ( bW ) ;
}
{
bW . Write ( Convert . ToByte ( _dnsServer . BlockListZoneManager . AllowListUrls . Count + _dnsServer . BlockListZoneManager . BlockListUrls . Count ) ) ;
foreach ( Uri allowListUrl in _dnsServer . BlockListZoneManager . AllowListUrls )
bW . WriteShortString ( "!" + allowListUrl . AbsoluteUri ) ;
foreach ( Uri blockListUrl in _dnsServer . BlockListZoneManager . BlockListUrls )
bW . WriteShortString ( blockListUrl . AbsoluteUri ) ;
2022-12-24 17:14:51 +05:30
bW . Write ( _settingsApi . BlockListUpdateIntervalHours ) ;
bW . Write ( _settingsApi . BlockListLastUpdatedOn ) ;
2022-09-18 18:04:28 +05:30
}
//proxy & forwarders
2019-06-15 13:30:03 +05:30
if ( _dnsServer . Proxy = = null )
{
bW . Write ( ( byte ) NetProxyType . None ) ;
}
else
{
bW . Write ( ( byte ) _dnsServer . Proxy . Type ) ;
bW . WriteShortString ( _dnsServer . Proxy . Address ) ;
bW . Write ( _dnsServer . Proxy . Port ) ;
NetworkCredential credential = _dnsServer . Proxy . Credential ;
if ( credential = = null )
{
bW . Write ( false ) ;
}
else
{
bW . Write ( true ) ;
bW . WriteShortString ( credential . UserName ) ;
bW . WriteShortString ( credential . Password ) ;
}
2019-12-15 18:35:36 +05:30
//bypass list
{
2020-04-18 14:06:19 +05:30
bW . Write ( Convert . ToByte ( _dnsServer . Proxy . BypassList . Count ) ) ;
2019-12-15 18:35:36 +05:30
2020-04-18 14:06:19 +05:30
foreach ( NetProxyBypassItem item in _dnsServer . Proxy . BypassList )
2019-12-15 18:35:36 +05:30
bW . WriteShortString ( item . Value ) ;
}
2019-06-15 13:30:03 +05:30
}
if ( _dnsServer . Forwarders = = null )
{
bW . Write ( ( byte ) 0 ) ;
}
else
{
2020-06-06 16:52:36 +05:30
bW . Write ( Convert . ToByte ( _dnsServer . Forwarders . Count ) ) ;
2019-06-15 13:30:03 +05:30
foreach ( NameServerAddress forwarder in _dnsServer . Forwarders )
forwarder . WriteTo ( bW ) ;
}
2024-09-14 19:19:59 +05:30
bW . Write ( _dnsServer . ConcurrentForwarding ) ;
2022-03-12 15:49:42 +05:30
bW . Write ( _dnsServer . ForwarderRetries ) ;
bW . Write ( _dnsServer . ForwarderTimeout ) ;
bW . Write ( _dnsServer . ForwarderConcurrency ) ;
2022-09-18 18:04:28 +05:30
//logging
2023-10-29 19:16:36 +05:30
bW . Write ( _dnsServer . ResolverLogManager is null ) ; //ignore resolver logs
2022-09-18 18:04:28 +05:30
bW . Write ( _dnsServer . QueryLogManager is not null ) ; //log all queries
2024-02-04 18:01:49 +05:30
bW . Write ( _dnsServer . StatsManager . EnableInMemoryStats ) ;
2022-09-18 18:04:28 +05:30
bW . Write ( _dnsServer . StatsManager . MaxStatFileDays ) ;
2019-06-15 13:30:03 +05:30
}
}
2024-09-14 19:19:59 +05:30
#endregion
#region secondary catalog zones
private void AuthZoneManager_SecondaryCatalogZoneAdded ( object sender , SecondaryCatalogEventArgs e )
2024-02-04 18:01:49 +05:30
{
2024-09-14 19:19:59 +05:30
AuthZoneInfo sourceZoneInfo = new AuthZoneInfo ( sender as ApexZone ) ;
AuthZoneInfo zoneInfo = e . ZoneInfo ;
2024-02-04 18:01:49 +05:30
2024-09-14 19:19:59 +05:30
//clone user/group permissions from source zone
Permission sourceZonePermissions = _authManager . GetPermission ( PermissionSection . Zones , sourceZoneInfo . Name ) ;
2024-02-04 18:01:49 +05:30
2024-09-14 19:19:59 +05:30
foreach ( KeyValuePair < User , PermissionFlag > userPermission in sourceZonePermissions . UserPermissions )
_authManager . SetPermission ( PermissionSection . Zones , zoneInfo . Name , userPermission . Key , userPermission . Value ) ;
2024-02-04 18:01:49 +05:30
2024-09-14 19:19:59 +05:30
foreach ( KeyValuePair < Group , PermissionFlag > groupPermissions in sourceZonePermissions . GroupPermissions )
_authManager . SetPermission ( PermissionSection . Zones , zoneInfo . Name , groupPermissions . Key , groupPermissions . Value ) ;
//set default permissions
_authManager . SetPermission ( PermissionSection . Zones , zoneInfo . Name , _authManager . GetGroup ( Group . ADMINISTRATORS ) , PermissionFlag . ViewModifyDelete ) ;
_authManager . SetPermission ( PermissionSection . Zones , zoneInfo . Name , _authManager . GetGroup ( Group . DNS_ADMINISTRATORS ) , PermissionFlag . ViewModifyDelete ) ;
_authManager . SaveConfigFile ( ) ;
2024-02-04 18:01:49 +05:30
}
2024-09-14 19:19:59 +05:30
private void AuthZoneManager_SecondaryCatalogZoneRemoved ( object sender , SecondaryCatalogEventArgs e )
2024-02-04 18:01:49 +05:30
{
2024-09-14 19:19:59 +05:30
_authManager . RemoveAllPermissions ( PermissionSection . Zones , e . ZoneInfo . Name ) ;
_authManager . SaveConfigFile ( ) ;
2024-02-04 18:01:49 +05:30
}
2021-02-27 19:18:08 +05:30
#endregion
2019-06-15 13:30:03 +05:30
#region public
2023-01-01 18:48:08 +05:30
public async Task StartAsync ( )
2019-06-15 13:30:03 +05:30
{
if ( _disposed )
2024-02-04 18:01:49 +05:30
ObjectDisposedException . ThrowIf ( _disposed , this ) ;
2019-06-15 13:30:03 +05:30
try
{
2020-10-31 13:15:34 +05:30
//get initial server domain
2024-05-19 16:08:35 +05:30
string dnsServerDomain = Environment . MachineName . ToLowerInvariant ( ) ;
2020-12-25 19:27:36 +05:30
if ( ! DnsClient . IsDomainNameValid ( dnsServerDomain ) )
dnsServerDomain = "dns-server-1" ; //use this name instead since machine name is not a valid domain name
2020-10-31 13:15:34 +05:30
2020-06-06 16:52:36 +05:30
//init dns server
2020-12-25 19:27:36 +05:30
_dnsServer = new DnsServer ( dnsServerDomain , _configFolder , Path . Combine ( _appFolder , "dohwww" ) , _log ) ;
2020-06-06 16:52:36 +05:30
//init dhcp server
2020-06-13 14:05:02 +05:30
_dhcpServer = new DhcpServer ( Path . Combine ( _configFolder , "scopes" ) , _log ) ;
2022-11-12 15:13:56 +05:30
_dhcpServer . DnsServer = _dnsServer ;
2022-09-18 18:04:28 +05:30
_dhcpServer . AuthManager = _authManager ;
//load auth config
_authManager . LoadConfigFile ( ) ;
2019-06-15 13:30:03 +05:30
2020-06-20 14:01:02 +05:30
//load config
2019-06-15 13:30:03 +05:30
LoadConfigFile ( ) ;
2021-03-06 17:48:21 +05:30
//load all dns applications
2025-03-29 19:12:54 +05:30
await _dnsServer . DnsApplicationManager . LoadAllApplicationsAsync ( ) ;
2021-02-27 19:18:08 +05:30
2020-06-20 14:01:02 +05:30
//load all zones files
2024-09-14 19:19:59 +05:30
_dnsServer . AuthZoneManager . SecondaryCatalogZoneAdded + = AuthZoneManager_SecondaryCatalogZoneAdded ;
_dnsServer . AuthZoneManager . SecondaryCatalogZoneRemoved + = AuthZoneManager_SecondaryCatalogZoneRemoved ;
2020-06-20 14:01:02 +05:30
_dnsServer . AuthZoneManager . LoadAllZoneFiles ( ) ;
2022-09-18 18:04:28 +05:30
InspectAndFixZonePermissions ( ) ;
2020-06-20 14:01:02 +05:30
//disable zones from old config format
2019-06-15 13:30:03 +05:30
if ( _configDisabledZones ! = null )
{
foreach ( string domain in _configDisabledZones )
{
2020-06-13 14:05:02 +05:30
AuthZoneInfo zoneInfo = _dnsServer . AuthZoneManager . GetAuthZoneInfo ( domain ) ;
2022-02-20 17:12:23 +05:30
if ( zoneInfo is not null )
2020-06-06 16:52:36 +05:30
{
zoneInfo . Disabled = true ;
_dnsServer . AuthZoneManager . SaveZoneFile ( zoneInfo . Name ) ;
}
2019-06-15 13:30:03 +05:30
}
}
2020-06-20 14:01:02 +05:30
//load allowed zone and blocked zone
_dnsServer . AllowedZoneManager . LoadAllowedZoneFile ( ) ;
_dnsServer . BlockedZoneManager . LoadBlockedZoneFile ( ) ;
//load block list zone async
2023-08-12 13:13:22 +05:30
if ( ( _dnsServer . BlockListZoneManager . AllowListUrls . Count + _dnsServer . BlockListZoneManager . BlockListUrls . Count ) > 0 )
2020-06-20 14:01:02 +05:30
{
ThreadPool . QueueUserWorkItem ( delegate ( object state )
{
try
{
_dnsServer . BlockListZoneManager . LoadBlockLists ( ) ;
}
catch ( Exception ex )
{
_log . Write ( ex ) ;
}
} ) ;
2023-08-12 13:13:22 +05:30
if ( _settingsApi . BlockListUpdateIntervalHours > 0 )
2024-02-04 18:01:49 +05:30
_settingsApi . StartBlockListUpdateTimer ( false ) ;
2023-08-12 13:13:22 +05:30
}
2023-05-20 18:10:40 +05:30
2023-01-14 14:59:50 +05:30
//load dns cache async
if ( _saveCache )
{
ThreadPool . QueueUserWorkItem ( delegate ( object state )
{
try
{
_dnsServer . CacheZoneManager . LoadCacheZoneFile ( ) ;
}
catch ( Exception ex )
{
2023-08-26 12:34:52 +05:30
_log . Write ( "Failed to fully load DNS Cache from disk\r\n" + ex . ToString ( ) ) ;
2023-01-14 14:59:50 +05:30
}
} ) ;
}
2019-06-15 13:30:03 +05:30
//start web service
2024-09-14 19:19:59 +05:30
await TryStartWebServiceAsync ( [ IPAddress . Any , IPAddress . IPv6Any ] , 5380 , 53443 ) ;
2023-01-14 14:59:50 +05:30
//start dns and dhcp
await _dnsServer . StartAsync ( ) ;
_dhcpServer . Start ( ) ;
2019-06-15 13:30:03 +05:30
2020-12-25 19:27:36 +05:30
_log . Write ( "DNS Server (v" + _currentVersion . ToString ( ) + ") was started successfully." ) ;
2019-06-15 13:30:03 +05:30
}
catch ( Exception ex )
{
2020-12-25 19:27:36 +05:30
_log . Write ( "Failed to start DNS Server (v" + _currentVersion . ToString ( ) + ")\r\n" + ex . ToString ( ) ) ;
2019-06-15 13:30:03 +05:30
throw ;
}
}
2023-01-01 18:48:08 +05:30
public async Task StopAsync ( )
2019-06-15 13:30:03 +05:30
{
2023-04-29 16:16:55 +05:30
if ( _disposed | | ( _dnsServer is null ) )
2019-06-15 13:30:03 +05:30
return ;
try
{
2023-01-14 14:59:50 +05:30
//stop dns
if ( _dnsServer is not null )
await _dnsServer . DisposeAsync ( ) ;
//stop dhcp
if ( _dhcpServer is not null )
_dhcpServer . Dispose ( ) ;
//stop web service
if ( _settingsApi is not null )
{
_settingsApi . StopBlockListUpdateTimer ( ) ;
_settingsApi . StopTemporaryDisableBlockingTimer ( ) ;
}
2019-06-15 13:30:03 +05:30
StopTlsCertificateUpdateTimer ( ) ;
2023-01-14 14:59:50 +05:30
await StopWebServiceAsync ( ) ;
if ( _saveCache )
{
try
{
_dnsServer . CacheZoneManager . SaveCacheZoneFile ( ) ;
}
catch ( Exception ex )
{
_log . Write ( ex ) ;
}
}
_log ? . Write ( "DNS Server (v" + _currentVersion . ToString ( ) + ") was stopped successfully." ) ;
2019-06-15 13:30:03 +05:30
}
catch ( Exception ex )
{
2023-01-14 14:59:50 +05:30
_log ? . Write ( "Failed to stop DNS Server (v" + _currentVersion . ToString ( ) + ")\r\n" + ex . ToString ( ) ) ;
2019-06-15 13:30:03 +05:30
throw ;
}
}
2023-01-01 18:48:08 +05:30
public void Start ( )
{
StartAsync ( ) . Sync ( ) ;
}
public void Stop ( )
{
StopAsync ( ) . Sync ( ) ;
}
2019-06-15 13:30:03 +05:30
#endregion
#region properties
public string ConfigFolder
{ get { return _configFolder ; } }
2020-12-25 19:27:36 +05:30
public int WebServiceHttpPort
{ get { return _webServiceHttpPort ; } }
2019-06-15 13:30:03 +05:30
2021-11-06 13:29:48 +05:30
public int WebServiceTlsPort
{ get { return _webServiceTlsPort ; } }
2025-02-15 12:45:41 +05:30
internal bool IsWebServiceTlsEnabled
{
get
{
return _webServiceEnableTls & & ( _webServiceUseSelfSignedTlsCertificate | | ! string . IsNullOrEmpty ( _webServiceTlsCertificatePath ) ) & & ( _webServiceSslServerAuthenticationOptions is not null ) ;
}
}
internal X509Certificate2 WebServiceTlsCertificate
{
get
{
if ( _webServiceSslServerAuthenticationOptions is null )
return null ;
return _webServiceSslServerAuthenticationOptions . ServerCertificateContext . TargetCertificate ;
}
}
2019-06-15 13:30:03 +05:30
#endregion
}
}