Skip to content

Commit

Permalink
Merge pull request #10 from richardschneider/peds
Browse files Browse the repository at this point in the history
Privacy enabled DNS (PEDS)
  • Loading branch information
richardschneider authored May 31, 2018
2 parents b23d944 + ed899a5 commit 13e16ae
Show file tree
Hide file tree
Showing 20 changed files with 502 additions and 49 deletions.
23 changes: 23 additions & 0 deletions Peds/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/>
</sectionGroup>
</configSections>

<common>
<logging>
<factoryAdapter type="Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter, Common.Logging">
<arg key="level" value="TRACE"/>
<arg key="showLogName" value="true"/>
<arg key="showDataTime" value="true"/>
<arg key="dateTimeFormat" value="yyyy/MM/dd HH:mm:ss:fff"/>
</factoryAdapter>
</logging>
</common>

<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
</startup>
</configuration>
11 changes: 11 additions & 0 deletions Peds/App.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="0.42.0.0" name="Peds"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!--requestedExecutionLevel level="requireAdministrator" uiAccess="false" /-->
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
4 changes: 4 additions & 0 deletions Peds/Issues.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
NIC uses WMI to manage the network adapters. However, WMI does not support IPv6!
See https://github.com/Noxwizard/dnscrypt-winclient/issues/4

Should detect new adapter or adapter is active and set the dns server.
102 changes: 102 additions & 0 deletions Peds/NetShell.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using Common.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;

namespace Peds
{
/// <summary>
/// Builds a list of 'netsh' commands and then executes them
/// all at once.
/// </summary>
class NetShell
{
static ILog log = LogManager.GetLogger("netsh");

StreamWriter commands;
string commandsFilename = Path.GetTempFileName();

/// <summary>
/// Set the DNS servers for a network interface.
/// </summary>
/// <param name="nic">
/// The network interface.
/// </param>
/// <param name="addresses">
/// The <see cref="IPAddress"/> sequence for the DNS server.
/// </param>
public void SetDnsServers(NetworkInterface nic, IEnumerable<IPAddress> addresses)
{
string qname = "\"" + nic.Name + "\"";

// IPv4
var addrs = addresses.Where(a => a.AddressFamily == AddressFamily.InterNetwork);
var primary = true;
foreach (var addr in addrs)
{
if (primary)
{
Run($"interface ipv4 delete dns {qname} all");
}
Run($"interface ipv4 add dns {qname} {addr} validate=no");
primary = false;
}

// IPv6
addrs = addresses.Where(a => a.AddressFamily == AddressFamily.InterNetworkV6);
primary = true;
foreach (var addr in addrs)
{
if (primary)
{
Run($"interface ipv6 delete dns {qname} all");
}
Run($"interface ipv6 add dns {qname} {addr} validate=no");
primary = false;
}
}

void Run(string args)
{
log.Debug(args);
if (commands == null)
{
commands = new StreamWriter(File.OpenWrite(commandsFilename));
}
commands.WriteLine(args);
}

/// <summary>
/// Run the netsh commands.
/// </summary>
public void Run()
{
if (commands == null)
return;
commands.Close();
commands = null;

var args = $"-f \"{commandsFilename}\"";
var netsh = Process.Start(new ProcessStartInfo
{
FileName = "netsh",
Arguments = args,
Verb = "runas",
UseShellExecute = true,
WindowStyle = ProcessWindowStyle.Hidden
});
netsh.WaitForExit(1000);
File.Delete(commandsFilename);
if (netsh.ExitCode != 0)
{
throw new Exception($"netsh failed with exit code {netsh.ExitCode}.");
}
}

}
}
62 changes: 62 additions & 0 deletions Peds/Nic.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using Common.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;

namespace Peds
{
/// <summary>
/// Controls the network interfaces.
/// </summary>
/// <remarks>
/// <b>Dispose</b> restores all networks to thier orignal values.
/// <note>
/// Requires elevated privileges.
/// </note>
/// </remarks>
class Nic : IDisposable
{
static ILog log = LogManager.GetLogger(typeof(Nic));

Dictionary<NetworkInterface, IPAddressCollection> originalDnsServers = new Dictionary<NetworkInterface, IPAddressCollection>();

/// <summary>
/// Set the DNS server addresses for all network interfaces.
/// </summary>
/// <param name="server">
/// The sequence of <see cref="IPAddress"/> for the DNS server.
/// </param>
public void SetDnsServer(IEnumerable<IPAddress> addresses)
{
var netsh = new NetShell();
var nics = NetworkInterface
.GetAllNetworkInterfaces()
.Where(nic => nic.NetworkInterfaceType != NetworkInterfaceType.Loopback)
.Where(nic =>
nic.Supports(NetworkInterfaceComponent.IPv4) ||
nic.Supports(NetworkInterfaceComponent.IPv6));
foreach (var nic in nics)
{
var original = nic.GetIPProperties().DnsAddresses;
originalDnsServers[nic] = original;
netsh.SetDnsServers(nic, addresses);
}
netsh.Run();
}

public void Dispose()
{
var netsh = new NetShell();
foreach (var x in originalDnsServers)
{
netsh.SetDnsServers(x.Key, x.Value);
}
netsh.Run();
}

}
}
25 changes: 25 additions & 0 deletions Peds/Peds.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net461</TargetFramework>
<!--ApplicationManifest>App.manifest</ApplicationManifest-->
<!-- developer build is always 0.2 -->
<AssemblyVersion>0.42</AssemblyVersion>
<Version>0.42</Version>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Common.Logging" Version="3.4.1" />
<PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\src\Udns.csproj" />
</ItemGroup>

<ItemGroup>
<Reference Include="System.Management" />
</ItemGroup>

</Project>
81 changes: 81 additions & 0 deletions Peds/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using Makaretu.Dns;
using System;
using System.Net;
using System.Threading.Tasks;

namespace Peds
{
partial class Program
{
TaskCompletionSource<int> done = new TaskCompletionSource<int>();
UdpServer server;
Nic nic;

static int Main(string[] args)
{
try
{
return new Program().RunAsync(args).Result;
}
catch (AggregateException e)
{
foreach (var ex in e.InnerExceptions)
{
Console.Error.WriteLine(ex.Message);
}
}
catch (Exception e)
{
Console.Error.WriteLine(e.Message);
}
return -1;
}

async Task<int> RunAsync(string[] args)
{
Console.WriteLine("Hi!");

// TODO: Process args

Console.CancelKeyPress += (s, e) =>
{
Console.WriteLine("CTRL-C");
Stop();
e.Cancel = true;
};

Start();
return await done.Task;
}

void Start()
{
var resolver = new DotClient
{
ThrowResponseError = false
};

server = new UdpServer { Resolver = resolver };
server.Start();

nic = new Nic();
nic.SetDnsServer(server.Addresses);
}

void Stop()
{
if (nic != null)
{
nic.Dispose();
nic = null;
}
if (server != null)
{
server.Dispose();
server = null;
}

done.SetCanceled();
}
}
}
Loading

0 comments on commit 13e16ae

Please sign in to comment.