Commit aab7e422 authored by Honfika's avatar Honfika

Tunnel Connect events renamed, call the BeforeResponse event handlers before...

Tunnel Connect events renamed, call the BeforeResponse event handlers before sending the authentication failed response
parent 6b46f96f
......@@ -69,8 +69,8 @@ namespace Titanium.Web.Proxy.Examples.Basic
};
//Fired when a CONNECT request is received
explicitEndPoint.TunnelConnectRequest += OnTunnelConnectRequest;
explicitEndPoint.TunnelConnectResponse += OnTunnelConnectResponse;
explicitEndPoint.BeforeTunnelConnectRequest += OnBeforeTunnelConnectRequest;
explicitEndPoint.BeforeTunnelConnectResponse += OnBeforeTunnelConnectResponse;
//An explicit endpoint is where the client knows about the existence of a proxy
//So client sends request in a proxy friendly manner
......@@ -108,8 +108,8 @@ namespace Titanium.Web.Proxy.Examples.Basic
public void Stop()
{
explicitEndPoint.TunnelConnectRequest -= OnTunnelConnectRequest;
explicitEndPoint.TunnelConnectResponse -= OnTunnelConnectResponse;
explicitEndPoint.BeforeTunnelConnectRequest -= OnBeforeTunnelConnectRequest;
explicitEndPoint.BeforeTunnelConnectResponse -= OnBeforeTunnelConnectResponse;
proxyServer.BeforeRequest -= OnRequest;
proxyServer.BeforeResponse -= OnResponse;
......@@ -122,7 +122,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
//proxyServer.CertificateManager.RemoveTrustedRootCertificates();
}
private async Task OnTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
{
string hostname = e.WebSession.Request.RequestUri.Host;
Console.WriteLine("Tunnel to: " + hostname);
......@@ -136,7 +136,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
}
}
private async Task OnTunnelConnectResponse(object sender, TunnelConnectSessionEventArgs e)
private async Task OnBeforeTunnelConnectResponse(object sender, TunnelConnectSessionEventArgs e)
{
}
......
......@@ -102,8 +102,8 @@ namespace Titanium.Web.Proxy.Examples.Wpf
proxyServer.BeforeRequest += ProxyServer_BeforeRequest;
proxyServer.BeforeResponse += ProxyServer_BeforeResponse;
explicitEndPoint.TunnelConnectRequest += ProxyServer_TunnelConnectRequest;
explicitEndPoint.TunnelConnectResponse += ProxyServer_TunnelConnectResponse;
explicitEndPoint.BeforeTunnelConnectRequest += ProxyServer_BeforeTunnelConnectRequest;
explicitEndPoint.BeforeTunnelConnectResponse += ProxyServer_BeforeTunnelConnectResponse;
proxyServer.ClientConnectionCountChanged += delegate { Dispatcher.Invoke(() => { ClientConnectionCount = proxyServer.ClientConnectionCount; }); };
proxyServer.ServerConnectionCountChanged += delegate { Dispatcher.Invoke(() => { ServerConnectionCount = proxyServer.ServerConnectionCount; }); };
proxyServer.Start();
......@@ -113,7 +113,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
InitializeComponent();
}
private async Task ProxyServer_TunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
private async Task ProxyServer_BeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
{
await Dispatcher.InvokeAsync(() =>
{
......@@ -121,7 +121,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
});
}
private async Task ProxyServer_TunnelConnectResponse(object sender, SessionEventArgs e)
private async Task ProxyServer_BeforeTunnelConnectResponse(object sender, SessionEventArgs e)
{
await Dispatcher.InvokeAsync(() =>
{
......
......@@ -27,13 +27,13 @@ namespace Titanium.Web.Proxy.Models
/// Valid only for explicit endpoints
/// Set the <see cref="TunnelConnectSessionEventArgs.Excluded"/> property to true if this HTTP connect request should'nt be decrypted and instead be relayed
/// </summary>
public event AsyncEventHandler<TunnelConnectSessionEventArgs> TunnelConnectRequest;
public event AsyncEventHandler<TunnelConnectSessionEventArgs> BeforeTunnelConnectRequest;
/// <summary>
/// Intercept tunnel connect response
/// Valid only for explicit endpoints
/// </summary>
public event AsyncEventHandler<TunnelConnectSessionEventArgs> TunnelConnectResponse;
public event AsyncEventHandler<TunnelConnectSessionEventArgs> BeforeTunnelConnectResponse;
/// <summary>
/// Constructor.
......@@ -45,20 +45,20 @@ namespace Titanium.Web.Proxy.Models
{
}
internal async Task InvokeTunnectConnectRequest(ProxyServer proxyServer, TunnelConnectSessionEventArgs connectArgs, Action<Exception> exceptionFunc)
internal async Task InvokeBeforeTunnelConnectRequest(ProxyServer proxyServer, TunnelConnectSessionEventArgs connectArgs, Action<Exception> exceptionFunc)
{
if (TunnelConnectRequest != null)
if (BeforeTunnelConnectRequest != null)
{
await TunnelConnectRequest.InvokeAsync(proxyServer, connectArgs, exceptionFunc);
await BeforeTunnelConnectRequest.InvokeAsync(proxyServer, connectArgs, exceptionFunc);
}
}
internal async Task InvokeTunnectConnectResponse(ProxyServer proxyServer, TunnelConnectSessionEventArgs connectArgs, Action<Exception> exceptionFunc, bool isClientHello = false)
internal async Task InvokeBeforeTunnectConnectResponse(ProxyServer proxyServer, TunnelConnectSessionEventArgs connectArgs, Action<Exception> exceptionFunc, bool isClientHello = false)
{
if (TunnelConnectResponse != null)
if (BeforeTunnelConnectResponse != null)
{
connectArgs.IsHttpsConnect = isClientHello;
await TunnelConnectResponse.InvokeAsync(proxyServer, connectArgs, exceptionFunc);
await BeforeTunnelConnectResponse.InvokeAsync(proxyServer, connectArgs, exceptionFunc);
}
}
}
......
......@@ -196,7 +196,7 @@ namespace Titanium.Web.Proxy.Network
/// <param name="rootCertificateIssuerName">Name of root certificate issuer.</param>
/// <param name="userTrustRootCertificate"></param>
/// <param name="machineTrustRootCertificate">Note:setting machineTrustRootCertificate to true will force userTrustRootCertificate to true</param>
/// <param name="trustRootCertificateAsAdmin "></param>
/// <param name="trustRootCertificateAsAdmin"></param>
/// <param name="exceptionFunc"></param>
internal CertificateManager(string rootCertificateName, string rootCertificateIssuerName, bool userTrustRootCertificate, bool machineTrustRootCertificate, bool trustRootCertificateAsAdmin, Action < Exception> exceptionFunc)
{
......@@ -310,6 +310,7 @@ namespace Titanium.Web.Proxy.Network
/// <summary>
/// Make current machine trust the Root Certificate used by this proxy
/// </summary>
/// <param name="storeName"></param>
/// <param name="storeLocation"></param>
/// <returns></returns>
private void InstallCertificate(StoreName storeName, StoreLocation storeLocation)
......@@ -348,7 +349,9 @@ namespace Titanium.Web.Proxy.Network
/// <summary>
/// Remove the Root Certificate trust
/// </summary>
/// <param name="storeName"></param>
/// <param name="storeLocation"></param>
/// <param name="certificate"></param>
/// <returns></returns>
private void UninstallCertificate(StoreName storeName, StoreLocation storeLocation, X509Certificate2 certificate)
{
......
......@@ -15,7 +15,7 @@ namespace Titanium.Web.Proxy
{
public partial class ProxyServer
{
private async Task<bool> CheckAuthorization(HttpResponseWriter clientStreamWriter, SessionEventArgs session)
private async Task<bool> CheckAuthorization(SessionEventArgs session)
{
if (AuthenticateUserFunc == null)
{
......@@ -29,7 +29,7 @@ namespace Titanium.Web.Proxy
var header = httpHeaders.GetFirstHeader(KnownHeaders.ProxyAuthorization);
if (header == null)
{
session.WebSession.Response = await SendAuthentication407Response(clientStreamWriter, "Proxy Authentication Required");
session.WebSession.Response = SendAuthentication407Response("Proxy Authentication Required");
return false;
}
......@@ -37,7 +37,7 @@ namespace Titanium.Web.Proxy
if (headerValueParts.Length != 2 || !headerValueParts[0].EqualsIgnoreCase(KnownHeaders.ProxyAuthorizationBasic))
{
//Return not authorized
session.WebSession.Response = await SendAuthentication407Response(clientStreamWriter, "Proxy Authentication Invalid");
session.WebSession.Response = SendAuthentication407Response("Proxy Authentication Invalid");
return false;
}
......@@ -46,25 +46,32 @@ namespace Titanium.Web.Proxy
if (colonIndex == -1)
{
//Return not authorized
session.WebSession.Response = await SendAuthentication407Response(clientStreamWriter, "Proxy Authentication Invalid");
session.WebSession.Response = SendAuthentication407Response("Proxy Authentication Invalid");
return false;
}
string username = decoded.Substring(0, colonIndex);
string password = decoded.Substring(colonIndex + 1);
return await AuthenticateUserFunc(username, password);
bool authenticated = await AuthenticateUserFunc(username, password);
if (!authenticated)
{
//Return not authorized
session.WebSession.Response = SendAuthentication407Response("Proxy Authentication Invalid");
}
return authenticated;
}
catch (Exception e)
{
ExceptionFunc(new ProxyAuthorizationException("Error whilst authorizing request", e, httpHeaders));
//Return not authorized
session.WebSession.Response = await SendAuthentication407Response(clientStreamWriter, "Proxy Authentication Invalid");
session.WebSession.Response = SendAuthentication407Response("Proxy Authentication Invalid");
return false;
}
}
private async Task<Response> SendAuthentication407Response(HttpResponseWriter clientStreamWriter, string description)
private Response SendAuthentication407Response(string description)
{
var response = new Response
{
......@@ -77,7 +84,6 @@ namespace Titanium.Web.Proxy
response.Headers.AddHeader(KnownHeaders.ProxyConnection, KnownHeaders.ProxyConnectionClose);
response.Headers.FixProxyHeaders();
await clientStreamWriter.WriteResponseAsync(response);
return response;
}
}
......
......@@ -210,7 +210,7 @@ namespace Titanium.Web.Proxy
/// </summary>
/// <param name="userTrustRootCertificate"></param>
/// <param name="machineTrustRootCertificate">Note:setting machineTrustRootCertificate to true will force userTrustRootCertificate to true</param>
/// <param name="trustRootCertificateAsAdmin "></param>
/// <param name="trustRootCertificateAsAdmin"></param>
public ProxyServer(bool userTrustRootCertificate = true, bool machineTrustRootCertificate = false, bool trustRootCertificateAsAdmin = false) : this(null, null, userTrustRootCertificate, machineTrustRootCertificate, trustRootCertificateAsAdmin)
{
}
......@@ -222,7 +222,7 @@ namespace Titanium.Web.Proxy
/// <param name="rootCertificateIssuerName">Name of root certificate issuer.</param>
/// <param name="userTrustRootCertificate"></param>
/// <param name="machineTrustRootCertificate">Note:setting machineTrustRootCertificate to true will force userTrustRootCertificate to true</param>
/// <param name="trustRootCertificateAsAdmin "></param>
/// <param name="trustRootCertificateAsAdmin"></param>
public ProxyServer(string rootCertificateName, string rootCertificateIssuerName, bool userTrustRootCertificate = true, bool machineTrustRootCertificate = false, bool trustRootCertificateAsAdmin = false)
{
//default values
......@@ -660,6 +660,22 @@ namespace Titanium.Web.Proxy
endPoint.Listener.Server.Dispose();
}
private async Task InvokeBeforeRequest(SessionEventArgs args)
{
if (BeforeRequest != null)
{
await BeforeRequest.InvokeAsync(this, args, ExceptionFunc);
}
}
private async Task InvokeBeforeResponse(SessionEventArgs args)
{
if (BeforeResponse != null)
{
await BeforeResponse.InvokeAsync(this, args, ExceptionFunc);
}
}
internal void UpdateClientConnectionCount(bool increment)
{
if (increment)
......
......@@ -77,14 +77,17 @@ namespace Titanium.Web.Proxy
connectArgs.ProxyClient.TcpClient = tcpClient;
connectArgs.ProxyClient.ClientStream = clientStream;
await endPoint.InvokeTunnectConnectRequest(this, connectArgs, ExceptionFunc);
await endPoint.InvokeBeforeTunnelConnectRequest(this, connectArgs, ExceptionFunc);
//filter out excluded host names
bool excluded = connectArgs.Excluded;
if (await CheckAuthorization(clientStreamWriter, connectArgs) == false)
if (await CheckAuthorization(connectArgs) == false)
{
await endPoint.InvokeTunnectConnectResponse(this, connectArgs, ExceptionFunc);
await endPoint.InvokeBeforeTunnectConnectResponse(this, connectArgs, ExceptionFunc);
//send the response
await clientStreamWriter.WriteResponseAsync(connectArgs.WebSession.Response);
return;
}
......@@ -102,7 +105,7 @@ namespace Titanium.Web.Proxy
connectRequest.ClientHelloInfo = clientHelloInfo;
}
await endPoint.InvokeTunnectConnectResponse(this, connectArgs, ExceptionFunc, isClientHello);
await endPoint.InvokeBeforeTunnectConnectResponse(this, connectArgs, ExceptionFunc, isClientHello);
if (!excluded && isClientHello)
{
......@@ -352,8 +355,12 @@ namespace Titanium.Web.Proxy
args.ProxyClient.ClientStreamWriter = clientStreamWriter;
//proxy authorization check
if (!args.IsTransparent && httpsConnectHostname == null && await CheckAuthorization(clientStreamWriter, args) == false)
if (!args.IsTransparent && httpsConnectHostname == null && await CheckAuthorization(args) == false)
{
await InvokeBeforeResponse(args);
//send the response
await clientStreamWriter.WriteResponseAsync(args.WebSession.Response);
break;
}
......@@ -372,10 +379,7 @@ namespace Titanium.Web.Proxy
}
//If user requested interception do it
if (BeforeRequest != null)
{
await BeforeRequest.InvokeAsync(this, args, ExceptionFunc);
}
await InvokeBeforeRequest(args);
var response = args.WebSession.Response;
......@@ -428,9 +432,9 @@ namespace Titanium.Web.Proxy
}
//If user requested call back then do it
if (BeforeResponse != null && !args.WebSession.Response.ResponseLocked)
if (!args.WebSession.Response.ResponseLocked)
{
await BeforeResponse.InvokeAsync(this, args, ExceptionFunc);
await InvokeBeforeResponse(args);
}
await TcpHelper.SendRaw(clientStream, connection.Stream, BufferSize,
......
......@@ -35,10 +35,10 @@ namespace Titanium.Web.Proxy
args.ReRequest = false;
//If user requested call back then do it
if (BeforeResponse != null && !response.ResponseLocked)
//if user requested call back then do it
if (!response.ResponseLocked)
{
await BeforeResponse.InvokeAsync(this, args, ExceptionFunc);
await InvokeBeforeResponse(args);
}
//if user requested to send request again
......
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