Unverified Commit 6149ed65 authored by honfika's avatar honfika Committed by GitHub

Merge pull request #722 from justcoding121/master

beta
parents 500ceade 6db82ba8
......@@ -15,6 +15,7 @@ Kindly report only issues/bugs here. For programming help or questions use [Stac
* View/modify/redirect/block requests and responses
* Supports mutual SSL authentication, proxy authentication & automatic upstream proxy detection
* Kerberos/NTLM authentication over HTTP protocols for windows domain
* SOCKS4/5 Proxy support
### Installation
Install by [nuget](https://www.nuget.org/packages/Titanium.Web.Proxy)
......@@ -29,21 +30,21 @@ For stable releases on [stable branch](https://github.com/justcoding121/Titanium
Supports
* .Net Standard 2.0 or above
* .Net Framework 4.6.1 or above
* .NET Standard 2.0 or above
* .NET Framework 4.5 or above
### Development environment
#### Windows
* Visual Studio Code as IDE for .NET core
* Visual Studio 2017/2019 as IDE for .NET framework/.NET core
* Visual Studio Code as IDE for .NET Core
* Visual Studio 2019 as IDE for .NET Framework/.NET Core
#### Mac OS
* Visual Studio Code as IDE for .NET core
* Visual Studio 2017 as IDE for Mono
* Visual Studio Code as IDE for .NET Core
* Visual Studio 2019 as IDE for Mono
#### Linux
* Visual Studio Code as IDE for .NET core
* Visual Studio Code as IDE for .NET Core
* Mono develop as IDE for Mono
### Usage
......@@ -191,7 +192,7 @@ public async Task OnResponse(object sender, SessionEventArgs e)
{
if (e.HttpClient.Response.ResponseStatusCode == "200")
{
if (e.HttpClient.Response.ContentType!=null && e.HttpClient.Response.ContentType.Trim().ToLower().Contains("text/html"))
if (e.HttpClient.Response.ContentType != null && e.HttpClient.Response.ContentType.Trim().ToLower().Contains("text/html"))
{
byte[] bodyBytes = await e.GetResponseBody();
await e.SetResponseBody(bodyBytes);
......@@ -202,7 +203,7 @@ public async Task OnResponse(object sender, SessionEventArgs e)
}
}
if (e.UserData!=null)
if (e.UserData != null)
{
// access request from UserData property where we stored it in RequestHandler
var request = (Request)e.UserData;
......@@ -216,14 +217,14 @@ public Task OnCertificateValidation(object sender, CertificateValidationEventArg
if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
e.IsValid = true;
return Task.FromResult(0);
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.FromResult(0);
return Task.CompletedTask;
}
```
### Note to contributors
......
......@@ -108,6 +108,10 @@
Default.</p>
</td>
</tr>
<tr>
<td id="Titanium_Web_Proxy_Network_CertificateEngine_BouncyCastleFast">BouncyCastleFast</td>
<td></td>
</tr>
<tr>
<td id="Titanium_Web_Proxy_Network_CertificateEngine_DefaultWindows">DefaultWindows</td>
<td><p>Uses Windows Certification Generation API and only valid in Windows OS.
......
......@@ -242,7 +242,7 @@
"api/Titanium.Web.Proxy.Network.CertificateEngine.html": {
"href": "api/Titanium.Web.Proxy.Network.CertificateEngine.html",
"title": "Enum CertificateEngine | Titanium Web Proxy",
"keywords": "Enum CertificateEngine Certificate Engine option. Namespace : Titanium.Web.Proxy.Network Assembly : Titanium.Web.Proxy.dll Syntax public enum CertificateEngine Fields Name Description BouncyCastle Uses BouncyCastle 3rd party library. Default. DefaultWindows Uses Windows Certification Generation API and only valid in Windows OS. Observed to be faster than BouncyCastle. Bug #468 Reported."
"keywords": "Enum CertificateEngine Certificate Engine option. Namespace : Titanium.Web.Proxy.Network Assembly : Titanium.Web.Proxy.dll Syntax public enum CertificateEngine Fields Name Description BouncyCastle Uses BouncyCastle 3rd party library. Default. BouncyCastleFast DefaultWindows Uses Windows Certification Generation API and only valid in Windows OS. Observed to be faster than BouncyCastle. Bug #468 Reported."
},
"api/Titanium.Web.Proxy.Network.CertificateManager.html": {
"href": "api/Titanium.Web.Proxy.Network.CertificateManager.html",
......
......@@ -2913,6 +2913,12 @@ references:
commentId: F:Titanium.Web.Proxy.Network.CertificateEngine.BouncyCastle
fullName: Titanium.Web.Proxy.Network.CertificateEngine.BouncyCastle
nameWithType: CertificateEngine.BouncyCastle
- uid: Titanium.Web.Proxy.Network.CertificateEngine.BouncyCastleFast
name: BouncyCastleFast
href: api/Titanium.Web.Proxy.Network.CertificateEngine.html#Titanium_Web_Proxy_Network_CertificateEngine_BouncyCastleFast
commentId: F:Titanium.Web.Proxy.Network.CertificateEngine.BouncyCastleFast
fullName: Titanium.Web.Proxy.Network.CertificateEngine.BouncyCastleFast
nameWithType: CertificateEngine.BouncyCastleFast
- uid: Titanium.Web.Proxy.Network.CertificateEngine.DefaultWindows
name: DefaultWindows
href: api/Titanium.Web.Proxy.Network.CertificateEngine.html#Titanium_Web_Proxy_Network_CertificateEngine_DefaultWindows
......
......@@ -44,6 +44,10 @@ namespace Titanium.Web.Proxy.Examples.Basic
};
proxyServer.ForwardToUpstreamGateway = true;
proxyServer.CertificateManager.SaveFakeCertificates = true;
//proxyServer.ProxyBasicAuthenticateFunc = async (args, userName, password) =>
//{
// return true;
//};
// this is just to show the functionality, provided implementations use junk value
//proxyServer.GetCustomUpStreamProxyFunc = onGetCustomUpStreamProxyFunc;
......@@ -94,8 +98,11 @@ namespace Titanium.Web.Proxy.Examples.Basic
//proxyServer.UpStreamHttpsProxy = new ExternalProxy("localhost", 8888);
// SOCKS proxy
//proxyServer.UpStreamHttpProxy = new ExternalProxy("46.63.0.17", 4145) { ProxyType = ExternalProxyType.Socks4 };
//proxyServer.UpStreamHttpsProxy = new ExternalProxy("46.63.0.17", 4145) { ProxyType = ExternalProxyType.Socks4 };
//proxyServer.UpStreamHttpProxy = new ExternalProxy("127.0.0.1", 1080)
// { ProxyType = ExternalProxyType.Socks5, UserName = "User1", Password = "Pass" };
//proxyServer.UpStreamHttpsProxy = new ExternalProxy("127.0.0.1", 1080)
// { ProxyType = ExternalProxyType.Socks5, UserName = "User1", Password = "Pass" };
//var socksEndPoint = new SocksProxyEndPoint(IPAddress.Any, 1080, true)
//{
......@@ -167,6 +174,12 @@ namespace Titanium.Web.Proxy.Examples.Basic
e.GetState().PipelineInfo.AppendLine(nameof(onBeforeTunnelConnectRequest) + ":" + hostname);
await writeToConsole("Tunnel to: " + hostname);
var clientLocalIp = e.ClientLocalEndPoint.Address;
if (!clientLocalIp.Equals(IPAddress.Loopback) && !clientLocalIp.Equals(IPAddress.IPv6Loopback))
{
e.HttpClient.UpStreamEndPoint = new IPEndPoint(clientLocalIp, 0);
}
if (hostname.Contains("dropbox.com"))
{
// Exclude Https addresses you don't want to proxy
......@@ -212,7 +225,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
{
e.GetState().PipelineInfo.AppendLine(nameof(onBeforeTunnelConnectResponse) + ":" + e.HttpClient.Request.RequestUri);
return Task.FromResult(false);
return Task.CompletedTask;
}
// intercept & cancel redirect or update requests
......@@ -356,7 +369,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
e.IsValid = true;
}
return Task.FromResult(0);
return Task.CompletedTask;
}
/// <summary>
......@@ -370,7 +383,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
// set e.clientCertificate to override
return Task.FromResult(0);
return Task.CompletedTask;
}
private async Task writeToConsole(string message, ConsoleColor? consoleColor = null)
......
......@@ -21,7 +21,7 @@ namespace WindowsServiceExample
{
// we do all this in here so we can reload settings with a simple restart
_proxyServerInstance = new ProxyServer();
_proxyServerInstance = new ProxyServer(false);
if (Properties.Settings.Default.ListeningPort <= 0 ||
Properties.Settings.Default.ListeningPort > 65535)
......
......@@ -53,7 +53,7 @@ namespace Titanium.Web.Proxy.EventArguments
{
BufferPool = server.BufferPool;
ExceptionFunc = server.ExceptionFunc;
TimeLine["Session Created"] = DateTime.Now;
TimeLine["Session Created"] = DateTime.UtcNow;
CancellationTokenSource = cancellationTokenSource;
......
......@@ -92,7 +92,7 @@ namespace Titanium.Web.Proxy.Http
/// <param name="serverConnection">Instance of <see cref="TcpServerConnection" /></param>
internal void SetConnection(TcpServerConnection serverConnection)
{
serverConnection.LastAccess = DateTime.Now;
serverConnection.LastAccess = DateTime.UtcNow;
connection = serverConnection;
}
......
......@@ -44,7 +44,6 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// Makes the certificate.
/// </summary>
/// <param name="sSubjectCn">The s subject cn.</param>
/// <param name="isRoot">if set to <c>true</c> [is root].</param>
/// <param name="signingCert">The signing cert.</param>
/// <returns>X509Certificate2 instance.</returns>
public X509Certificate2 MakeCertificate(string sSubjectCn, X509Certificate2? signingCert = null)
......
......@@ -105,7 +105,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
// KeyLength
const int keyLength = 2048;
var now = DateTime.Now;
var now = DateTime.UtcNow;
var graceTime = now.AddDays(graceDays);
var certificate = makeCertificate(sSubjectCN, fullSubject, keyLength, hashAlgo, graceTime,
now.AddDays(validDays), signingCertificate);
......
......@@ -24,6 +24,8 @@ namespace Titanium.Web.Proxy.Network
/// </summary>
BouncyCastle = 0,
BouncyCastleFast = 2,
/// <summary>
/// Uses Windows Certification Generation API and only valid in Windows OS.
/// Observed to be faster than BouncyCastle.
......@@ -68,9 +70,19 @@ namespace Titanium.Web.Proxy.Network
{
if (certEngineValue == null)
{
certEngineValue = engine == CertificateEngine.BouncyCastle
? (ICertificateMaker)new BCCertificateMaker(ExceptionFunc)
: new WinCertificateMaker(ExceptionFunc);
switch (engine)
{
case CertificateEngine.BouncyCastle:
certEngineValue = new BCCertificateMaker(ExceptionFunc);
break;
case CertificateEngine.BouncyCastleFast:
certEngineValue = new BCCertificateMakerFast(ExceptionFunc);
break;
case CertificateEngine.DefaultWindows:
default:
certEngineValue = new WinCertificateMaker(ExceptionFunc);
break;
}
}
return certEngineValue;
......@@ -459,7 +471,7 @@ namespace Titanium.Web.Proxy.Network
// check in cache first
if (cachedCertificates.TryGetValue(certificateName, out var cached))
{
cached.LastAccess = DateTime.Now;
cached.LastAccess = DateTime.UtcNow;
return cached.Certificate;
}
......@@ -498,7 +510,7 @@ namespace Titanium.Web.Proxy.Network
var cancellationToken = clearCertificatesTokenSource.Token;
while (!cancellationToken.IsCancellationRequested)
{
var cutOff = DateTime.Now.AddMinutes(-CertificateCacheTimeOutMinutes);
var cutOff = DateTime.UtcNow.AddMinutes(-CertificateCacheTimeOutMinutes);
var outdated = cachedCertificates.Where(x => x.Value.LastAccess < cutOff).ToList();
......
......@@ -241,7 +241,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
if (cache.TryGetValue(cacheKey, out var existingConnections))
{
// +3 seconds for potential delay after getting connection
var cutOff = DateTime.Now.AddSeconds(-proxyServer.ConnectionTimeOutSeconds + 3);
var cutOff = DateTime.UtcNow.AddSeconds(-proxyServer.ConnectionTimeOutSeconds + 3);
while (existingConnections.Count > 0)
{
if (existingConnections.TryDequeue(out var recentConnection))
......@@ -350,7 +350,7 @@ retry:
if (sessionArgs != null)
{
sessionArgs.TimeLine["Dns Resolved"] = DateTime.Now;
sessionArgs.TimeLine["Dns Resolved"] = DateTime.UtcNow;
}
Array.Sort(ipAddresses, (x, y) => x.AddressFamily.CompareTo(y.AddressFamily));
......@@ -458,7 +458,7 @@ retry:
if (newUpstreamProxy != null)
{
sessionArgs.CustomUpStreamProxyUsed = newUpstreamProxy;
sessionArgs.TimeLine["Retrying Upstream Proxy Connection"] = DateTime.Now;
sessionArgs.TimeLine["Retrying Upstream Proxy Connection"] = DateTime.UtcNow;
return await createServerConnection(remoteHostName, remotePort, httpVersion, isHttps, sslProtocol, applicationProtocols, isConnect, proxyServer, sessionArgs, upStreamEndPoint, externalProxy, cacheKey, cancellationToken);
}
}
......@@ -468,7 +468,7 @@ retry:
if (sessionArgs != null)
{
sessionArgs.TimeLine["Connection Established"] = DateTime.Now;
sessionArgs.TimeLine["Connection Established"] = DateTime.UtcNow;
}
await proxyServer.InvokeServerConnectionCreateEvent(tcpServerSocket);
......@@ -532,7 +532,7 @@ retry:
if (sessionArgs != null)
{
sessionArgs.TimeLine["HTTPS Established"] = DateTime.Now;
sessionArgs.TimeLine["HTTPS Established"] = DateTime.UtcNow;
}
}
}
......@@ -570,7 +570,7 @@ retry:
return;
}
connection.LastAccess = DateTime.Now;
connection.LastAccess = DateTime.UtcNow;
try
{
......@@ -634,7 +634,7 @@ retry:
{
try
{
var cutOff = DateTime.Now.AddSeconds(-Server.ConnectionTimeOutSeconds);
var cutOff = DateTime.UtcNow.AddSeconds(-Server.ConnectionTimeOutSeconds);
foreach (var item in cache)
{
var queue = item.Value;
......
......@@ -20,7 +20,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
Version version, IExternalProxy? upStreamProxy, IPEndPoint? upStreamEndPoint, string cacheKey)
{
TcpSocket = tcpSocket;
LastAccess = DateTime.Now;
LastAccess = DateTime.UtcNow;
this.proxyServer = proxyServer;
this.proxyServer.UpdateServerConnectionCount(true);
Stream = stream;
......
......@@ -43,7 +43,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
Credentials = new Common.SecurityHandle(0);
Context = new Common.SecurityHandle(0);
LastSeen = DateTime.Now;
LastSeen = DateTime.UtcNow;
AuthState = WinAuthState.UNAUTHORIZED;
}
......@@ -56,7 +56,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
internal void UpdatePresence()
{
LastSeen = DateTime.Now;
LastSeen = DateTime.UtcNow;
}
}
}
......@@ -279,7 +279,7 @@ namespace Titanium.Web.Proxy
// set the connection and send request headers
args.HttpClient.SetConnection(connection);
args.TimeLine["Connection Ready"] = DateTime.Now;
args.TimeLine["Connection Ready"] = DateTime.UtcNow;
if (args.HttpClient.Request.UpgradeToWebSocket)
{
......@@ -335,7 +335,7 @@ namespace Titanium.Web.Proxy
}
}
args.TimeLine["Request Sent"] = DateTime.Now;
args.TimeLine["Request Sent"] = DateTime.UtcNow;
// parse and send response
await handleHttpSessionResponse(args);
......@@ -374,7 +374,7 @@ namespace Titanium.Web.Proxy
/// <returns></returns>
private async Task onBeforeRequest(SessionEventArgs args)
{
args.TimeLine["Request Received"] = DateTime.Now;
args.TimeLine["Request Received"] = DateTime.UtcNow;
if (BeforeRequest != null)
{
......
......@@ -32,7 +32,7 @@ namespace Titanium.Web.Proxy
await args.HttpClient.ReceiveResponse(cancellationToken);
}
args.TimeLine["Response Received"] = DateTime.Now;
args.TimeLine["Response Received"] = DateTime.UtcNow;
var response = args.HttpClient.Response;
args.ReRequest = false;
......@@ -122,7 +122,7 @@ namespace Titanium.Web.Proxy
}
}
args.TimeLine["Response Sent"] = DateTime.Now;
args.TimeLine["Response Sent"] = DateTime.UtcNow;
}
/// <summary>
......
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