Skip to content

Commit

Permalink
Added DNS Proxy improving privacy protection and enabling system wide…
Browse files Browse the repository at this point in the history
… ad blocking
  • Loading branch information
DavidXanatos committed Nov 30, 2019
1 parent 541327b commit f0602ef
Show file tree
Hide file tree
Showing 93 changed files with 7,665 additions and 434 deletions.
31 changes: 30 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,42 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).


## [0.60] - 2019-11-30

### Added
- added DNS proxy to monitor all DNS requests
- added ability to set priv10 as system DNS
- added DNS Query Log based on DNS Proxy events
- added system DNS cache monitor
- added dns proxy page
- added dns querry log
- added dns blacklist/whitelist page
- added dns blocklists page
- added blocklist update mechanism

### Changed
- reworked DNS Inspector class
- changed from tne .NET reverse dns facility to using native windows API's for better performance
- dns inspector can now be switched on or off

### Fixed
- issue where the accept button in the notifiction window would get disabled again
- issue with aplpyung rules when some rules were already present for the given programm
- issue saving gpo's, sometimes it failed with a file is in use error
- issue where file blockign tweaks were never shown as available after a recent change



## [0.57] - 2019-11-16

### Added
- a few new tweaks
- added a few new tweaks
- aded windows 8 and newer address keywords
- added app context menu option to uninstall the client (remove service, autorun, event log)
- added -help command to show all available console ocmmands
- added clear firewall log option
- added extended program cleanup option

### Changed
- on windows 8 and above the "Internet" address keyword is used for rules, instead of a manually assembled range
Expand Down
88 changes: 88 additions & 0 deletions DNS/Client/ClientRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System;
using System.Collections.Generic;
using System.Net;
using DNS.Protocol;
using DNS.Client.RequestResolver;

namespace DNS.Client {
public class ClientRequest : IRequest {
private const int DEFAULT_PORT = 53;

private IPEndPoint dns;
private IRequestResolver resolver;
private IRequest request;

public ClientRequest(IPEndPoint dns, IRequest request = null, IRequestResolver resolver = null) {
this.dns = dns;
this.request = request == null ? new Request() : new Request(request);
this.resolver = resolver == null ? new UdpRequestResolver() : resolver;
}

public ClientRequest(IPAddress ip, int port = DEFAULT_PORT, IRequest request = null, IRequestResolver resolver = null) :
this(new IPEndPoint(ip, port), request, resolver) { }

public ClientRequest(string ip, int port = DEFAULT_PORT, IRequest request = null, IRequestResolver resolver = null) :
this(IPAddress.Parse(ip), port, request, resolver) { }

public int Id {
get { return request.Id; }
set { request.Id = value; }
}

public OperationCode OperationCode {
get { return request.OperationCode; }
set { request.OperationCode = value; }
}

public bool RecursionDesired {
get { return request.RecursionDesired; }
set { request.RecursionDesired = value; }
}

public IList<Question> Questions {
get { return request.Questions; }
}

public int Size {
get { return request.Size; }
}

public byte[] ToArray() {
return request.ToArray();
}

public override string ToString() {
return request.ToString();
}

public IPEndPoint Dns {
get { return dns; }
set { dns = value; }
}

/// <summary>
/// Resolves this request into a response using the provided DNS information. The given
/// request strategy is used to retrieve the response.
/// </summary>
/// <exception cref="ResponseException">Throw if a malformed response is received from the server</exception>
/// <exception cref="IOException">Thrown if a IO error occurs</exception>
/// <exception cref="SocketException">Thrown if a the reading or writing to the socket fails</exception>
/// <returns>The response received from server</returns>
public ClientResponse Resolve() {
try {
ClientResponse response = resolver.Request(this);

if (response.Id != this.Id) {
throw new ResponseException(response, "Mismatching request/response IDs");
}
if (response.ResponseCode != ResponseCode.NoError) {
throw new ResponseException(response);
}

return response;
} catch (ArgumentException e) {
throw new ResponseException("Invalid response", e);
}
}
}
}
93 changes: 93 additions & 0 deletions DNS/Client/ClientResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using DNS.Protocol;
using DNS.Protocol.ResourceRecords;

namespace DNS.Client {
public class ClientResponse : IResponse {
private Response response;
private byte[] message;

public static ClientResponse FromArray(ClientRequest request, byte[] message) {
Response response = Response.FromArray(message);
return new ClientResponse(request, response, message);
}

internal ClientResponse(ClientRequest request, Response response, byte[] message) {
Request = request;

this.message = message;
this.response = response;
}

internal ClientResponse(ClientRequest request, Response response) {
Request = request;

this.message = response.ToArray();
this.response = response;
}

public ClientRequest Request {
get;
private set;
}

public int Id {
get { return response.Id; }
set { }
}

public IList<IResourceRecord> AnswerRecords {
get { return response.AnswerRecords; }
}

public IList<IResourceRecord> AuthorityRecords {
get { return new ReadOnlyCollection<IResourceRecord>(response.AuthorityRecords); }
}

public IList<IResourceRecord> AdditionalRecords {
get { return new ReadOnlyCollection<IResourceRecord>(response.AdditionalRecords); }
}

public bool RecursionAvailable {
get { return response.RecursionAvailable; }
set { }
}

public bool AuthorativeServer {
get { return response.AuthorativeServer; }
set { }
}

public bool Truncated {
get { return response.Truncated; }
set { }
}

public OperationCode OperationCode {
get { return response.OperationCode; }
set { }
}

public ResponseCode ResponseCode {
get { return response.ResponseCode; }
set { }
}

public IList<Question> Questions {
get { return new ReadOnlyCollection<Question>(response.Questions); }
}

public int Size {
get { return message.Length; }
}

public byte[] ToArray() {
return message;
}

public override string ToString() {
return response.ToString();
}
}
}
86 changes: 86 additions & 0 deletions DNS/Client/DnsClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using DNS.Protocol;
using DNS.Protocol.ResourceRecords;
using DNS.Client.RequestResolver;

