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 ...@@ -30,7 +30,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary> /// <summary>
/// Holds a reference to proxy response handler method /// Holds a reference to proxy response handler method
/// </summary> /// </summary>
private readonly Func<SessionEventArgs, Task> httpResponseHandler; private Func<SessionEventArgs, Task> httpResponseHandler;
/// <summary> /// <summary>
/// Holds a reference to client /// Holds a reference to client
...@@ -522,6 +522,10 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -522,6 +522,10 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary> /// </summary>
public void Dispose() public void Dispose()
{ {
httpResponseHandler = null;
CustomUpStreamHttpProxyUsed = null;
CustomUpStreamHttpsProxyUsed = null;
WebSession.Dispose(); WebSession.Dispose();
} }
} }
......
...@@ -214,14 +214,10 @@ namespace Titanium.Web.Proxy.Http ...@@ -214,14 +214,10 @@ namespace Titanium.Web.Proxy.Http
/// </summary> /// </summary>
public void Dispose() public void Dispose()
{ {
//not really needed since GC will collect it ConnectHeaders = null;
//but just to be on safe side
Request.RequestBody = null;
Response.ResponseBody = null;
Request.RequestBodyString = null;
Response.ResponseBodyString = null;
Request.Dispose();
Response.Dispose();
} }
} }
} }
...@@ -9,7 +9,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -9,7 +9,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary> /// <summary>
/// A HTTP(S) request object /// A HTTP(S) request object
/// </summary> /// </summary>
public class Request public class Request : IDisposable
{ {
/// <summary> /// <summary>
/// Request Method /// Request Method
...@@ -294,5 +294,20 @@ namespace Titanium.Web.Proxy.Http ...@@ -294,5 +294,20 @@ namespace Titanium.Web.Proxy.Http
RequestHeaders = new Dictionary<string, HttpHeader>(StringComparer.OrdinalIgnoreCase); RequestHeaders = new Dictionary<string, HttpHeader>(StringComparer.OrdinalIgnoreCase);
NonUniqueRequestHeaders = new Dictionary<string, List<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 ...@@ -10,7 +10,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary> /// <summary>
/// Http(s) response object /// Http(s) response object
/// </summary> /// </summary>
public class Response public class Response : IDisposable
{ {
/// <summary> /// <summary>
/// Response Status Code. /// Response Status Code.
...@@ -234,5 +234,20 @@ namespace Titanium.Web.Proxy.Http ...@@ -234,5 +234,20 @@ namespace Titanium.Web.Proxy.Http
ResponseHeaders = new Dictionary<string, HttpHeader>(StringComparer.OrdinalIgnoreCase); ResponseHeaders = new Dictionary<string, HttpHeader>(StringComparer.OrdinalIgnoreCase);
NonUniqueResponseHeaders = new Dictionary<string, List<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;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
...@@ -30,7 +31,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -30,7 +31,7 @@ namespace Titanium.Web.Proxy.Network
/// <summary> /// <summary>
/// A class to manage SSL certificates used by this proxy server /// A class to manage SSL certificates used by this proxy server
/// </summary> /// </summary>
public class CertificateManager : IDisposable public sealed class CertificateManager : IDisposable
{ {
internal CertificateEngine Engine internal CertificateEngine Engine
{ {
...@@ -147,7 +148,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -147,7 +148,7 @@ namespace Titanium.Web.Proxy.Network
return fileName; return fileName;
} }
internal X509Certificate2 LoadRootCertificate() private X509Certificate2 LoadRootCertificate()
{ {
var fileName = GetRootCertificatePath(); var fileName = GetRootCertificatePath();
if (!File.Exists(fileName)) return null; if (!File.Exists(fileName)) return null;
...@@ -218,6 +219,51 @@ namespace Titanium.Web.Proxy.Network ...@@ -218,6 +219,51 @@ namespace Titanium.Web.Proxy.Network
TrustRootCertificate(StoreLocation.LocalMachine); 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> /// <summary>
/// Removes the trusted certificates. /// Removes the trusted certificates.
/// </summary> /// </summary>
...@@ -230,13 +276,49 @@ namespace Titanium.Web.Proxy.Network ...@@ -230,13 +276,49 @@ namespace Titanium.Web.Proxy.Network
RemoveTrustedRootCertificates(StoreLocation.LocalMachine); 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> /// <summary>
/// Create an SSL certificate /// Create an SSL certificate
/// </summary> /// </summary>
/// <param name="certificateName"></param> /// <param name="certificateName"></param>
/// <param name="isRootCertificate"></param> /// <param name="isRootCertificate"></param>
/// <returns></returns> /// <returns></returns>
internal virtual X509Certificate2 CreateCertificate(string certificateName, bool isRootCertificate) internal X509Certificate2 CreateCertificate(string certificateName, bool isRootCertificate)
{ {
if (certificateCache.ContainsKey(certificateName)) if (certificateCache.ContainsKey(certificateName))
{ {
...@@ -317,7 +399,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -317,7 +399,7 @@ namespace Titanium.Web.Proxy.Network
/// </summary> /// </summary>
/// <param name="storeLocation"></param> /// <param name="storeLocation"></param>
/// <returns></returns> /// <returns></returns>
internal void TrustRootCertificate(StoreLocation storeLocation) private void TrustRootCertificate(StoreLocation storeLocation)
{ {
if (RootCertificate == null) if (RootCertificate == null)
{ {
...@@ -328,7 +410,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -328,7 +410,7 @@ namespace Titanium.Web.Proxy.Network
return; return;
} }
X509Store x509RootStore = new X509Store(StoreName.Root, storeLocation); var x509RootStore = new X509Store(StoreName.Root, storeLocation);
var x509PersonalStore = new X509Store(StoreName.My, storeLocation); var x509PersonalStore = new X509Store(StoreName.My, storeLocation);
try try
...@@ -357,7 +439,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -357,7 +439,7 @@ namespace Titanium.Web.Proxy.Network
/// </summary> /// </summary>
/// <param name="storeLocation"></param> /// <param name="storeLocation"></param>
/// <returns></returns> /// <returns></returns>
internal void RemoveTrustedRootCertificates(StoreLocation storeLocation) private void RemoveTrustedRootCertificates(StoreLocation storeLocation)
{ {
if (RootCertificate == null) if (RootCertificate == null)
{ {
...@@ -368,7 +450,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -368,7 +450,7 @@ namespace Titanium.Web.Proxy.Network
return; return;
} }
X509Store x509RootStore = new X509Store(StoreName.Root, storeLocation); var x509RootStore = new X509Store(StoreName.Root, storeLocation);
var x509PersonalStore = new X509Store(StoreName.My, storeLocation); var x509PersonalStore = new X509Store(StoreName.My, storeLocation);
try try
...@@ -382,7 +464,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -382,7 +464,7 @@ namespace Titanium.Web.Proxy.Network
catch (Exception e) catch (Exception e)
{ {
exceptionFunc( 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)); + $" for {storeLocation} store location. You may need admin rights.", e));
} }
finally finally
...@@ -392,6 +474,9 @@ namespace Titanium.Web.Proxy.Network ...@@ -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() public void Dispose()
{ {
} }
......
...@@ -647,46 +647,5 @@ namespace Titanium.Web.Proxy ...@@ -647,46 +647,5 @@ namespace Titanium.Web.Proxy
endPoint.Listener.Server.Close(); endPoint.Listener.Server.Close();
endPoint.Listener.Server.Dispose(); 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