Skip to content

Commit

Permalink
Rewrite system proxy set
Browse files Browse the repository at this point in the history
  • Loading branch information
justcoding121 committed Feb 6, 2016
1 parent de0ec9c commit 3da0c59
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 60 deletions.
10 changes: 6 additions & 4 deletions Titanium.Web.Proxy.Test/ProxyTestController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,22 @@ public void StartProxy()
//Usefull for clients that use certificate pinning
//for example dropbox.com
var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Loopback, 8000, true){
ExcludedHostNameRegex = new List<string>() { "dropbox.com" }
ExcludedHttpsHostNameRegex = new List<string>() { "dropbox.com" }
};

var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Loopback, 8001, true);

ProxyServer.AddEndPoint(explicitEndPoint);
ProxyServer.AddEndPoint(transparentEndPoint);
ProxyServer.Start();

//You can also add/remove end points after proxy has been started
ProxyServer.AddEndPoint(transparentEndPoint);

foreach (var endPoint in ProxyServer.ProxyEndPoints)
Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);

ProxyServer.SetAsSystemProxy(explicitEndPoint);

ProxyServer.SetAsSystemHttpProxy(explicitEndPoint);
ProxyServer.SetAsSystemHttpsProxy(explicitEndPoint);
}

public void Stop()
Expand Down
6 changes: 4 additions & 2 deletions Titanium.Web.Proxy/Models/EndPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ public ProxyEndPoint(IPAddress IpAddress, int Port, bool EnableSsl)