namespace DNS.Client {
public class DnsClient {
private const int DEFAULT_PORT = 53;
private static readonly Random RANDOM = new Random();

private IPEndPoint dns;
private IRequestResolver resolver;

public DnsClient(IPEndPoint dns, IRequestResolver resolver = null) {
this.dns = dns;
this.resolver = resolver == null ? new UdpRequestResolver(new TcpRequestResolver()) : resolver;
}

public DnsClient(IPAddress ip, int port = DEFAULT_PORT, IRequestResolver resolver = null) :
this(new IPEndPoint(ip, port), resolver) { }

public DnsClient(string ip, int port = DEFAULT_PORT, IRequestResolver resolver = null) :
this(IPAddress.Parse(ip), port, resolver) { }

public ClientRequest FromArray(byte[] message) {
Request request = Request.FromArray(message);
return new ClientRequest(dns, request, resolver);
}

public ClientRequest Create(IRequest request = null) {
return new ClientRequest(dns, request, resolver);
}

public IList<IPAddress> Lookup(string domain, RecordType type = RecordType.A) {
if (type != RecordType.A && type != RecordType.AAAA) {
throw new ArgumentException("Invalid record type " + type);
}

ClientResponse response = Resolve(domain, type);
IList<IPAddress> ips = response.AnswerRecords
.Where(r => r.Type == type)
.Cast<IPAddressResourceRecord>()
.Select(r => r.IPAddress)
.ToList();

if (ips.Count == 0) {
throw new ResponseException(response, "No matching records");
}

return ips;
}

public string Reverse(string ip) {
return Reverse(IPAddress.Parse(ip));
}

public string Reverse(IPAddress ip) {
ClientResponse response = Resolve(Domain.PointerName(ip), RecordType.PTR);
IResourceRecord ptr = response.AnswerRecords.FirstOrDefault(r => r.Type == RecordType.PTR);

if (ptr == null) {
throw new ResponseException(response, "No matching records");
}

return ((PointerResourceRecord) ptr).PointerDomainName.ToString();
}

public ClientResponse Resolve(string domain, RecordType type) {
return Resolve(new Domain(domain), type);
}

public ClientResponse Resolve(Domain domain, RecordType type) {
ClientRequest request = Create();
Question question = new Question(domain, type);

request.Questions.Add(question);
request.OperationCode = OperationCode.Query;
request.RecursionDesired = true;

return request.Resolve();
}
}
}
5 changes: 5 additions & 0 deletions DNS/Client/RequestResolver/IRequestResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace DNS.Client.RequestResolver {
public interface IRequestResolver {
ClientResponse Request(ClientRequest request);
}
}
7 changes: 7 additions & 0 deletions DNS/Client/RequestResolver/NullRequestResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace DNS.Client.RequestResolver {
public class NullRequestResolver : IRequestResolver {
public ClientResponse Request(ClientRequest request) {
throw new ResponseException("Request failed");
}
}
}
58 changes: 58 additions & 0 deletions DNS/Client/RequestResolver/TcpRequestResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using System.IO;
using System.Net.Sockets;
using DNS.Protocol;

namespace DNS.Client.RequestResolver {
public class TcpRequestResolver : IRequestResolver {
public ClientResponse Request(ClientRequest request) {
TcpClient tcp = new TcpClient();

try {
tcp.Connect(request.Dns);

Stream stream = tcp.GetStream();
byte[] buffer = request.ToArray();
byte[] length = BitConverter.GetBytes((ushort) buffer.Length);

if (BitConverter.IsLittleEndian) {
Array.Reverse(length);
}

stream.Write(length, 0, length.Length);
stream.Write(buffer, 0, buffer.Length);

buffer = new byte[2];
Read(stream, buffer);

if (BitConverter.IsLittleEndian) {
Array.Reverse(buffer);
}

buffer = new byte[BitConverter.ToUInt16(buffer, 0)];
Read(stream, buffer);

Response response = Response.FromArray(buffer);

return new ClientResponse(request, response, buffer);
} finally {
tcp.Close();
}
}

private static void Read(Stream stream, byte[] buffer) {
int length = buffer.Length;
int offset = 0;
int size = 0;

while (length > 0 && (size = stream.Read(buffer, offset, length)) > 0) {
offset += size;
length -= size;
}

if (length > 0) {
throw new IOException("Unexpected end of stream");
}
}
}
}
Loading

0 comments on commit f0602ef

Please sign in to comment.