Commit c1f6c64e authored by justcoding121's avatar justcoding121

move methods specific to transparent endpoint; Mark obsolete;

parent 29de4d43
...@@ -14,7 +14,7 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -14,7 +14,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
public class ProxyTestController public class ProxyTestController
{ {
private readonly ProxyServer proxyServer; private readonly ProxyServer proxyServer;
private ExplicitProxyEndPoint explicitEndPoint;
//keep track of request headers //keep track of request headers
private readonly IDictionary<Guid, HeaderCollection> requestHeaderHistory = new ConcurrentDictionary<Guid, HeaderCollection>(); private readonly IDictionary<Guid, HeaderCollection> requestHeaderHistory = new ConcurrentDictionary<Guid, HeaderCollection>();
...@@ -52,30 +52,14 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -52,30 +52,14 @@ namespace Titanium.Web.Proxy.Examples.Basic
{ {
proxyServer.BeforeRequest += OnRequest; proxyServer.BeforeRequest += OnRequest;
proxyServer.BeforeResponse += OnResponse; proxyServer.BeforeResponse += OnResponse;
proxyServer.TunnelConnectRequest += OnTunnelConnectRequest;
proxyServer.TunnelConnectResponse += OnTunnelConnectResponse;
proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; proxyServer.ServerCertificateValidationCallback += OnCertificateValidation;
proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection;
//proxyServer.EnableWinAuth = true; //proxyServer.EnableWinAuth = true;
var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true) explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true)
{
//Exclude Https addresses you don't want to proxy
//Useful for clients that use certificate pinning
//for example google.com and dropbox.com
ExcludedHttpsHostNameRegex = new List<string>
{ {
"dropbox.com"
},
//Include Https addresses you want to proxy (others will be excluded)
//for example github.com
//IncludedHttpsHostNameRegex = new List<string>
//{
// "github.com"
//},
//You can set only one of the ExcludedHttpsHostNameRegex and IncludedHttpsHostNameRegex properties, otherwise ArgumentException will be thrown //You can set only one of the ExcludedHttpsHostNameRegex and IncludedHttpsHostNameRegex properties, otherwise ArgumentException will be thrown
//Use self-issued generic certificate on all https requests //Use self-issued generic certificate on all https requests
...@@ -84,6 +68,15 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -84,6 +68,15 @@ namespace Titanium.Web.Proxy.Examples.Basic
//GenericCertificate = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "genericcert.pfx"), "password") //GenericCertificate = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "genericcert.pfx"), "password")
}; };
//Exclude Https addresses you don't want to proxy
//Useful for clients that use certificate pinning
//for example google.com and dropbox.com
explicitEndPoint.BeforeTunnelConnect += OnBeforeTunnelConnect;
explicitEndPoint.TunnelConnectRequest += OnTunnelConnectRequest;
explicitEndPoint.TunnelConnectResponse += OnTunnelConnectResponse;
//An explicit endpoint is where the client knows about the existence of a proxy //An explicit endpoint is where the client knows about the existence of a proxy
//So client sends request in a proxy friendly manner //So client sends request in a proxy friendly manner
proxyServer.AddEndPoint(explicitEndPoint); proxyServer.AddEndPoint(explicitEndPoint);
...@@ -120,8 +113,10 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -120,8 +113,10 @@ namespace Titanium.Web.Proxy.Examples.Basic
public void Stop() public void Stop()
{ {
proxyServer.TunnelConnectRequest -= OnTunnelConnectRequest; explicitEndPoint.BeforeTunnelConnect -= OnBeforeTunnelConnect;
proxyServer.TunnelConnectResponse -= OnTunnelConnectResponse; explicitEndPoint.TunnelConnectRequest -= OnTunnelConnectRequest;
explicitEndPoint.TunnelConnectResponse -= OnTunnelConnectResponse;
proxyServer.BeforeRequest -= OnRequest; proxyServer.BeforeRequest -= OnRequest;
proxyServer.BeforeResponse -= OnResponse; proxyServer.BeforeResponse -= OnResponse;
proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation; proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation;
...@@ -133,6 +128,20 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -133,6 +128,20 @@ namespace Titanium.Web.Proxy.Examples.Basic
//proxyServer.CertificateManager.RemoveTrustedRootCertificates(); //proxyServer.CertificateManager.RemoveTrustedRootCertificates();
} }
private async Task<bool> OnBeforeTunnelConnect(string hostname)
{
if (hostname.Contains("google.com") || hostname.Contains("bing.com"))
{
//exclude bing.com and google.com from being decrypted
//instead it will be relayed via a secure TCP tunnel
return await Task.FromResult(true);
}
else
{
return await Task.FromResult(false);
}
}
private async Task OnTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e) private async Task OnTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
{ {
Console.WriteLine("Tunnel to: " + e.WebSession.Request.Host); Console.WriteLine("Tunnel to: " + e.WebSession.Request.Host);
......
...@@ -5,6 +5,9 @@ using System.Net; ...@@ -5,6 +5,9 @@ using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Extensions;
namespace Titanium.Web.Proxy.Models namespace Titanium.Web.Proxy.Models
{ {
...@@ -67,9 +70,15 @@ namespace Titanium.Web.Proxy.Models ...@@ -67,9 +70,15 @@ namespace Titanium.Web.Proxy.Models
internal bool IsSystemHttpsProxy { get; set; } internal bool IsSystemHttpsProxy { get; set; }
/// <summary>
/// Generic certificate to use for SSL decryption.
/// </summary>
public X509Certificate2 GenericCertificate { get; set; }
/// <summary> /// <summary>
/// List of host names to exclude using Regular Expressions. /// List of host names to exclude using Regular Expressions.
/// </summary> /// </summary>
[Obsolete("ExcludedHttpsHostNameRegex is deprecated, please use ExcludeTunnelConnect instead.")]
public IEnumerable<string> ExcludedHttpsHostNameRegex public IEnumerable<string> ExcludedHttpsHostNameRegex
{ {
get { return ExcludedHttpsHostNameRegexList?.Select(x => x.ToString()).ToList(); } get { return ExcludedHttpsHostNameRegexList?.Select(x => x.ToString()).ToList(); }
...@@ -87,6 +96,7 @@ namespace Titanium.Web.Proxy.Models ...@@ -87,6 +96,7 @@ namespace Titanium.Web.Proxy.Models
/// <summary> /// <summary>
/// List of host names to exclude using Regular Expressions. /// List of host names to exclude using Regular Expressions.
/// </summary> /// </summary>
[Obsolete("IncludedHttpsHostNameRegex is deprecated, please use ExcludeTunnelConnect instead.")]
public IEnumerable<string> IncludedHttpsHostNameRegex public IEnumerable<string> IncludedHttpsHostNameRegex
{ {
get { return IncludedHttpsHostNameRegexList?.Select(x => x.ToString()).ToList(); } get { return IncludedHttpsHostNameRegexList?.Select(x => x.ToString()).ToList(); }
...@@ -102,10 +112,22 @@ namespace Titanium.Web.Proxy.Models ...@@ -102,10 +112,22 @@ namespace Titanium.Web.Proxy.Models
} }
/// <summary> /// <summary>
/// Generic certificate to use for SSL decryption. /// Return true if this HTTP connect request should'nt be decrypted and instead be relayed
/// Valid only for explicit endpoints
/// </summary> /// </summary>
public X509Certificate2 GenericCertificate { get; set; } public Func<string, Task<bool>> BeforeTunnelConnect;
/// <summary>
/// Intercept tunnel connect request
/// Valid only for explicit endpoints
/// </summary>
public event AsyncEventHandler<TunnelConnectSessionEventArgs> TunnelConnectRequest;
/// <summary>
/// Intercept tunnel connect response
/// Valid only for explicit endpoints
/// </summary>
public event AsyncEventHandler<TunnelConnectSessionEventArgs> TunnelConnectResponse;
/// <summary> /// <summary>
/// Constructor. /// Constructor.
/// </summary> /// </summary>
...@@ -115,6 +137,31 @@ namespace Titanium.Web.Proxy.Models ...@@ -115,6 +137,31 @@ namespace Titanium.Web.Proxy.Models
public ExplicitProxyEndPoint(IPAddress ipAddress, int port, bool enableSsl) : base(ipAddress, port, enableSsl) public ExplicitProxyEndPoint(IPAddress ipAddress, int port, bool enableSsl) : base(ipAddress, port, enableSsl)
{ {
} }
internal async Task InvokeTunnectConnectRequest(ProxyServer proxyServer, TunnelConnectSessionEventArgs connectArgs, Action<Exception> exceptionFunc)
{
if (TunnelConnectRequest != null)
{
await TunnelConnectRequest.InvokeAsync(proxyServer, connectArgs, exceptionFunc);
}
}
internal async Task InvokeTunnectConnectResponse(ProxyServer proxyServer, TunnelConnectSessionEventArgs connectArgs, Action<Exception> exceptionFunc)
{
if (TunnelConnectResponse != null)
{
await TunnelConnectResponse.InvokeAsync(proxyServer, connectArgs, exceptionFunc);
}
}
internal async Task InvokeTunnectConnectResponse(ProxyServer proxyServer, TunnelConnectSessionEventArgs connectArgs, Action<Exception> exceptionFunc, bool isClientHello)
{
if (TunnelConnectResponse != null)
{
connectArgs.IsHttpsConnect = isClientHello;
await TunnelConnectResponse.InvokeAsync(proxyServer, connectArgs, exceptionFunc);
}
}
} }
/// <summary> /// <summary>
......
...@@ -285,24 +285,6 @@ namespace Titanium.Web.Proxy ...@@ -285,24 +285,6 @@ namespace Titanium.Web.Proxy
/// </summary> /// </summary>
public event EventHandler ServerConnectionCountChanged; public event EventHandler ServerConnectionCountChanged;
/// <summary>
/// Return true if this HTTP connect request should'nt be decrypted and instead be relayed
/// Valid only for explicit endpoints
/// </summary>
public Func<string, Task<bool>> ExcludeTunnelConnect;
/// <summary>
/// Intercept tunnel connect request
/// Valid only for explicit endpoints
/// </summary>
public event AsyncEventHandler<TunnelConnectSessionEventArgs> TunnelConnectRequest;
/// <summary>
/// Intercept tunnel connect response
/// Valid only for explicit endpoints
/// </summary>
public event AsyncEventHandler<TunnelConnectSessionEventArgs> TunnelConnectResponse;
/// <summary> /// <summary>
/// Verifies the remote Secure Sockets Layer (SSL) certificate used for authentication /// Verifies the remote Secure Sockets Layer (SSL) certificate used for authentication
/// </summary> /// </summary>
......
...@@ -77,9 +77,9 @@ namespace Titanium.Web.Proxy ...@@ -77,9 +77,9 @@ namespace Titanium.Web.Proxy
excluded = !endPoint.IncludedHttpsHostNameRegexList.Any(x => x.IsMatch(connectHostname)); excluded = !endPoint.IncludedHttpsHostNameRegexList.Any(x => x.IsMatch(connectHostname));
} }
if(ExcludeTunnelConnect!=null) if(endPoint.BeforeTunnelConnect!=null)
{ {
excluded = await ExcludeTunnelConnect(connectHostname); excluded = await endPoint.BeforeTunnelConnect(connectHostname);
} }
connectRequest = new ConnectRequest connectRequest = new ConnectRequest
...@@ -95,18 +95,12 @@ namespace Titanium.Web.Proxy ...@@ -95,18 +95,12 @@ namespace Titanium.Web.Proxy
connectArgs.ProxyClient.TcpClient = tcpClient; connectArgs.ProxyClient.TcpClient = tcpClient;
connectArgs.ProxyClient.ClientStream = clientStream; connectArgs.ProxyClient.ClientStream = clientStream;
if (TunnelConnectRequest != null) await endPoint.InvokeTunnectConnectRequest(this, connectArgs, ExceptionFunc);
{
await TunnelConnectRequest.InvokeAsync(this, connectArgs, ExceptionFunc);
}
if (await CheckAuthorization(clientStreamWriter, connectArgs) == false) if (await CheckAuthorization(clientStreamWriter, connectArgs) == false)
{ {
if (TunnelConnectResponse != null) await endPoint.InvokeTunnectConnectResponse(this, connectArgs, ExceptionFunc);
{
await TunnelConnectResponse.InvokeAsync(this, connectArgs, ExceptionFunc);
}
return; return;
} }
...@@ -124,11 +118,7 @@ namespace Titanium.Web.Proxy ...@@ -124,11 +118,7 @@ namespace Titanium.Web.Proxy
connectRequest.ClientHelloInfo = clientHelloInfo; connectRequest.ClientHelloInfo = clientHelloInfo;
} }
if (TunnelConnectResponse != null) await endPoint.InvokeTunnectConnectResponse(this, connectArgs, ExceptionFunc, isClientHello);
{
connectArgs.IsHttpsConnect = isClientHello;
await TunnelConnectResponse.InvokeAsync(this, connectArgs, ExceptionFunc);
}
if (!excluded && isClientHello) if (!excluded && isClientHello)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment