137 lines
5.0 KiB
C#
137 lines
5.0 KiB
C#
using Serilog;
|
|
using System.Text.RegularExpressions;
|
|
using Titanium.Web.Proxy;
|
|
using Titanium.Web.Proxy.EventArguments;
|
|
using Titanium.Web.Proxy.Models;
|
|
|
|
namespace Elisa.GameServer;
|
|
|
|
public class ProxyControl
|
|
{
|
|
static readonly Regex HostFilter = new Regex("(.*).(girlfrontline\\.co\\.kr|ppgame\\.com|txwy\\.tw|sunborngame\\.com|aihelp\\.net).*");
|
|
static readonly Regex AWSFilter = new Regex(@"s3.*.amazonaws.com");
|
|
static readonly Regex DLlistFilter = new Regex(@"dl.listdl.com");
|
|
readonly string forwardIpAddress;
|
|
readonly ProxyServer proxyServer;
|
|
readonly ExplicitProxyEndPoint explicitEndPoint;
|
|
|
|
public ProxyControl(string forwardIpAddress, int port = 9000)
|
|
{
|
|
this.forwardIpAddress = forwardIpAddress;
|
|
proxyServer = new ProxyServer();
|
|
explicitEndPoint = new ExplicitProxyEndPoint(System.Net.IPAddress.Any, port, true);
|
|
|
|
proxyServer.BeforeRequest += OnRequest;
|
|
//Ssl handling
|
|
explicitEndPoint.BeforeTunnelConnectRequest += OnBeforeTunnelConnectRequest;
|
|
|
|
|
|
proxyServer.ServerCertificateValidationCallback += OnCertificateValidation;
|
|
proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection;
|
|
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
proxyServer.AddEndPoint(explicitEndPoint);
|
|
proxyServer.Start();
|
|
|
|
//proxyServer.SetAsSystemHttpProxy(explicitEndPoint);
|
|
//proxyServer.SetAsSystemHttpsProxy(explicitEndPoint);
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
proxyServer.BeforeRequest -= OnRequest;
|
|
//Ssl Handling
|
|
proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation;
|
|
proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection;
|
|
|
|
|
|
explicitEndPoint.BeforeTunnelConnectRequest -= OnBeforeTunnelConnectRequest;
|
|
//proxyServer.DisableAllSystemProxies();
|
|
proxyServer.Stop();
|
|
}
|
|
private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
|
|
{
|
|
string hostname = e.HttpClient.Request.RequestUri.Host;
|
|
|
|
//show the hostname
|
|
Log.Information($"Tunnel Connect Request for {hostname}");
|
|
//Forward to our domain --this doesn't work
|
|
|
|
if (HostFilter.IsMatch(hostname) || AWSFilter.IsMatch(hostname) || DLlistFilter.IsMatch(hostname))
|
|
{
|
|
Log.Information($"Forwarding tunnel connect request for {hostname} to {forwardIpAddress}");
|
|
e.DecryptSsl = true;
|
|
e.HttpClient.Request.RequestUri = new Uri("https://" + forwardIpAddress + e.HttpClient.Request.RequestUri.PathAndQuery, UriKind.Absolute);
|
|
|
|
return;
|
|
}
|
|
|
|
if (hostname.Contains("gf-passport.sunborngame.com"))
|
|
{
|
|
// Exclude Https addresses you don't want to proxy
|
|
// Useful for clients that use certificate pinning
|
|
// for example dropbox.com
|
|
e.DecryptSsl = false;
|
|
}
|
|
|
|
}
|
|
public Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)
|
|
{
|
|
// set IsValid to true/false based on Certificate Errors
|
|
//if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
|
|
e.IsValid = true;
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
// Allows overriding default client certificate selection logic during mutual authentication
|
|
public Task OnCertificateSelection(object sender, CertificateSelectionEventArgs e)
|
|
{
|
|
// set e.clientCertificate to override
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private async Task OnRequest(object sender, SessionEventArgs e)
|
|
{
|
|
if (e.IsHttps)
|
|
{
|
|
Log.Information("HTTPS request detected, skipping");
|
|
return;
|
|
}
|
|
Uri requestUri = e.HttpClient.Request.RequestUri;
|
|
if (HostFilter.IsMatch(requestUri.Host))
|
|
{
|
|
Log.Information($"Forwarding request for {requestUri} to {forwardIpAddress}");
|
|
|
|
Uri newUri = new Uri("http://" + forwardIpAddress + requestUri.PathAndQuery, UriKind.Absolute);
|
|
Log.Information($"Forwarded request to {newUri}");
|
|
|
|
e.HttpClient.Request.RequestUri = newUri;
|
|
|
|
// Bubble it out to user
|
|
}
|
|
//Test for aws
|
|
else if (AWSFilter.IsMatch(requestUri.Host))
|
|
{
|
|
Log.Information($"Forwarding AWS request for {requestUri} to {forwardIpAddress}");
|
|
|
|
Uri newUri = new Uri("http://" + forwardIpAddress + requestUri.PathAndQuery, UriKind.Absolute);
|
|
Log.Information($"Forwarded request to {newUri}");
|
|
|
|
e.HttpClient.Request.RequestUri = newUri;
|
|
}
|
|
else if (DLlistFilter.IsMatch(requestUri.Host))
|
|
{
|
|
Log.Information($"Forwarding DLList request for {requestUri} to {forwardIpAddress}");
|
|
|
|
Uri newUri = new Uri("http://" + forwardIpAddress + requestUri.PathAndQuery, UriKind.Absolute);
|
|
Log.Information($"Forwarded request to {newUri}");
|
|
|
|
e.HttpClient.Request.RequestUri = newUri;
|
|
}
|
|
}
|
|
}
|