Skip to content
This repository was archived by the owner on Jul 9, 2023. It is now read-only.
Merged

Beta #240

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class SessionEventArgs : EventArgs, IDisposable
/// <summary>
/// Holds a reference to proxy response handler method
/// </summary>
private readonly Func<SessionEventArgs, Task> httpResponseHandler;
private Func<SessionEventArgs, Task> httpResponseHandler;

/// <summary>
/// Holds a reference to client
Expand Down Expand Up @@ -522,6 +522,10 @@ public async Task Respond(Response response)
/// </summary>
public void Dispose()
{
httpResponseHandler = null;
CustomUpStreamHttpProxyUsed = null;
CustomUpStreamHttpsProxyUsed = null;

WebSession.Dispose();
}
}
Expand Down
10 changes: 3 additions & 7 deletions Titanium.Web.Proxy/Http/HttpWebClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,14 +214,10 @@ internal async Task ReceiveResponse()
/// </summary>
public void Dispose()
{
//not really needed since GC will collect it
//but just to be on safe side
Request.RequestBody = null;
Response.ResponseBody = null;

Request.RequestBodyString = null;
Response.ResponseBodyString = null;
ConnectHeaders = null;

Request.Dispose();
Response.Dispose();
}
}
}
17 changes: 16 additions & 1 deletion Titanium.Web.Proxy/Http/Request.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// A HTTP(S) request object
/// </summary>
public class Request
public class Request : IDisposable
{
/// <summary>
/// Request Method
Expand Down Expand Up @@ -294,5 +294,20 @@ public Request()
RequestHeaders = new Dictionary<string, HttpHeader>(StringComparer.OrdinalIgnoreCase);
NonUniqueRequestHeaders = new Dictionary<string, List<HttpHeader>>(StringComparer.OrdinalIgnoreCase);
}

/// <summary>
/// Dispose off
/// </summary>
public void Dispose()
{
//not really needed since GC will collect it
//but just to be on safe side

RequestHeaders = null;
NonUniqueRequestHeaders = null;

RequestBody = null;
RequestBody = null;
}
}
}
17 changes: 16 additions & 1 deletion Titanium.Web.Proxy/Http/Response.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// Http(s) response object
/// </summary>
public class Response
public class Response : IDisposable
{
/// <summary>
/// Response Status Code.
Expand Down Expand Up @@ -234,5 +234,20 @@ public Response()
ResponseHeaders = new Dictionary<string, HttpHeader>(StringComparer.OrdinalIgnoreCase);
NonUniqueResponseHeaders = new Dictionary<string, List<HttpHeader>>(StringComparer.OrdinalIgnoreCase);
}

/// <summary>
/// Dispose off
/// </summary>
public void Dispose()
{
//not really needed since GC will collect it
//but just to be on safe side

ResponseHeaders = null;
NonUniqueResponseHeaders = null;

ResponseBody = null;
ResponseBodyString = null;
}
}
}
101 changes: 93 additions & 8 deletions Titanium.Web.Proxy/Network/CertificateManager.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
Expand Down Expand Up @@ -30,7 +31,7 @@ public enum CertificateEngine
/// <summary>
/// A class to manage SSL certificates used by this proxy server
/// </summary>
public class CertificateManager : IDisposable
public sealed class CertificateManager : IDisposable
{
internal CertificateEngine Engine
{
Expand Down Expand Up @@ -147,7 +148,7 @@ private string GetRootCertificatePath()
return fileName;
}

internal X509Certificate2 LoadRootCertificate()
private X509Certificate2 LoadRootCertificate()
{
var fileName = GetRootCertificatePath();
if (!File.Exists(fileName)) return null;
Expand Down Expand Up @@ -218,6 +219,51 @@ public void TrustRootCertificate()
TrustRootCertificate(StoreLocation.LocalMachine);
}

/// <summary>
/// Puts the certificate to the local machine's certificate store.
/// Needs elevated permission. Works only on Windows.
/// </summary>
/// <returns></returns>
public bool TrustRootCertificateAsAdministrator()
{
if (RunTime.IsRunningOnMono())
{
return false;
}

var fileName = Path.GetTempFileName();
File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12));

var info = new ProcessStartInfo
{
FileName = "certutil.exe",
Arguments = "-importPFX -p \"\" -f \"" + fileName + "\"",
CreateNoWindow = true,
UseShellExecute = true,
Verb = "runas",
ErrorDialog = false,
};

try
{
var process = Process.Start(info);
if (process == null)
{
return false;
}

process.WaitForExit();

File.Delete(fileName);
}
catch
{
return false;
}

return true;
}

/// <summary>
/// Removes the trusted certificates.
/// </summary>
Expand All @@ -230,13 +276,49 @@ public void RemoveTrustedRootCertificates()
RemoveTrustedRootCertificates(StoreLocation.LocalMachine);
}