public class ExplicitProxyEndPoint : ProxyEndPoint
{
internal bool IsSystemProxy { get; set; }
public List<string> ExcludedHostNameRegex { get; set; }
internal bool IsSystemHttpProxy { get; set; }
internal bool IsSystemHttpsProxy { get; set; }

public List<string> ExcludedHttpsHostNameRegex { get; set; }

public ExplicitProxyEndPoint(IPAddress IpAddress, int Port, bool EnableSsl)
: base(IpAddress, Port, EnableSsl)
Expand Down
155 changes: 102 additions & 53 deletions Titanium.Web.Proxy/ProxyServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public partial class ProxyServer
Encoding.ASCII.GetBytes(0.ToString("x2") + Environment.NewLine + Environment.NewLine);

#if NET45
internal static SslProtocols SupportedProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Ssl3 ;
internal static SslProtocols SupportedProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Ssl3;
#else
public static SslProtocols SupportedProtocols = SslProtocols.Tls | SslProtocols.Ssl3;
#endif
Expand All @@ -53,7 +53,7 @@ static ProxyServer()
private static CertificateManager CertManager { get; set; }
private static bool EnableSsl { get; set; }
private static bool certTrusted { get; set; }
private static bool proxyStarted { get; set; }
private static bool proxyRunning { get; set; }

public static string RootCertificateName { get; set; }

Expand All @@ -69,75 +69,144 @@ public static void Initialize()

public static void AddEndPoint(ProxyEndPoint endPoint)
{
if (proxyStarted)
throw new Exception("Cannot add end points after proxy started.");

ProxyEndPoints.Add(endPoint);

if (proxyRunning)
Listen(endPoint);
}


public static void SetAsSystemProxy(ExplicitProxyEndPoint endPoint)
public static void RemoveEndPoint(ProxyEndPoint endPoint)
{

if (ProxyEndPoints.Contains(endPoint) == false)
throw new Exception("Cannot set endPoints not added to proxy as system proxy");
throw new Exception("Cannot remove endPoints not added to proxy");

if (!proxyStarted)
throw new Exception("Cannot set system proxy settings before proxy has been started.");
ProxyEndPoints.Remove(endPoint);

if (proxyRunning)
QuitListen(endPoint);
}

//clear any settings previously added
ProxyEndPoints.OfType<ExplicitProxyEndPoint>().ToList().ForEach(x => x.IsSystemProxy = false);

endPoint.IsSystemProxy = true;
public static void SetAsSystemHttpProxy(ExplicitProxyEndPoint endPoint)
{
VerifyProxy(endPoint);

//clear any settings previously added
ProxyEndPoints.OfType<ExplicitProxyEndPoint>().ToList().ForEach(x => x.IsSystemHttpProxy = false);

SystemProxyHelper.EnableProxyHttp(
Equals(endPoint.IpAddress, IPAddress.Any) | Equals(endPoint.IpAddress, IPAddress.Loopback) ? "127.0.0.1" : endPoint.IpAddress.ToString(), endPoint.Port);

endPoint.IsSystemHttpProxy = true;
#if !DEBUG
FireFoxHelper.AddFirefox();
#endif
Console.WriteLine("Set endpoint at Ip {1} and port: {2} as System HTTPS Proxy", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);

}

public static void SetAsSystemHttpsProxy(ExplicitProxyEndPoint endPoint)
{
VerifyProxy(endPoint);

if (!endPoint.EnableSsl)
{
throw new Exception("Endpoint do not support Https connections");
}

//clear any settings previously added
ProxyEndPoints.OfType<ExplicitProxyEndPoint>().ToList().ForEach(x => x.IsSystemHttpsProxy = false);

RootCertificateName = RootCertificateName ?? "Titanium_Proxy_Test_Root";

if (endPoint.EnableSsl)
//If certificate was trusted by the machine
if (certTrusted)
{
RootCertificateName = RootCertificateName ?? "Titanium_Proxy_Test_Root";

//If certificate was trusted by the machine
if (certTrusted)
{
SystemProxyHelper.EnableProxyHttps(
Equals(endPoint.IpAddress, IPAddress.Any) | Equals(endPoint.IpAddress, IPAddress.Loopback) ? "127.0.0.1" : endPoint.IpAddress.ToString(),
endPoint.Port);
}
SystemProxyHelper.EnableProxyHttps(
Equals(endPoint.IpAddress, IPAddress.Any) | Equals(endPoint.IpAddress, IPAddress.Loopback) ? "127.0.0.1" : endPoint.IpAddress.ToString(),
endPoint.Port);
}

Console.WriteLine("Set endpoint at Ip {1} and port: {2} as System Proxy", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);
endPoint.IsSystemHttpsProxy = true;

#if !DEBUG
FireFoxHelper.AddFirefox();
#endif
Console.WriteLine("Set endpoint at Ip {1} and port: {2} as System HTTPS Proxy", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);
}

public static void Start()
{
if (proxyRunning)
throw new Exception("Proxy is already running.");

EnableSsl = ProxyEndPoints.Any(x => x.EnableSsl);

if (EnableSsl)
certTrusted = CertManager.CreateTrustedRootCertificate();

foreach (var endPoint in ProxyEndPoints)
{
Listen(endPoint);
}

proxyRunning = true;
}

public static void Stop()
{
if (!proxyRunning)
throw new Exception("Proxy is not running.");

endPoint.listener = new TcpListener(endPoint.IpAddress, endPoint.Port);
endPoint.listener.Start();
var SetAsSystemProxy = ProxyEndPoints.OfType<ExplicitProxyEndPoint>().Any(x => x.IsSystemHttpProxy || x.IsSystemHttpsProxy);

endPoint.Port = ((IPEndPoint)endPoint.listener.LocalEndpoint).Port;
// accept clients asynchronously
endPoint.listener.BeginAcceptTcpClient(OnAcceptConnection, endPoint);
if (SetAsSystemProxy)
{
SystemProxyHelper.DisableAllProxy();
#if !DEBUG
FireFoxHelper.RemoveFirefox();
#endif
}

foreach (var endPoint in ProxyEndPoints)
{
endPoint.listener.Stop();
}

proxyStarted = true;
CertManager.Dispose();

proxyRunning = false;
}

private static void Listen(ProxyEndPoint endPoint)
{
endPoint.listener = new TcpListener(endPoint.IpAddress, endPoint.Port);
endPoint.listener.Start();

endPoint.Port = ((IPEndPoint)endPoint.listener.LocalEndpoint).Port;
// accept clients asynchronously
endPoint.listener.BeginAcceptTcpClient(OnAcceptConnection, endPoint);
}

private static void QuitListen(ProxyEndPoint endPoint)
{
endPoint.listener.Stop();
}


private static void VerifyProxy(ExplicitProxyEndPoint endPoint)
{
if (ProxyEndPoints.Contains(endPoint) == false)
throw new Exception("Cannot set endPoints not added to proxy as system proxy");

if (!proxyRunning)
throw new Exception("Cannot set system proxy settings before proxy has been started.");
}

private static void OnAcceptConnection(IAsyncResult asyn)
{
var endPoint = (ProxyEndPoint)asyn.AsyncState;

var client = endPoint.listener.EndAcceptTcpClient(asyn);

try
Expand All @@ -151,30 +220,10 @@ private static void OnAcceptConnection(IAsyncResult asyn)
{
// ignored
}

// Get the listener that handles the client request.
endPoint.listener.BeginAcceptTcpClient(OnAcceptConnection, endPoint);

}


public static void Stop()
{
var SetAsSystemProxy = ProxyEndPoints.OfType<ExplicitProxyEndPoint>().Any(x => x.IsSystemProxy);

if (SetAsSystemProxy)
{
SystemProxyHelper.DisableAllProxy();
#if !DEBUG
FireFoxHelper.RemoveFirefox();
#endif
}

foreach (var endPoint in ProxyEndPoints)
{
endPoint.listener.Stop();
}

CertManager.Dispose();
}

}
}
2 changes: 1 addition & 1 deletion Titanium.Web.Proxy/RequestHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ private static void HandleClient(ExplicitProxyEndPoint endPoint, TcpClient clien

var httpVersion = httpCmdSplit[2];

var excluded = endPoint.ExcludedHostNameRegex != null ? endPoint.ExcludedHostNameRegex.Any(x => Regex.IsMatch(httpRemoteUri.Host, x)) : false;
var excluded = endPoint.ExcludedHttpsHostNameRegex != null ? endPoint.ExcludedHttpsHostNameRegex.Any(x => Regex.IsMatch(httpRemoteUri.Host, x)) : false;

//Client wants to create a secure tcp tunnel (its a HTTPS request)
if (httpVerb.ToUpper() == "CONNECT" && !excluded && httpRemoteUri.Port != 80)
Expand Down

0 comments on commit 3da0c59

Please sign in to comment.