Commit cbda4ca6 authored by Jehonathan Thomas's avatar Jehonathan Thomas Committed by GitHub

Merge pull request #210 from honfika/develop

#205 IncludedHttpsHostNameRegex  and #207 Inconsistent naming fixes
parents 196bf663 f2988f4a
......@@ -37,9 +37,15 @@ namespace Titanium.Web.Proxy.Examples.Basic
{
//Exclude Https addresses you don't want to proxy
//Useful for clients that use certificate pinning
//for example dropbox.com
//for example google.com and dropbox.com
// ExcludedHttpsHostNameRegex = new List<string>() { "google.com", "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
//Use self-issued generic certificate on all https requests
//Optimizes performance by not creating a certificate for each https-enabled domain
//Useful when certificate trust is not required by proxy clients
......
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
......@@ -13,14 +14,14 @@ namespace Titanium.Web.Proxy.Models
/// <summary>
/// Constructor.
/// </summary>
/// <param name="IpAddress"></param>
/// <param name="Port"></param>
/// <param name="EnableSsl"></param>
protected ProxyEndPoint(IPAddress IpAddress, int Port, bool EnableSsl)
/// <param name="ipAddress"></param>
/// <param name="port"></param>
/// <param name="enableSsl"></param>
protected ProxyEndPoint(IPAddress ipAddress, int port, bool enableSsl)
{
this.IpAddress = IpAddress;
this.Port = Port;
this.EnableSsl = EnableSsl;
this.IpAddress = ipAddress;
this.Port = port;
this.EnableSsl = enableSsl;
}
/// <summary>
......@@ -43,7 +44,7 @@ namespace Titanium.Web.Proxy.Models
|| Equals(IpAddress, IPAddress.IPv6Loopback)
|| Equals(IpAddress, IPAddress.IPv6None);
internal TcpListener listener { get; set; }
internal TcpListener Listener { get; set; }
}
/// <summary>
......@@ -52,13 +53,46 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
public class ExplicitProxyEndPoint : ProxyEndPoint
{
private List<string> _excludedHttpsHostNameRegex;
private List<string> _includedHttpsHostNameRegex;
internal bool IsSystemHttpProxy { get; set; }
internal bool IsSystemHttpsProxy { get; set; }
/// <summary>
/// List of host names to exclude using Regular Expressions.
/// </summary>
public List<string> ExcludedHttpsHostNameRegex { get; set; }
public List<string> ExcludedHttpsHostNameRegex
{
get { return _excludedHttpsHostNameRegex; }
set
{
if (IncludedHttpsHostNameRegex != null)
{
throw new ArgumentException("Cannot set excluded when included is set");
}
_excludedHttpsHostNameRegex = value;
}
}
/// <summary>
/// List of host names to exclude using Regular Expressions.
/// </summary>
public List<string> IncludedHttpsHostNameRegex
{
get { return _includedHttpsHostNameRegex; }
set
{
if (ExcludedHttpsHostNameRegex != null)
{
throw new ArgumentException("Cannot set included when excluded is set");
}
_includedHttpsHostNameRegex = value;
}
}
/// <summary>
/// Generic certificate to use for SSL decryption.
......@@ -68,11 +102,11 @@ namespace Titanium.Web.Proxy.Models
/// <summary>
/// Constructor.
/// </summary>
/// <param name="IpAddress"></param>
/// <param name="Port"></param>
/// <param name="EnableSsl"></param>
public ExplicitProxyEndPoint(IPAddress IpAddress, int Port, bool EnableSsl)
: base(IpAddress, Port, EnableSsl)
/// <param name="ipAddress"></param>
/// <param name="port"></param>
/// <param name="enableSsl"></param>
public ExplicitProxyEndPoint(IPAddress ipAddress, int port, bool enableSsl)
: base(ipAddress, port, enableSsl)
{
}
......@@ -94,11 +128,11 @@ namespace Titanium.Web.Proxy.Models
/// <summary>
/// Constructor.
/// </summary>
/// <param name="IpAddress"></param>
/// <param name="Port"></param>
/// <param name="EnableSsl"></param>
public TransparentProxyEndPoint(IPAddress IpAddress, int Port, bool EnableSsl)
: base(IpAddress, Port, EnableSsl)
/// <param name="ipAddress"></param>
/// <param name="port"></param>
/// <param name="enableSsl"></param>
public TransparentProxyEndPoint(IPAddress ipAddress, int port, bool enableSsl)
: base(ipAddress, port, enableSsl)
{
this.GenericCertificateName = "localhost";
}
......
......@@ -43,9 +43,10 @@ namespace Titanium.Web.Proxy.Network
private readonly Action<Exception> exceptionFunc;
internal string Issuer { get; }
internal string RootCertificateName { get; }
internal X509Certificate2 rootCertificate { get; set; }
internal X509Certificate2 RootCertificate { get; set; }
internal CertificateManager(CertificateEngine engine,
string issuer,
......@@ -107,32 +108,32 @@ namespace Titanium.Web.Proxy.Network
/// <returns>true if succeeded, else false</returns>
internal bool CreateTrustedRootCertificate()
{
rootCertificate = GetRootCertificate();
if (rootCertificate != null)
RootCertificate = GetRootCertificate();
if (RootCertificate != null)
{
return true;
}
try
{
rootCertificate = CreateCertificate(RootCertificateName, true);
RootCertificate = CreateCertificate(RootCertificateName, true);
}
catch (Exception e)
{
exceptionFunc(e);
}
if (rootCertificate != null)
if (RootCertificate != null)
{
try
{
var fileName = GetRootCertificatePath();
File.WriteAllBytes(fileName, rootCertificate.Export(X509ContentType.Pkcs12));
File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12));
}
catch (Exception e)
{
exceptionFunc(e);
}
}
return rootCertificate != null;
return RootCertificate != null;
}
/// <summary>
......@@ -159,7 +160,7 @@ namespace Titanium.Web.Proxy.Network
{
try
{
certificate = certEngine.MakeCertificate(certificateName, isRootCertificate, rootCertificate);
certificate = certEngine.MakeCertificate(certificateName, isRootCertificate, RootCertificate);
}
catch (Exception e)
{
......@@ -226,7 +227,7 @@ namespace Titanium.Web.Proxy.Network
internal void TrustRootCertificate(StoreLocation storeLocation,
Action<Exception> exceptionFunc)
{
if (rootCertificate == null)
if (RootCertificate == null)
{
exceptionFunc(
new Exception("Could not set root certificate"
......@@ -243,8 +244,8 @@ namespace Titanium.Web.Proxy.Network
x509RootStore.Open(OpenFlags.ReadWrite);
x509PersonalStore.Open(OpenFlags.ReadWrite);
x509RootStore.Add(rootCertificate);
x509PersonalStore.Add(rootCertificate);
x509RootStore.Add(RootCertificate);
x509PersonalStore.Add(RootCertificate);
}
catch (Exception e)
{
......
......@@ -13,14 +13,14 @@ namespace Titanium.Web.Proxy
public partial class ProxyServer
{
private async Task<bool> CheckAuthorization(StreamWriter clientStreamWriter, IEnumerable<HttpHeader> Headers)
private async Task<bool> CheckAuthorization(StreamWriter clientStreamWriter, IEnumerable<HttpHeader> headers)
{
if (AuthenticateUserFunc == null)
{
return true;
}
var httpHeaders = Headers as HttpHeader[] ?? Headers.ToArray();
var httpHeaders = headers as HttpHeader[] ?? headers.ToArray();
try
{
......
......@@ -491,12 +491,12 @@ namespace Titanium.Web.Proxy
/// <param name="endPoint"></param>
private void Listen(ProxyEndPoint endPoint)
{
endPoint.listener = new TcpListener(endPoint.IpAddress, endPoint.Port);
endPoint.listener.Start();
endPoint.Listener = new TcpListener(endPoint.IpAddress, endPoint.Port);
endPoint.Listener.Start();
endPoint.Port = ((IPEndPoint)endPoint.listener.LocalEndpoint).Port;
endPoint.Port = ((IPEndPoint)endPoint.Listener.LocalEndpoint).Port;
// accept clients asynchronously
endPoint.listener.BeginAcceptTcpClient(OnAcceptConnection, endPoint);
endPoint.Listener.BeginAcceptTcpClient(OnAcceptConnection, endPoint);
}
/// <summary>
......@@ -505,9 +505,9 @@ namespace Titanium.Web.Proxy
/// <param name="endPoint"></param>
private void QuitListen(ProxyEndPoint endPoint)
{
endPoint.listener.Stop();
endPoint.listener.Server.Close();
endPoint.listener.Server.Dispose();
endPoint.Listener.Stop();
endPoint.Listener.Server.Close();
endPoint.Listener.Server.Dispose();
}
/// <summary>
......@@ -541,7 +541,7 @@ namespace Titanium.Web.Proxy
try
{
//based on end point type call appropriate request handlers
tcpClient = endPoint.listener.EndAcceptTcpClient(asyn);
tcpClient = endPoint.Listener.EndAcceptTcpClient(asyn);
}
catch (ObjectDisposedException)
{
......@@ -595,7 +595,7 @@ namespace Titanium.Web.Proxy
}
// Get the listener that handles the client request.
endPoint.listener.BeginAcceptTcpClient(OnAcceptConnection, endPoint);
endPoint.Listener.BeginAcceptTcpClient(OnAcceptConnection, endPoint);
}
/// <summary>
......
......@@ -72,8 +72,17 @@ namespace Titanium.Web.Proxy
}
//filter out excluded host names
var excluded = endPoint.ExcludedHttpsHostNameRegex != null
&& endPoint.ExcludedHttpsHostNameRegex.Any(x => Regex.IsMatch(httpRemoteUri.Host, x));
bool excluded = false;
if (endPoint.ExcludedHttpsHostNameRegex != null)
{
excluded = endPoint.ExcludedHttpsHostNameRegex.Any(x => Regex.IsMatch(httpRemoteUri.Host, x));
}
if (endPoint.IncludedHttpsHostNameRegex != null)
{
excluded = !endPoint.IncludedHttpsHostNameRegex.Any(x => Regex.IsMatch(httpRemoteUri.Host, x));
}
List<HttpHeader> connectRequestHeaders = null;
......@@ -212,7 +221,7 @@ namespace Titanium.Web.Proxy
endPoint.EnableSsl ? endPoint.GenericCertificateName : null, endPoint, null);
}
private async Task HandleHttpSessionRequestInternal(TcpConnection connection, SessionEventArgs args, ExternalProxy customUpStreamHttpProxy, ExternalProxy customUpStreamHttpsProxy, bool CloseConnection)
private async Task HandleHttpSessionRequestInternal(TcpConnection connection, SessionEventArgs args, ExternalProxy customUpStreamHttpProxy, ExternalProxy customUpStreamHttpsProxy, bool closeConnection)
{
try
{
......@@ -331,7 +340,7 @@ namespace Titanium.Web.Proxy
return;
}
if (CloseConnection)
if (closeConnection)
{
//dispose
connection?.Dispose();
......
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