/// <summary>
/// Determines whether the root certificate is trusted.
/// </summary>
public bool IsRootCertificateTrusted()
{
return FindRootCertificate(StoreLocation.CurrentUser) || IsRootCertificateMachineTrusted();
}

/// <summary>
/// Determines whether the root certificate is machine trusted.
/// </summary>
public bool IsRootCertificateMachineTrusted()
{
return FindRootCertificate(StoreLocation.LocalMachine);
}

private bool FindRootCertificate(StoreLocation storeLocation)
{
string value = $"{RootCertificate.Issuer}";
return FindCertificates(StoreName.Root, storeLocation, value).Count > 0;
}

private X509Certificate2Collection FindCertificates(StoreName storeName, StoreLocation storeLocation, string findValue)
{
X509Store x509Store = new X509Store(storeName, storeLocation);
try
{
x509Store.Open(OpenFlags.OpenExistingOnly);
return x509Store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, findValue, false);
}
finally
{
x509Store.Close();
}
}

/// <summary>
/// Create an SSL certificate
/// </summary>
/// <param name="certificateName"></param>
/// <param name="isRootCertificate"></param>
/// <returns></returns>
internal virtual X509Certificate2 CreateCertificate(string certificateName, bool isRootCertificate)
internal X509Certificate2 CreateCertificate(string certificateName, bool isRootCertificate)
{
if (certificateCache.ContainsKey(certificateName))
{
Expand Down Expand Up @@ -317,7 +399,7 @@ internal async void ClearIdleCertificates(int certificateCacheTimeOutMinutes)
/// </summary>
/// <param name="storeLocation"></param>
/// <returns></returns>
internal void TrustRootCertificate(StoreLocation storeLocation)
private void TrustRootCertificate(StoreLocation storeLocation)
{
if (RootCertificate == null)
{
Expand All @@ -328,7 +410,7 @@ internal void TrustRootCertificate(StoreLocation storeLocation)
return;
}

X509Store x509RootStore = new X509Store(StoreName.Root, storeLocation);
var x509RootStore = new X509Store(StoreName.Root, storeLocation);
var x509PersonalStore = new X509Store(StoreName.My, storeLocation);

try
Expand Down Expand Up @@ -357,7 +439,7 @@ internal void TrustRootCertificate(StoreLocation storeLocation)
/// </summary>
/// <param name="storeLocation"></param>
/// <returns></returns>
internal void RemoveTrustedRootCertificates(StoreLocation storeLocation)
private void RemoveTrustedRootCertificates(StoreLocation storeLocation)
{
if (RootCertificate == null)
{
Expand All @@ -368,7 +450,7 @@ internal void RemoveTrustedRootCertificates(StoreLocation storeLocation)
return;
}

X509Store x509RootStore = new X509Store(StoreName.Root, storeLocation);
var x509RootStore = new X509Store(StoreName.Root, storeLocation);
var x509PersonalStore = new X509Store(StoreName.My, storeLocation);

try
Expand All @@ -382,7 +464,7 @@ internal void RemoveTrustedRootCertificates(StoreLocation storeLocation)
catch (Exception e)
{
exceptionFunc(
new Exception("Failed to make system trust root certificate "
new Exception("Failed to remove root certificate trust "
+ $" for {storeLocation} store location. You may need admin rights.", e));
}
finally
Expand All @@ -392,6 +474,9 @@ internal void RemoveTrustedRootCertificates(StoreLocation storeLocation)
}
}

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
}
Expand Down
41 changes: 0 additions & 41 deletions Titanium.Web.Proxy/ProxyServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -647,46 +647,5 @@ private void QuitListen(ProxyEndPoint endPoint)
endPoint.Listener.Server.Close();
endPoint.Listener.Server.Dispose();
}

/// <summary>
/// Invocator for BeforeRequest event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void OnBeforeRequest(object sender, SessionEventArgs e)
{
BeforeRequest?.Invoke(sender, e);
}

/// <summary>
/// Invocator for BeforeResponse event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <returns></returns>
protected virtual void OnBeforeResponse(object sender, SessionEventArgs e)
{
BeforeResponse?.Invoke(sender, e);
}

/// <summary>
/// Invocator for ServerCertificateValidationCallback event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void OnServerCertificateValidationCallback(object sender, CertificateValidationEventArgs e)
{
ServerCertificateValidationCallback?.Invoke(sender, e);
}

/// <summary>
/// Invocator for ClientCertifcateSelectionCallback event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void OnClientCertificateSelectionCallback(object sender, CertificateSelectionEventArgs e)
{
ClientCertificateSelectionCallback?.Invoke(sender, e);
}
}
}
Loading