Commit 6a66e7b1 authored by Jehonathan Thomas's avatar Jehonathan Thomas Committed by GitHub

Merge pull request #240 from justcoding121/develop

Beta
parents 9afb81c6 37b14243
......@@ -30,7 +30,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <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
......@@ -522,6 +522,10 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary>
public void Dispose()
{
httpResponseHandler = null;
CustomUpStreamHttpProxyUsed = null;
CustomUpStreamHttpsProxyUsed = null;
WebSession.Dispose();
}
}
......
......@@ -214,14 +214,10 @@ namespace Titanium.Web.Proxy.Http
/// </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();
}
}
}
......@@ -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
......@@ -294,5 +294,20 @@ namespace Titanium.Web.Proxy.Http
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;
}
}
}
......@@ -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.
......@@ -234,5 +234,20 @@ namespace Titanium.Web.Proxy.Http
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;
}
}
}
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
......@@ -30,7 +31,7 @@ namespace Titanium.Web.Proxy.Network
/// <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
{
......@@ -147,7 +148,7 @@ namespace Titanium.Web.Proxy.Network
return fileName;
}
internal X509Certificate2 LoadRootCertificate()
private X509Certificate2 LoadRootCertificate()
{
var fileName = GetRootCertificatePath();
if (!File.Exists(fileName)) return null;
......@@ -218,6 +219,51 @@ namespace Titanium.Web.Proxy.Network
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>
......@@ -230,13 +276,49 @@ namespace Titanium.Web.Proxy.Network
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))
{
......@@ -317,7 +399,7 @@ namespace Titanium.Web.Proxy.Network
/// </summary>
/// <param name="storeLocation"></param>
/// <returns></returns>
internal void TrustRootCertificate(StoreLocation storeLocation)
private void TrustRootCertificate(StoreLocation storeLocation)
{
if (RootCertificate == null)
{
......@@ -328,7 +410,7 @@ namespace Titanium.Web.Proxy.Network
return;
}
X509Store x509RootStore = new X509Store(StoreName.Root, storeLocation);
var x509RootStore = new X509Store(StoreName.Root, storeLocation);
var x509PersonalStore = new X509Store(StoreName.My, storeLocation);
try
......@@ -357,7 +439,7 @@ namespace Titanium.Web.Proxy.Network
/// </summary>
/// <param name="storeLocation"></param>
/// <returns></returns>
internal void RemoveTrustedRootCertificates(StoreLocation storeLocation)
private void RemoveTrustedRootCertificates(StoreLocation storeLocation)
{
if (RootCertificate == null)
{
......@@ -368,7 +450,7 @@ namespace Titanium.Web.Proxy.Network
return;
}
X509Store x509RootStore = new X509Store(StoreName.Root, storeLocation);
var x509RootStore = new X509Store(StoreName.Root, storeLocation);
var x509PersonalStore = new X509Store(StoreName.My, storeLocation);
try
......@@ -382,7 +464,7 @@ namespace Titanium.Web.Proxy.Network
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
......@@ -392,6 +474,9 @@ namespace Titanium.Web.Proxy.Network
}
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
}
......
......@@ -647,46 +647,5 @@ namespace Titanium.Web.Proxy
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);
}
}
}
This diff is collapsed.
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