Commit 70c107a4 authored by justcoding121's avatar justcoding121 Committed by justcoding121

Merge pull request #276 from honfika/develop

Code cleanup - if you prefer any other style, please let me know
parents 6493ea87 126eed5e
...@@ -25,8 +25,7 @@ namespace Titanium.Web.Proxy.Examples.Basic.Helpers ...@@ -25,8 +25,7 @@ namespace Titanium.Web.Proxy.Examples.Basic.Helpers
internal static bool DisableQuickEditMode() internal static bool DisableQuickEditMode()
{ {
var consoleHandle = GetStdHandle(STD_INPUT_HANDLE);
IntPtr consoleHandle = GetStdHandle(STD_INPUT_HANDLE);
// get current console mode // get current console mode
uint consoleMode; uint consoleMode;
......
using System; using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Titanium.Web.Proxy.Examples.Basic.Helpers; using Titanium.Web.Proxy.Examples.Basic.Helpers;
namespace Titanium.Web.Proxy.Examples.Basic namespace Titanium.Web.Proxy.Examples.Basic
......
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net; using System.Net;
using System.Net.Security; using System.Net.Security;
...@@ -55,7 +54,10 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -55,7 +54,10 @@ namespace Titanium.Web.Proxy.Examples.Basic
//Exclude Https addresses you don't want to proxy //Exclude Https addresses you don't want to proxy
//Useful for clients that use certificate pinning //Useful for clients that use certificate pinning
//for example google.com and dropbox.com //for example google.com and dropbox.com
ExcludedHttpsHostNameRegex = new List<string> { "dropbox.com" } ExcludedHttpsHostNameRegex = new List<string>
{
"dropbox.com"
}
//Include Https addresses you want to proxy (others will be excluded) //Include Https addresses you want to proxy (others will be excluded)
//for example github.com //for example github.com
...@@ -91,8 +93,7 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -91,8 +93,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
//proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 }; //proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
foreach (var endPoint in proxyServer.ProxyEndPoints) foreach (var endPoint in proxyServer.ProxyEndPoints)
Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ", Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);
endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);
//Only explicit proxies can be set as system proxy! //Only explicit proxies can be set as system proxy!
//proxyServer.SetAsSystemHttpProxy(explicitEndPoint); //proxyServer.SetAsSystemHttpProxy(explicitEndPoint);
...@@ -125,7 +126,7 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -125,7 +126,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
if (e.WebSession.Request.HasBody) if (e.WebSession.Request.HasBody)
{ {
//Get/Set request body bytes //Get/Set request body bytes
byte[] bodyBytes = await e.GetRequestBody(); var bodyBytes = await e.GetRequestBody();
await e.SetRequestBody(bodyBytes); await e.SetRequestBody(bodyBytes);
//Get/Set request body as string //Get/Set request body as string
...@@ -179,7 +180,7 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -179,7 +180,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
{ {
if (e.WebSession.Response.ContentType != null && e.WebSession.Response.ContentType.Trim().ToLower().Contains("text/html")) if (e.WebSession.Response.ContentType != null && e.WebSession.Response.ContentType.Trim().ToLower().Contains("text/html"))
{ {
byte[] bodyBytes = await e.GetResponseBody(); var bodyBytes = await e.GetResponseBody();
await e.SetResponseBody(bodyBytes); await e.SetResponseBody(bodyBytes);
string body = await e.GetResponseBodyAsString(); string body = await e.GetResponseBodyAsString();
......
...@@ -18,7 +18,7 @@ namespace Titanium.Web.Proxy.IntegrationTests ...@@ -18,7 +18,7 @@ namespace Titanium.Web.Proxy.IntegrationTests
{ {
//expand this to stress test to find //expand this to stress test to find
//why in long run proxy becomes unresponsive as per issue #184 //why in long run proxy becomes unresponsive as per issue #184
var testUrl = "https://google.com"; string testUrl = "https://google.com";
int proxyPort = 8086; int proxyPort = 8086;
var proxy = new ProxyTestController(); var proxy = new ProxyTestController();
proxy.StartProxy(proxyPort); proxy.StartProxy(proxyPort);
......
...@@ -25,7 +25,7 @@ namespace Titanium.Web.Proxy.UnitTests ...@@ -25,7 +25,7 @@ namespace Titanium.Web.Proxy.UnitTests
for (int i = 0; i < 1000; i++) for (int i = 0; i < 1000; i++)
{ {
foreach (var host in hostNames) foreach (string host in hostNames)
{ {
tasks.Add(Task.Run(async () => tasks.Add(Task.Run(async () =>
{ {
......
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Net; using System.Net;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Helpers.WinHttp; using Titanium.Web.Proxy.Helpers.WinHttp;
......
using Microsoft.VisualStudio.TestTools.UnitTesting; using System;
using System; using Microsoft.VisualStudio.TestTools.UnitTesting;
using Titanium.Web.Proxy.Network.WinAuth; using Titanium.Web.Proxy.Network.WinAuth;
namespace Titanium.Web.Proxy.UnitTests namespace Titanium.Web.Proxy.UnitTests
...@@ -10,7 +10,7 @@ namespace Titanium.Web.Proxy.UnitTests ...@@ -10,7 +10,7 @@ namespace Titanium.Web.Proxy.UnitTests
[TestMethod] [TestMethod]
public void Test_Acquire_Client_Token() public void Test_Acquire_Client_Token()
{ {
var token = WinAuthHandler.GetInitialAuthToken("mylocalserver.com", "NTLM", Guid.NewGuid()); string token = WinAuthHandler.GetInitialAuthToken("mylocalserver.com", "NTLM", Guid.NewGuid());
Assert.IsTrue(token.Length > 1); Assert.IsTrue(token.Length > 1);
} }
} }
......
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_CASE_STATEMENT_STYLE/@EntryValue">LINE_BREAK</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_EMBEDDED_STATEMENT_STYLE/@EntryValue">LINE_BREAK</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">240</s:Int64> <s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">160</s:Int64>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForBuiltInTypes/@EntryValue">UseExplicitType</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseVar</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BC/@EntryIndexedValue">BC</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BC/@EntryIndexedValue">BC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CN/@EntryIndexedValue">CN</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CN/@EntryIndexedValue">CN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DN/@EntryIndexedValue">DN</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DN/@EntryIndexedValue">DN</s:String>
......
...@@ -16,11 +16,7 @@ namespace Titanium.Web.Proxy ...@@ -16,11 +16,7 @@ namespace Titanium.Web.Proxy
/// <param name="chain"></param> /// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param> /// <param name="sslPolicyErrors"></param>
/// <returns></returns> /// <returns></returns>
internal bool ValidateServerCertificate( internal bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{ {
//if user callback is registered then do it //if user callback is registered then do it
if (ServerCertificateValidationCallback != null) if (ServerCertificateValidationCallback != null)
...@@ -56,22 +52,15 @@ namespace Titanium.Web.Proxy ...@@ -56,22 +52,15 @@ namespace Titanium.Web.Proxy
/// <param name="remoteCertificate"></param> /// <param name="remoteCertificate"></param>
/// <param name="acceptableIssuers"></param> /// <param name="acceptableIssuers"></param>
/// <returns></returns> /// <returns></returns>
internal X509Certificate SelectClientCertificate( internal X509Certificate SelectClientCertificate(object sender, string targetHost, X509CertificateCollection localCertificates,
object sender, X509Certificate remoteCertificate, string[] acceptableIssuers)
string targetHost,
X509CertificateCollection localCertificates,
X509Certificate remoteCertificate,
string[] acceptableIssuers)
{ {
X509Certificate clientCertificate = null; X509Certificate clientCertificate = null;
if (acceptableIssuers != null && if (acceptableIssuers != null && acceptableIssuers.Length > 0 && localCertificates != null && localCertificates.Count > 0)
acceptableIssuers.Length > 0 &&
localCertificates != null &&
localCertificates.Count > 0)
{ {
// Use the first certificate that is from an acceptable issuer. // Use the first certificate that is from an acceptable issuer.
foreach (X509Certificate certificate in localCertificates) foreach (var certificate in localCertificates)
{ {
string issuer = certificate.Issuer; string issuer = certificate.Issuer;
if (Array.IndexOf(acceptableIssuers, issuer) != -1) if (Array.IndexOf(acceptableIssuers, issuer) != -1)
...@@ -81,8 +70,7 @@ namespace Titanium.Web.Proxy ...@@ -81,8 +70,7 @@ namespace Titanium.Web.Proxy
} }
} }
if (localCertificates != null && if (localCertificates != null && localCertificates.Count > 0)
localCertificates.Count > 0)
{ {
clientCertificate = localCertificates[0]; clientCertificate = localCertificates[0];
} }
......
...@@ -48,7 +48,6 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -48,7 +48,6 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary> /// </summary>
public Guid Id => WebSession.RequestId; public Guid Id => WebSession.RequestId;
/// <summary> /// <summary>
/// Should we send the request again /// Should we send the request again
/// </summary> /// </summary>
...@@ -59,8 +58,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -59,8 +58,7 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
if (WebSession.Response.ResponseStatusCode == null) if (WebSession.Response.ResponseStatusCode == null)
{ {
throw new Exception("Response status code is null. Cannot request again a request " throw new Exception("Response status code is null. Cannot request again a request " + "which was never send to server.");
+ "which was never send to server.");
} }
reRequest = value; reRequest = value;
...@@ -113,8 +111,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -113,8 +111,7 @@ namespace Titanium.Web.Proxy.EventArguments
//GET request don't have a request body to read //GET request don't have a request body to read
if (!WebSession.Request.HasBody) if (!WebSession.Request.HasBody)
{ {
throw new BodyNotFoundException("Request don't have a body. " + throw new BodyNotFoundException("Request don't have a body. " + "Please verify that this request is a Http POST/PUT/PATCH and request " +
"Please verify that this request is a Http POST/PUT/PATCH and request " +
"content length is greater than zero before accessing the body."); "content length is greater than zero before accessing the body.");
} }
...@@ -135,16 +132,14 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -135,16 +132,14 @@ namespace Titanium.Web.Proxy.EventArguments
if (WebSession.Request.ContentLength > 0) if (WebSession.Request.ContentLength > 0)
{ {
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response //If not chunked then its easy just read the amount of bytes mentioned in content length header of response
await ProxyClient.ClientStreamReader.CopyBytesToStream(requestBodyStream, await ProxyClient.ClientStreamReader.CopyBytesToStream(requestBodyStream, WebSession.Request.ContentLength);
WebSession.Request.ContentLength);
} }
else if (WebSession.Request.HttpVersion.Major == 1 && WebSession.Request.HttpVersion.Minor == 0) else if (WebSession.Request.HttpVersion.Major == 1 && WebSession.Request.HttpVersion.Minor == 0)
{ {
await WebSession.ServerConnection.StreamReader.CopyBytesToStream(requestBodyStream, long.MaxValue); await WebSession.ServerConnection.StreamReader.CopyBytesToStream(requestBodyStream, long.MaxValue);
} }
} }
WebSession.Request.RequestBody = await GetDecompressedResponseBody(WebSession.Request.ContentEncoding, WebSession.Request.RequestBody = await GetDecompressedResponseBody(WebSession.Request.ContentEncoding, requestBodyStream.ToArray());
requestBodyStream.ToArray());
} }
//Now set the flag to true //Now set the flag to true
...@@ -185,17 +180,16 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -185,17 +180,16 @@ namespace Titanium.Web.Proxy.EventArguments
if (WebSession.Response.ContentLength > 0) if (WebSession.Response.ContentLength > 0)
{ {
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response //If not chunked then its easy just read the amount of bytes mentioned in content length header of response
await WebSession.ServerConnection.StreamReader.CopyBytesToStream(responseBodyStream, await WebSession.ServerConnection.StreamReader.CopyBytesToStream(responseBodyStream, WebSession.Response.ContentLength);
WebSession.Response.ContentLength);
} }
else if (WebSession.Response.HttpVersion.Major == 1 && WebSession.Response.HttpVersion.Minor == 0 || WebSession.Response.ContentLength == -1) else if (WebSession.Response.HttpVersion.Major == 1 && WebSession.Response.HttpVersion.Minor == 0 ||
WebSession.Response.ContentLength == -1)
{ {
await WebSession.ServerConnection.StreamReader.CopyBytesToStream(responseBodyStream, long.MaxValue); await WebSession.ServerConnection.StreamReader.CopyBytesToStream(responseBodyStream, long.MaxValue);
} }
} }
WebSession.Response.ResponseBody = await GetDecompressedResponseBody(WebSession.Response.ContentEncoding, WebSession.Response.ResponseBody = await GetDecompressedResponseBody(WebSession.Response.ContentEncoding, responseBodyStream.ToArray());
responseBodyStream.ToArray());
} }
//set this to true for caching //set this to true for caching
WebSession.Response.ResponseBodyRead = true; WebSession.Response.ResponseBodyRead = true;
...@@ -236,7 +230,8 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -236,7 +230,8 @@ namespace Titanium.Web.Proxy.EventArguments
await ReadRequestBody(); await ReadRequestBody();
} }
//Use the encoding specified in request to decode the byte[] data to string //Use the encoding specified in request to decode the byte[] data to string
return WebSession.Request.RequestBodyString ?? (WebSession.Request.RequestBodyString = WebSession.Request.Encoding.GetString(WebSession.Request.RequestBody)); return WebSession.Request.RequestBodyString ?? (WebSession.Request.RequestBodyString =
WebSession.Request.Encoding.GetString(WebSession.Request.RequestBody));
} }
/// <summary> /// <summary>
...@@ -316,8 +311,8 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -316,8 +311,8 @@ namespace Titanium.Web.Proxy.EventArguments
await GetResponseBody(); await GetResponseBody();
return WebSession.Response.ResponseBodyString ?? return WebSession.Response.ResponseBodyString ?? (WebSession.Response.ResponseBodyString =
(WebSession.Response.ResponseBodyString = WebSession.Response.Encoding.GetString(WebSession.Response.ResponseBody)); WebSession.Response.Encoding.GetString(WebSession.Response.ResponseBody));
} }
/// <summary> /// <summary>
......
...@@ -9,8 +9,7 @@ ...@@ -9,8 +9,7 @@
/// Constructor. /// Constructor.
/// </summary> /// </summary>
/// <param name="message"></param> /// <param name="message"></param>
public BodyNotFoundException(string message) public BodyNotFoundException(string message) : base(message)
: base(message)
{ {
} }
} }
......
...@@ -7,8 +7,8 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -7,8 +7,8 @@ namespace Titanium.Web.Proxy.Extensions
{ {
public static void InvokeParallel<T>(this Func<object, T, Task> callback, object sender, T args) public static void InvokeParallel<T>(this Func<object, T, Task> callback, object sender, T args)
{ {
Delegate[] invocationList = callback.GetInvocationList(); var invocationList = callback.GetInvocationList();
Task[] handlerTasks = new Task[invocationList.Length]; var handlerTasks = new Task[invocationList.Length];
for (int i = 0; i < invocationList.Length; i++) for (int i = 0; i < invocationList.Length; i++)
{ {
...@@ -20,8 +20,8 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -20,8 +20,8 @@ namespace Titanium.Web.Proxy.Extensions
public static async Task InvokeParallelAsync<T>(this Func<object, T, Task> callback, object sender, T args) public static async Task InvokeParallelAsync<T>(this Func<object, T, Task> callback, object sender, T args)
{ {
Delegate[] invocationList = callback.GetInvocationList(); var invocationList = callback.GetInvocationList();
Task[] handlerTasks = new Task[invocationList.Length]; var handlerTasks = new Task[invocationList.Length];
for (int i = 0; i < invocationList.Length; i++) for (int i = 0; i < invocationList.Length; i++)
{ {
......
using System; using System.Text;
using System.Text;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
......
using System; using System.Text;
using System.Text;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
......
...@@ -39,7 +39,7 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -39,7 +39,7 @@ namespace Titanium.Web.Proxy.Extensions
/// <returns></returns> /// <returns></returns>
internal static async Task CopyBytesToStream(this CustomBinaryReader streamReader, Stream stream, long totalBytesToRead) internal static async Task CopyBytesToStream(this CustomBinaryReader streamReader, Stream stream, long totalBytesToRead)
{ {
byte[] buffer = streamReader.Buffer; var buffer = streamReader.Buffer;
long remainingBytes = totalBytesToRead; long remainingBytes = totalBytesToRead;
while (remainingBytes > 0) while (remainingBytes > 0)
...@@ -72,8 +72,8 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -72,8 +72,8 @@ namespace Titanium.Web.Proxy.Extensions
{ {
while (true) while (true)
{ {
var chuchkHead = await clientStreamReader.ReadLineAsync(); string chuchkHead = await clientStreamReader.ReadLineAsync();
var chunkSize = int.Parse(chuchkHead, NumberStyles.HexNumber); int chunkSize = int.Parse(chuchkHead, NumberStyles.HexNumber);
if (chunkSize != 0) if (chunkSize != 0)
{ {
...@@ -119,7 +119,8 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -119,7 +119,8 @@ namespace Titanium.Web.Proxy.Extensions
/// <param name="isChunked"></param> /// <param name="isChunked"></param>
/// <param name="contentLength"></param> /// <param name="contentLength"></param>
/// <returns></returns> /// <returns></returns>
internal static async Task WriteResponseBody(this CustomBinaryReader inStreamReader, int bufferSize, Stream outStream, bool isChunked, long contentLength) internal static async Task WriteResponseBody(this CustomBinaryReader inStreamReader, int bufferSize, Stream outStream, bool isChunked,
long contentLength)
{ {
if (!isChunked) if (!isChunked)
{ {
...@@ -147,8 +148,8 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -147,8 +148,8 @@ namespace Titanium.Web.Proxy.Extensions
{ {
while (true) while (true)
{ {
var chunkHead = await inStreamReader.ReadLineAsync(); string chunkHead = await inStreamReader.ReadLineAsync();
var chunkSize = int.Parse(chunkHead, NumberStyles.HexNumber); int chunkSize = int.Parse(chunkHead, NumberStyles.HexNumber);
if (chunkSize != 0) if (chunkSize != 0)
{ {
......
...@@ -13,7 +13,7 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -13,7 +13,7 @@ namespace Titanium.Web.Proxy.Extensions
internal static bool IsConnected(this Socket client) internal static bool IsConnected(this Socket client)
{ {
// This is how you can determine whether a socket is still connected. // This is how you can determine whether a socket is still connected.
var blockingState = client.Blocking; bool blockingState = client.Blocking;
try try
{ {
......
using System; using System.Collections.Concurrent;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.Helpers namespace Titanium.Web.Proxy.Helpers
{ {
......
...@@ -34,7 +34,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -34,7 +34,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns></returns> /// <returns></returns>
internal async Task<string> ReadLineAsync() internal async Task<string> ReadLineAsync()
{ {
var lastChar = default(byte); byte lastChar = default(byte);
int bufferDataLength = 0; int bufferDataLength = 0;
...@@ -43,7 +43,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -43,7 +43,7 @@ namespace Titanium.Web.Proxy.Helpers
while (stream.DataAvailable || await stream.FillBufferAsync()) while (stream.DataAvailable || await stream.FillBufferAsync())
{ {
var newChar = stream.ReadByteFromBuffer(); byte newChar = stream.ReadByteFromBuffer();
buffer[bufferDataLength] = newChar; buffer[bufferDataLength] = newChar;
//if new line //if new line
......
...@@ -35,7 +35,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -35,7 +35,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="bufferSize">Size of the buffer.</param> /// <param name="bufferSize">Size of the buffer.</param>
public CustomBufferedStream(Stream baseStream, int bufferSize) public CustomBufferedStream(Stream baseStream, int bufferSize)
{ {
readCallback = new AsyncCallback(ReadCallback); readCallback = ReadCallback;
this.baseStream = baseStream; this.baseStream = baseStream;
streamBuffer = BufferPool.GetBuffer(bufferSize); streamBuffer = BufferPool.GetBuffer(bufferSize);
} }
...@@ -359,7 +359,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -359,7 +359,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
if(!disposed) if (!disposed)
{ {
disposed = true; disposed = true;
baseStream.Dispose(); baseStream.Dispose();
...@@ -367,7 +367,6 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -367,7 +367,6 @@ namespace Titanium.Web.Proxy.Helpers
streamBuffer = null; streamBuffer = null;
readCallback = null; readCallback = null;
} }
} }
/// <summary> /// <summary>
......
...@@ -16,9 +16,9 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -16,9 +16,9 @@ namespace Titanium.Web.Proxy.Helpers
try try
{ {
var myProfileDirectory = var myProfileDirectory =
new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Mozilla\\Firefox\\Profiles\\")
"\\Mozilla\\Firefox\\Profiles\\").GetDirectories("*.default"); .GetDirectories("*.default");
var myFfPrefFile = myProfileDirectory[0].FullName + "\\prefs.js"; string myFfPrefFile = myProfileDirectory[0].FullName + "\\prefs.js";
if (!File.Exists(myFfPrefFile)) if (!File.Exists(myFfPrefFile))
{ {
return; return;
...@@ -26,18 +26,17 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -26,18 +26,17 @@ namespace Titanium.Web.Proxy.Helpers
// We have a pref file so let''s make sure it has the proxy setting // We have a pref file so let''s make sure it has the proxy setting
var myReader = new StreamReader(myFfPrefFile); var myReader = new StreamReader(myFfPrefFile);
var myPrefContents = myReader.ReadToEnd(); string myPrefContents = myReader.ReadToEnd();
myReader.Close(); myReader.Close();
for (int i = 0; i <= 4; i++) for (int i = 0; i <= 4; i++)
{ {
var searchStr = $"user_pref(\"network.proxy.type\", {i});"; string searchStr = $"user_pref(\"network.proxy.type\", {i});";
if (myPrefContents.Contains(searchStr)) if (myPrefContents.Contains(searchStr))
{ {
// Add the proxy enable line and write it back to the file // Add the proxy enable line and write it back to the file
myPrefContents = myPrefContents.Replace(searchStr, myPrefContents = myPrefContents.Replace(searchStr, "user_pref(\"network.proxy.type\", 5);");
"user_pref(\"network.proxy.type\", 5);");
} }
} }
......
...@@ -20,7 +20,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -20,7 +20,7 @@ namespace Titanium.Web.Proxy.Helpers
//extract the encoding by finding the charset //extract the encoding by finding the charset
var parameters = contentType.Split(ProxyConstants.SemiColonSplit); var parameters = contentType.Split(ProxyConstants.SemiColonSplit);
foreach (var parameter in parameters) foreach (string parameter in parameters)
{ {
var encodingSplit = parameter.Split(ProxyConstants.EqualSplit, 2); var encodingSplit = parameter.Split(ProxyConstants.EqualSplit, 2);
if (encodingSplit.Length == 2 && encodingSplit[0].Trim().Equals("charset", StringComparison.CurrentCultureIgnoreCase)) if (encodingSplit.Length == 2 && encodingSplit[0].Trim().Equals("charset", StringComparison.CurrentCultureIgnoreCase))
...@@ -66,9 +66,8 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -66,9 +66,8 @@ namespace Titanium.Web.Proxy.Helpers
if (hostname.Split(ProxyConstants.DotSplit).Length > 2) if (hostname.Split(ProxyConstants.DotSplit).Length > 2)
{ {
int idx = hostname.IndexOf(ProxyConstants.DotSplit); int idx = hostname.IndexOf(ProxyConstants.DotSplit);
var rootDomain = hostname.Substring(idx + 1); string rootDomain = hostname.Substring(idx + 1);
return "*." + rootDomain; return "*." + rootDomain;
} }
//return as it is //return as it is
......
...@@ -15,7 +15,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -15,7 +15,7 @@ namespace Titanium.Web.Proxy.Helpers
internal static int GetProcessIdFromPort(int port, bool ipV6Enabled) internal static int GetProcessIdFromPort(int port, bool ipV6Enabled)
{ {
var processId = FindProcessIdFromLocalPort(port, IpVersion.Ipv4); int processId = FindProcessIdFromLocalPort(port, IpVersion.Ipv4);
if (processId > 0 && !ipV6Enabled) if (processId > 0 && !ipV6Enabled)
{ {
...@@ -43,10 +43,10 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -43,10 +43,10 @@ namespace Titanium.Web.Proxy.Helpers
{ {
bool isLocalhost = false; bool isLocalhost = false;
IPHostEntry localhost = Dns.GetHostEntry("127.0.0.1"); var localhost = Dns.GetHostEntry("127.0.0.1");
if (hostName == localhost.HostName) if (hostName == localhost.HostName)
{ {
IPHostEntry hostEntry = Dns.GetHostEntry(hostName); var hostEntry = Dns.GetHostEntry(hostName);
isLocalhost = hostEntry.AddressList.Any(IPAddress.IsLoopback); isLocalhost = hostEntry.AddressList.Any(IPAddress.IsLoopback);
} }
......
...@@ -3,7 +3,6 @@ using System.Collections.Generic; ...@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.Helpers namespace Titanium.Web.Proxy.Helpers
{ {
...@@ -37,14 +36,14 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -37,14 +36,14 @@ namespace Titanium.Web.Proxy.Helpers
if (proxyServer != null) if (proxyServer != null)
{ {
Proxies = GetSystemProxyValues(proxyServer).ToDictionary(x=>x.ProtocolType); Proxies = GetSystemProxyValues(proxyServer).ToDictionary(x => x.ProtocolType);
} }
if (proxyOverride != null) if (proxyOverride != null)
{ {
var overrides = proxyOverride.Split(';'); var overrides = proxyOverride.Split(';');
var overrides2 = new List<string>(); var overrides2 = new List<string>();
foreach (var overrideHost in overrides) foreach (string overrideHost in overrides)
{ {
if (overrideHost == "<-loopback>") if (overrideHost == "<-loopback>")
{ {
...@@ -71,7 +70,8 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -71,7 +70,8 @@ namespace Titanium.Web.Proxy.Helpers
private static string BypassStringEscape(string rawString) private static string BypassStringEscape(string rawString)
{ {
Match match = new Regex("^(?<scheme>.*://)?(?<host>[^:]*)(?<port>:[0-9]{1,5})?$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant).Match(rawString); var match =
new Regex("^(?<scheme>.*://)?(?<host>[^:]*)(?<port>:[0-9]{1,5})?$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant).Match(rawString);
string empty1; string empty1;
string rawString1; string rawString1;
string empty2; string empty2;
...@@ -174,7 +174,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -174,7 +174,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns></returns> /// <returns></returns>
private static HttpSystemProxyValue ParseProxyValue(string value) private static HttpSystemProxyValue ParseProxyValue(string value)
{ {
var tmp = Regex.Replace(value, @"\s+", " ").Trim(); string tmp = Regex.Replace(value, @"\s+", " ").Trim();
int equalsIndex = tmp.IndexOf("=", StringComparison.InvariantCulture); int equalsIndex = tmp.IndexOf("=", StringComparison.InvariantCulture);
if (equalsIndex >= 0) if (equalsIndex >= 0)
......
...@@ -11,8 +11,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -11,8 +11,7 @@ namespace Titanium.Web.Proxy.Helpers
/// cache for mono runtime check /// cache for mono runtime check
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private static Lazy<bool> isRunningOnMono private static readonly Lazy<bool> isRunningOnMono = new Lazy<bool>(() => Type.GetType("Mono.Runtime") != null);
= new Lazy<bool>(()=> Type.GetType("Mono.Runtime") != null);
/// <summary> /// <summary>
/// Is running on Mono? /// Is running on Mono?
......
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Microsoft.Win32; using Microsoft.Win32;
...@@ -34,8 +33,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -34,8 +33,7 @@ namespace Titanium.Web.Proxy.Helpers
internal partial class NativeMethods internal partial class NativeMethods
{ {
[DllImport("wininet.dll")] [DllImport("wininet.dll")]
internal static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, internal static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);
int dwBufferLength);
[DllImport("kernel32.dll")] [DllImport("kernel32.dll")]
internal static extern IntPtr GetConsoleWindow(); internal static extern IntPtr GetConsoleWindow();
...@@ -129,7 +127,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -129,7 +127,7 @@ namespace Titanium.Web.Proxy.Helpers
SaveOriginalProxyConfiguration(reg); SaveOriginalProxyConfiguration(reg);
PrepareRegistry(reg); PrepareRegistry(reg);
var exisitingContent = reg.GetValue(regProxyServer) as string; string exisitingContent = reg.GetValue(regProxyServer) as string;
var existingSystemProxyValues = ProxyInfo.GetSystemProxyValues(exisitingContent); var existingSystemProxyValues = ProxyInfo.GetSystemProxyValues(exisitingContent);
existingSystemProxyValues.RemoveAll(x => (protocolType & x.ProtocolType) != 0); existingSystemProxyValues.RemoveAll(x => (protocolType & x.ProtocolType) != 0);
if ((protocolType & ProxyProtocolType.Http) != 0) if ((protocolType & ProxyProtocolType.Http) != 0)
...@@ -175,7 +173,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -175,7 +173,7 @@ namespace Titanium.Web.Proxy.Helpers
if (reg.GetValue(regProxyServer) != null) if (reg.GetValue(regProxyServer) != null)
{ {
var exisitingContent = reg.GetValue(regProxyServer) as string; string exisitingContent = reg.GetValue(regProxyServer) as string;
var existingSystemProxyValues = ProxyInfo.GetSystemProxyValues(exisitingContent); var existingSystemProxyValues = ProxyInfo.GetSystemProxyValues(exisitingContent);
existingSystemProxyValues.RemoveAll(x => (protocolType & x.ProtocolType) != 0); existingSystemProxyValues.RemoveAll(x => (protocolType & x.ProtocolType) != 0);
...@@ -305,11 +303,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -305,11 +303,7 @@ namespace Titanium.Web.Proxy.Helpers
private ProxyInfo GetProxyInfoFromRegistry(RegistryKey reg) private ProxyInfo GetProxyInfoFromRegistry(RegistryKey reg)
{ {
var pi = new ProxyInfo( var pi = new ProxyInfo(null, reg.GetValue(regAutoConfigUrl) as string, reg.GetValue(regProxyEnable) as int?, reg.GetValue(regProxyServer) as string,
null,
reg.GetValue(regAutoConfigUrl) as string,
reg.GetValue(regProxyEnable) as int?,
reg.GetValue(regProxyServer) as string,
reg.GetValue(regProxyOverride) as string); reg.GetValue(regProxyOverride) as string);
return pi; return pi;
......
...@@ -83,12 +83,12 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -83,12 +83,12 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns>Collection of <see cref="TcpRow"/>.</returns> /// <returns>Collection of <see cref="TcpRow"/>.</returns>
internal static TcpTable GetExtendedTcpTable(IpVersion ipVersion) internal static TcpTable GetExtendedTcpTable(IpVersion ipVersion)
{ {
List<TcpRow> tcpRows = new List<TcpRow>(); var tcpRows = new List<TcpRow>();
IntPtr tcpTable = IntPtr.Zero; var tcpTable = IntPtr.Zero;
int tcpTableLength = 0; int tcpTableLength = 0;
var ipVersionValue = ipVersion == IpVersion.Ipv4 ? NativeMethods.AfInet : NativeMethods.AfInet6; int ipVersionValue = ipVersion == IpVersion.Ipv4 ? NativeMethods.AfInet : NativeMethods.AfInet6;
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, false, ipVersionValue, (int)NativeMethods.TcpTableType.OwnerPidAll, 0) != 0) if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, false, ipVersionValue, (int)NativeMethods.TcpTableType.OwnerPidAll, 0) != 0)
{ {
...@@ -97,9 +97,9 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -97,9 +97,9 @@ namespace Titanium.Web.Proxy.Helpers
tcpTable = Marshal.AllocHGlobal(tcpTableLength); tcpTable = Marshal.AllocHGlobal(tcpTableLength);
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, ipVersionValue, (int)NativeMethods.TcpTableType.OwnerPidAll, 0) == 0) if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, ipVersionValue, (int)NativeMethods.TcpTableType.OwnerPidAll, 0) == 0)
{ {
NativeMethods.TcpTable table = (NativeMethods.TcpTable)Marshal.PtrToStructure(tcpTable, typeof(NativeMethods.TcpTable)); var table = (NativeMethods.TcpTable)Marshal.PtrToStructure(tcpTable, typeof(NativeMethods.TcpTable));
IntPtr rowPtr = (IntPtr)((long)tcpTable + Marshal.SizeOf(table.length)); var rowPtr = (IntPtr)((long)tcpTable + Marshal.SizeOf(table.length));
for (int i = 0; i < table.length; ++i) for (int i = 0; i < table.length; ++i)
{ {
...@@ -126,10 +126,10 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -126,10 +126,10 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns><see cref="TcpRow"/>.</returns> /// <returns><see cref="TcpRow"/>.</returns>
internal static TcpRow GetTcpRowByLocalPort(IpVersion ipVersion, int localPort) internal static TcpRow GetTcpRowByLocalPort(IpVersion ipVersion, int localPort)
{ {
IntPtr tcpTable = IntPtr.Zero; var tcpTable = IntPtr.Zero;
int tcpTableLength = 0; int tcpTableLength = 0;
var ipVersionValue = ipVersion == IpVersion.Ipv4 ? NativeMethods.AfInet : NativeMethods.AfInet6; int ipVersionValue = ipVersion == IpVersion.Ipv4 ? NativeMethods.AfInet : NativeMethods.AfInet6;
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, false, ipVersionValue, (int)NativeMethods.TcpTableType.OwnerPidAll, 0) != 0) if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, false, ipVersionValue, (int)NativeMethods.TcpTableType.OwnerPidAll, 0) != 0)
{ {
...@@ -138,9 +138,9 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -138,9 +138,9 @@ namespace Titanium.Web.Proxy.Helpers
tcpTable = Marshal.AllocHGlobal(tcpTableLength); tcpTable = Marshal.AllocHGlobal(tcpTableLength);
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, ipVersionValue, (int)NativeMethods.TcpTableType.OwnerPidAll, 0) == 0) if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, ipVersionValue, (int)NativeMethods.TcpTableType.OwnerPidAll, 0) == 0)
{ {
NativeMethods.TcpTable table = (NativeMethods.TcpTable)Marshal.PtrToStructure(tcpTable, typeof(NativeMethods.TcpTable)); var table = (NativeMethods.TcpTable)Marshal.PtrToStructure(tcpTable, typeof(NativeMethods.TcpTable));
IntPtr rowPtr = (IntPtr)((long)tcpTable + Marshal.SizeOf(table.length)); var rowPtr = (IntPtr)((long)tcpTable + Marshal.SizeOf(table.length));
for (int i = 0; i < table.length; ++i) for (int i = 0; i < table.length; ++i)
{ {
...@@ -181,11 +181,8 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -181,11 +181,8 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="tcpConnectionFactory"></param> /// <param name="tcpConnectionFactory"></param>
/// <param name="connection"></param> /// <param name="connection"></param>
/// <returns></returns> /// <returns></returns>
internal static async Task SendRaw(ProxyServer server, internal static async Task SendRaw(ProxyServer server, string remoteHostName, int remotePort, string httpCmd, Version httpVersion,
string remoteHostName, int remotePort, Dictionary<string, HttpHeader> requestHeaders, bool isHttps, Stream clientStream, TcpConnectionFactory tcpConnectionFactory,
string httpCmd, Version httpVersion, Dictionary<string, HttpHeader> requestHeaders,
bool isHttps,
Stream clientStream, TcpConnectionFactory tcpConnectionFactory,
TcpConnection connection = null) TcpConnection connection = null)
{ {
//prepare the prefix content //prepare the prefix content
...@@ -202,7 +199,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -202,7 +199,7 @@ namespace Titanium.Web.Proxy.Helpers
if (requestHeaders != null) if (requestHeaders != null)
{ {
foreach (var header in requestHeaders.Select(t => t.Value.ToString())) foreach (string header in requestHeaders.Select(t => t.Value.ToString()))
{ {
sb.Append(header); sb.Append(header);
sb.Append(ProxyConstants.NewLine); sb.Append(ProxyConstants.NewLine);
...@@ -218,10 +215,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -218,10 +215,7 @@ namespace Titanium.Web.Proxy.Helpers
//create new connection if connection is null //create new connection if connection is null
if (connection == null) if (connection == null)
{ {
tcpConnection = await tcpConnectionFactory.CreateClient(server, tcpConnection = await tcpConnectionFactory.CreateClient(server, remoteHostName, remotePort, httpVersion, isHttps, null, null);
remoteHostName, remotePort,
httpVersion, isHttps,
null, null);
connectionCreated = true; connectionCreated = true;
} }
...@@ -232,7 +226,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -232,7 +226,7 @@ namespace Titanium.Web.Proxy.Helpers
try try
{ {
Stream tunnelStream = tcpConnection.Stream; var tunnelStream = tcpConnection.Stream;
//Now async relay all server=>client & client=>server data //Now async relay all server=>client & client=>server data
var sendRelay = clientStream.CopyToAsync(sb?.ToString() ?? string.Empty, tunnelStream); var sendRelay = clientStream.CopyToAsync(sb?.ToString() ?? string.Empty, tunnelStream);
......
...@@ -18,7 +18,8 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -18,7 +18,8 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
internal static extern bool WinHttpSetTimeouts(WinHttpHandle session, int resolveTimeout, int connectTimeout, int sendTimeout, int receiveTimeout); internal static extern bool WinHttpSetTimeouts(WinHttpHandle session, int resolveTimeout, int connectTimeout, int sendTimeout, int receiveTimeout);
[DllImport("winhttp.dll", CharSet = CharSet.Unicode, SetLastError = true)] [DllImport("winhttp.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool WinHttpGetProxyForUrl(WinHttpHandle session, string url, [In] ref WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions, out WINHTTP_PROXY_INFO proxyInfo); internal static extern bool WinHttpGetProxyForUrl(WinHttpHandle session, string url, [In] ref WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions,
out WINHTTP_PROXY_INFO proxyInfo);
[DllImport("winhttp.dll", CharSet = CharSet.Unicode, SetLastError = true)] [DllImport("winhttp.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool WinHttpCloseHandle(IntPtr httpSession); internal static extern bool WinHttpCloseHandle(IntPtr httpSession);
...@@ -62,8 +63,8 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -62,8 +63,8 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
public AutoProxyFlags Flags; public AutoProxyFlags Flags;
public AutoDetectType AutoDetectFlags; public AutoDetectType AutoDetectFlags;
[MarshalAs(UnmanagedType.LPWStr)] public string AutoConfigUrl; [MarshalAs(UnmanagedType.LPWStr)] public string AutoConfigUrl;
private IntPtr lpvReserved; private readonly IntPtr lpvReserved;
private int dwReserved; private readonly int dwReserved;
public bool AutoLogonIfChallenged; public bool AutoLogonIfChallenged;
} }
......
...@@ -26,7 +26,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -26,7 +26,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
public bool AutomaticallyDetectSettings { get; internal set; } public bool AutomaticallyDetectSettings { get; internal set; }
private WebProxy Proxy { get; set; } private WebProxy proxy { get; set; }
public WinHttpWebProxyFinder() public WinHttpWebProxyFinder()
{ {
...@@ -89,26 +89,26 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -89,26 +89,26 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
return null; return null;
} }
string proxy = proxies[0]; string proxyStr = proxies[0];
int port = 80; int port = 80;
if (proxy.Contains(":")) if (proxyStr.Contains(":"))
{ {
var parts = proxy.Split(new[] { ':' }, 2); var parts = proxyStr.Split(new[] { ':' }, 2);
proxy = parts[0]; proxyStr = parts[0];
port = int.Parse(parts[1]); port = int.Parse(parts[1]);
} }
// TODO: Apply authorization // TODO: Apply authorization
var systemProxy = new ExternalProxy var systemProxy = new ExternalProxy
{ {
HostName = proxy, HostName = proxyStr,
Port = port, Port = port,
}; };
return systemProxy; return systemProxy;
} }
if (Proxy?.IsBypassed(destination) == true) if (proxy?.IsBypassed(destination) == true)
return null; return null;
var protocolType = ProxyInfo.ParseProtocolType(destination.Scheme); var protocolType = ProxyInfo.ParseProtocolType(destination.Scheme);
...@@ -138,7 +138,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -138,7 +138,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
AutomaticConfigurationScript = pi.AutoConfigUrl == null ? null : new Uri(pi.AutoConfigUrl); AutomaticConfigurationScript = pi.AutoConfigUrl == null ? null : new Uri(pi.AutoConfigUrl);
BypassLoopback = pi.BypassLoopback; BypassLoopback = pi.BypassLoopback;
BypassOnLocal = pi.BypassOnLocal; BypassOnLocal = pi.BypassOnLocal;
Proxy = new WebProxy(new Uri("http://localhost"), BypassOnLocal, pi.BypassList); proxy = new WebProxy(new Uri("http://localhost"), BypassOnLocal, pi.BypassList);
} }
private ProxyInfo GetProxyInfo() private ProxyInfo GetProxyInfo()
......
...@@ -8,8 +8,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -8,8 +8,7 @@ namespace Titanium.Web.Proxy.Http
{ {
internal static class HeaderParser internal static class HeaderParser
{ {
internal static async Task ReadHeaders(CustomBinaryReader reader, internal static async Task ReadHeaders(CustomBinaryReader reader, Dictionary<string, List<HttpHeader>> nonUniqueResponseHeaders,
Dictionary<string, List<HttpHeader>> nonUniqueResponseHeaders,
Dictionary<string, HttpHeader> headers) Dictionary<string, HttpHeader> headers)
{ {
string tmpLine; string tmpLine;
...@@ -29,7 +28,11 @@ namespace Titanium.Web.Proxy.Http ...@@ -29,7 +28,11 @@ namespace Titanium.Web.Proxy.Http
{ {
var existing = headers[newHeader.Name]; var existing = headers[newHeader.Name];
var nonUniqueHeaders = new List<HttpHeader> { existing, newHeader }; var nonUniqueHeaders = new List<HttpHeader>
{
existing,
newHeader
};
nonUniqueResponseHeaders.Add(newHeader.Name, nonUniqueHeaders); nonUniqueResponseHeaders.Add(newHeader.Name, nonUniqueHeaders);
headers.Remove(newHeader.Name); headers.Remove(newHeader.Name);
......
...@@ -118,7 +118,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -118,7 +118,7 @@ namespace Titanium.Web.Proxy.Http
requestLines.AppendLine(); requestLines.AppendLine();
var request = requestLines.ToString(); string request = requestLines.ToString();
var requestBytes = Encoding.ASCII.GetBytes(request); var requestBytes = Encoding.ASCII.GetBytes(request);
await stream.WriteAsync(requestBytes, 0, requestBytes.Length); await stream.WriteAsync(requestBytes, 0, requestBytes.Length);
...@@ -129,8 +129,8 @@ namespace Titanium.Web.Proxy.Http ...@@ -129,8 +129,8 @@ namespace Titanium.Web.Proxy.Http
if (Request.ExpectContinue) if (Request.ExpectContinue)
{ {
var httpResult = (await ServerConnection.StreamReader.ReadLineAsync()).Split(ProxyConstants.SpaceSplit, 3); var httpResult = (await ServerConnection.StreamReader.ReadLineAsync()).Split(ProxyConstants.SpaceSplit, 3);
var responseStatusCode = httpResult[1].Trim(); string responseStatusCode = httpResult[1].Trim();
var responseStatusDescription = httpResult[2].Trim(); string responseStatusDescription = httpResult[2].Trim();
//find if server is willing for expect continue //find if server is willing for expect continue
if (responseStatusCode.Equals("100") if (responseStatusCode.Equals("100")
...@@ -156,7 +156,8 @@ namespace Titanium.Web.Proxy.Http ...@@ -156,7 +156,8 @@ namespace Titanium.Web.Proxy.Http
internal async Task ReceiveResponse() internal async Task ReceiveResponse()
{ {
//return if this is already read //return if this is already read
if (Response.ResponseStatusCode != null) return; if (Response.ResponseStatusCode != null)
return;
string line = await ServerConnection.StreamReader.ReadLineAsync(); string line = await ServerConnection.StreamReader.ReadLineAsync();
if (line == null) if (line == null)
...@@ -172,7 +173,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -172,7 +173,7 @@ namespace Titanium.Web.Proxy.Http
httpResult = (await ServerConnection.StreamReader.ReadLineAsync()).Split(ProxyConstants.SpaceSplit, 3); httpResult = (await ServerConnection.StreamReader.ReadLineAsync()).Split(ProxyConstants.SpaceSplit, 3);
} }
var httpVersion = httpResult[0]; string httpVersion = httpResult[0];
var version = HttpHeader.Version11; var version = HttpHeader.Version11;
if (string.Equals(httpVersion, "HTTP/1.0", StringComparison.OrdinalIgnoreCase)) if (string.Equals(httpVersion, "HTTP/1.0", StringComparison.OrdinalIgnoreCase))
......
using System; using System;
using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
...@@ -41,12 +41,12 @@ namespace Titanium.Web.Proxy.Http ...@@ -41,12 +41,12 @@ namespace Titanium.Web.Proxy.Http
{ {
get get
{ {
var hasHeader = RequestHeaders.ContainsKey("host"); bool hasHeader = RequestHeaders.ContainsKey("host");
return hasHeader ? RequestHeaders["host"].Value : null; return hasHeader ? RequestHeaders["host"].Value : null;
} }
set set
{ {
var hasHeader = RequestHeaders.ContainsKey("host"); bool hasHeader = RequestHeaders.ContainsKey("host");
if (hasHeader) if (hasHeader)
{ {
RequestHeaders["host"].Value = value; RequestHeaders["host"].Value = value;
...@@ -65,7 +65,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -65,7 +65,7 @@ namespace Titanium.Web.Proxy.Http
{ {
get get
{ {
var hasHeader = RequestHeaders.ContainsKey("content-encoding"); bool hasHeader = RequestHeaders.ContainsKey("content-encoding");
if (hasHeader) if (hasHeader)
{ {
...@@ -83,7 +83,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -83,7 +83,7 @@ namespace Titanium.Web.Proxy.Http
{ {
get get
{ {
var hasHeader = RequestHeaders.ContainsKey("content-length"); bool hasHeader = RequestHeaders.ContainsKey("content-length");
if (hasHeader == false) if (hasHeader == false)
{ {
...@@ -103,7 +103,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -103,7 +103,7 @@ namespace Titanium.Web.Proxy.Http
} }
set set
{ {
var hasHeader = RequestHeaders.ContainsKey("content-length"); bool hasHeader = RequestHeaders.ContainsKey("content-length");
var header = RequestHeaders["content-length"]; var header = RequestHeaders["content-length"];
...@@ -137,7 +137,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -137,7 +137,7 @@ namespace Titanium.Web.Proxy.Http
{ {
get get
{ {
var hasHeader = RequestHeaders.ContainsKey("content-type"); bool hasHeader = RequestHeaders.ContainsKey("content-type");
if (hasHeader) if (hasHeader)
{ {
...@@ -149,7 +149,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -149,7 +149,7 @@ namespace Titanium.Web.Proxy.Http
} }
set set
{ {
var hasHeader = RequestHeaders.ContainsKey("content-type"); bool hasHeader = RequestHeaders.ContainsKey("content-type");
if (hasHeader) if (hasHeader)
{ {
...@@ -170,7 +170,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -170,7 +170,7 @@ namespace Titanium.Web.Proxy.Http
{ {
get get
{ {
var hasHeader = RequestHeaders.ContainsKey("transfer-encoding"); bool hasHeader = RequestHeaders.ContainsKey("transfer-encoding");
if (hasHeader) if (hasHeader)
{ {
...@@ -183,7 +183,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -183,7 +183,7 @@ namespace Titanium.Web.Proxy.Http
} }
set set
{ {
var hasHeader = RequestHeaders.ContainsKey("transfer-encoding"); bool hasHeader = RequestHeaders.ContainsKey("transfer-encoding");
if (value) if (value)
{ {
...@@ -216,9 +216,10 @@ namespace Titanium.Web.Proxy.Http ...@@ -216,9 +216,10 @@ namespace Titanium.Web.Proxy.Http
{ {
get get
{ {
var hasHeader = RequestHeaders.ContainsKey("expect"); bool hasHeader = RequestHeaders.ContainsKey("expect");
if (!hasHeader) return false; if (!hasHeader)
return false;
var header = RequestHeaders["expect"]; var header = RequestHeaders["expect"];
return header.Value.Equals("100-continue"); return header.Value.Equals("100-continue");
...@@ -267,7 +268,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -267,7 +268,7 @@ namespace Titanium.Web.Proxy.Http
{ {
get get
{ {
var hasHeader = RequestHeaders.ContainsKey("upgrade"); bool hasHeader = RequestHeaders.ContainsKey("upgrade");
if (hasHeader == false) if (hasHeader == false)
{ {
...@@ -317,8 +318,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -317,8 +318,7 @@ namespace Titanium.Web.Proxy.Http
/// <returns></returns> /// <returns></returns>
public bool HeaderExists(string name) public bool HeaderExists(string name)
{ {
if (RequestHeaders.ContainsKey(name) if (RequestHeaders.ContainsKey(name) || NonUniqueRequestHeaders.ContainsKey(name))
|| NonUniqueRequestHeaders.ContainsKey(name))
{ {
return true; return true;
} }
...@@ -336,9 +336,12 @@ namespace Titanium.Web.Proxy.Http ...@@ -336,9 +336,12 @@ namespace Titanium.Web.Proxy.Http
{ {
if (RequestHeaders.ContainsKey(name)) if (RequestHeaders.ContainsKey(name))
{ {
return new List<HttpHeader>() { RequestHeaders[name] }; return new List<HttpHeader>
{
RequestHeaders[name]
};
} }
else if (NonUniqueRequestHeaders.ContainsKey(name)) if (NonUniqueRequestHeaders.ContainsKey(name))
{ {
return new List<HttpHeader>(NonUniqueRequestHeaders[name]); return new List<HttpHeader>(NonUniqueRequestHeaders[name]);
} }
...@@ -387,8 +390,11 @@ namespace Titanium.Web.Proxy.Http ...@@ -387,8 +390,11 @@ namespace Titanium.Web.Proxy.Http
var existing = RequestHeaders[newHeader.Name]; var existing = RequestHeaders[newHeader.Name];
RequestHeaders.Remove(newHeader.Name); RequestHeaders.Remove(newHeader.Name);
NonUniqueRequestHeaders.Add(newHeader.Name, NonUniqueRequestHeaders.Add(newHeader.Name, new List<HttpHeader>
new List<HttpHeader>() { existing, newHeader }); {
existing,
newHeader
});
} }
else else
{ {
...@@ -409,7 +415,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -409,7 +415,7 @@ namespace Titanium.Web.Proxy.Http
RequestHeaders.Remove(headerName); RequestHeaders.Remove(headerName);
return true; return true;
} }
else if (NonUniqueRequestHeaders.ContainsKey(headerName)) if (NonUniqueRequestHeaders.ContainsKey(headerName))
{ {
NonUniqueRequestHeaders.Remove(headerName); NonUniqueRequestHeaders.Remove(headerName);
return true; return true;
...@@ -431,12 +437,10 @@ namespace Titanium.Web.Proxy.Http ...@@ -431,12 +437,10 @@ namespace Titanium.Web.Proxy.Http
RequestHeaders.Remove(header.Name); RequestHeaders.Remove(header.Name);
return true; return true;
} }
} }
else if (NonUniqueRequestHeaders.ContainsKey(header.Name)) else if (NonUniqueRequestHeaders.ContainsKey(header.Name))
{ {
if (NonUniqueRequestHeaders[header.Name] if (NonUniqueRequestHeaders[header.Name].RemoveAll(x => x.Equals(header)) > 0)
.RemoveAll(x => x.Equals(header)) > 0)
{ {
return true; return true;
} }
...@@ -460,7 +464,5 @@ namespace Titanium.Web.Proxy.Http ...@@ -460,7 +464,5 @@ namespace Titanium.Web.Proxy.Http
RequestBody = null; RequestBody = null;
RequestBody = null; RequestBody = null;
} }
} }
} }
using System; using System;
using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.Linq;
using System.Text; using System.Text;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
...@@ -35,9 +34,10 @@ namespace Titanium.Web.Proxy.Http ...@@ -35,9 +34,10 @@ namespace Titanium.Web.Proxy.Http
{ {
get get
{ {
var hasHeader = ResponseHeaders.ContainsKey("content-encoding"); bool hasHeader = ResponseHeaders.ContainsKey("content-encoding");
if (!hasHeader) return null; if (!hasHeader)
return null;
var header = ResponseHeaders["content-encoding"]; var header = ResponseHeaders["content-encoding"];
return header.Value.Trim(); return header.Value.Trim();
...@@ -56,7 +56,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -56,7 +56,7 @@ namespace Titanium.Web.Proxy.Http
{ {
get get
{ {
var hasHeader = ResponseHeaders.ContainsKey("connection"); bool hasHeader = ResponseHeaders.ContainsKey("connection");
if (hasHeader) if (hasHeader)
{ {
...@@ -79,7 +79,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -79,7 +79,7 @@ namespace Titanium.Web.Proxy.Http
{ {
get get
{ {
var hasHeader = ResponseHeaders.ContainsKey("content-type"); bool hasHeader = ResponseHeaders.ContainsKey("content-type");
if (hasHeader) if (hasHeader)
{ {
...@@ -99,7 +99,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -99,7 +99,7 @@ namespace Titanium.Web.Proxy.Http
{ {
get get
{ {
var hasHeader = ResponseHeaders.ContainsKey("content-length"); bool hasHeader = ResponseHeaders.ContainsKey("content-length");
if (hasHeader == false) if (hasHeader == false)
{ {
...@@ -119,7 +119,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -119,7 +119,7 @@ namespace Titanium.Web.Proxy.Http
} }
set set
{ {
var hasHeader = ResponseHeaders.ContainsKey("content-length"); bool hasHeader = ResponseHeaders.ContainsKey("content-length");
if (value >= 0) if (value >= 0)
{ {
...@@ -152,7 +152,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -152,7 +152,7 @@ namespace Titanium.Web.Proxy.Http
{ {
get get
{ {
var hasHeader = ResponseHeaders.ContainsKey("transfer-encoding"); bool hasHeader = ResponseHeaders.ContainsKey("transfer-encoding");
if (hasHeader) if (hasHeader)
{ {
...@@ -168,7 +168,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -168,7 +168,7 @@ namespace Titanium.Web.Proxy.Http
} }
set set
{ {
var hasHeader = ResponseHeaders.ContainsKey("transfer-encoding"); bool hasHeader = ResponseHeaders.ContainsKey("transfer-encoding");
if (value) if (value)
{ {
...@@ -250,8 +250,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -250,8 +250,7 @@ namespace Titanium.Web.Proxy.Http
/// <returns></returns> /// <returns></returns>
public bool HeaderExists(string name) public bool HeaderExists(string name)
{ {
if(ResponseHeaders.ContainsKey(name) if (ResponseHeaders.ContainsKey(name) || NonUniqueResponseHeaders.ContainsKey(name))
|| NonUniqueResponseHeaders.ContainsKey(name))
{ {
return true; return true;
} }
...@@ -269,9 +268,12 @@ namespace Titanium.Web.Proxy.Http ...@@ -269,9 +268,12 @@ namespace Titanium.Web.Proxy.Http
{ {
if (ResponseHeaders.ContainsKey(name)) if (ResponseHeaders.ContainsKey(name))
{ {
return new List<HttpHeader>() { ResponseHeaders[name] }; return new List<HttpHeader>
{
ResponseHeaders[name]
};
} }
else if (NonUniqueResponseHeaders.ContainsKey(name)) if (NonUniqueResponseHeaders.ContainsKey(name))
{ {
return new List<HttpHeader>(NonUniqueResponseHeaders[name]); return new List<HttpHeader>(NonUniqueResponseHeaders[name]);
} }
...@@ -320,8 +322,11 @@ namespace Titanium.Web.Proxy.Http ...@@ -320,8 +322,11 @@ namespace Titanium.Web.Proxy.Http
var existing = ResponseHeaders[newHeader.Name]; var existing = ResponseHeaders[newHeader.Name];
ResponseHeaders.Remove(newHeader.Name); ResponseHeaders.Remove(newHeader.Name);
NonUniqueResponseHeaders.Add(newHeader.Name, NonUniqueResponseHeaders.Add(newHeader.Name, new List<HttpHeader>
new List<HttpHeader>() { existing, newHeader }); {
existing,
newHeader
});
} }
else else
{ {
...@@ -337,12 +342,12 @@ namespace Titanium.Web.Proxy.Http ...@@ -337,12 +342,12 @@ namespace Titanium.Web.Proxy.Http
/// False if no header exists with given name</returns> /// False if no header exists with given name</returns>
public bool RemoveHeader(string headerName) public bool RemoveHeader(string headerName)
{ {
if(ResponseHeaders.ContainsKey(headerName)) if (ResponseHeaders.ContainsKey(headerName))
{ {
ResponseHeaders.Remove(headerName); ResponseHeaders.Remove(headerName);
return true; return true;
} }
else if (NonUniqueResponseHeaders.ContainsKey(headerName)) if (NonUniqueResponseHeaders.ContainsKey(headerName))
{ {
NonUniqueResponseHeaders.Remove(headerName); NonUniqueResponseHeaders.Remove(headerName);
return true; return true;
...@@ -364,12 +369,10 @@ namespace Titanium.Web.Proxy.Http ...@@ -364,12 +369,10 @@ namespace Titanium.Web.Proxy.Http
ResponseHeaders.Remove(header.Name); ResponseHeaders.Remove(header.Name);
return true; return true;
} }
} }
else if (NonUniqueResponseHeaders.ContainsKey(header.Name)) else if (NonUniqueResponseHeaders.ContainsKey(header.Name))
{ {
if (NonUniqueResponseHeaders[header.Name] if (NonUniqueResponseHeaders[header.Name].RemoveAll(x => x.Equals(header)) > 0)
.RemoveAll(x => x.Equals(header)) > 0)
{ {
return true; return true;
} }
......
...@@ -53,7 +53,6 @@ namespace Titanium.Web.Proxy.Models ...@@ -53,7 +53,6 @@ namespace Titanium.Web.Proxy.Models
public bool IpV6Enabled => Equals(IpAddress, IPAddress.IPv6Any) public bool IpV6Enabled => Equals(IpAddress, IPAddress.IPv6Any)
|| Equals(IpAddress, IPAddress.IPv6Loopback) || Equals(IpAddress, IPAddress.IPv6Loopback)
|| Equals(IpAddress, IPAddress.IPv6None); || Equals(IpAddress, IPAddress.IPv6None);
} }
/// <summary> /// <summary>
...@@ -120,11 +119,14 @@ namespace Titanium.Web.Proxy.Models ...@@ -120,11 +119,14 @@ namespace Titanium.Web.Proxy.Models
/// <param name="ipAddress"></param> /// <param name="ipAddress"></param>
/// <param name="port"></param> /// <param name="port"></param>
/// <param name="enableSsl"></param> /// <param name="enableSsl"></param>
public ExplicitProxyEndPoint(IPAddress ipAddress, int port, bool enableSsl) public ExplicitProxyEndPoint(IPAddress ipAddress, int port, bool enableSsl) : base(ipAddress, port, enableSsl)
: base(ipAddress, port, enableSsl)
{ {
//init to well known HTTPS ports //init to well known HTTPS ports
RemoteHttpsPorts = new List<int> { 443, 8443 }; RemoteHttpsPorts = new List<int>
{
443,
8443
};
} }
} }
...@@ -146,8 +148,7 @@ namespace Titanium.Web.Proxy.Models ...@@ -146,8 +148,7 @@ namespace Titanium.Web.Proxy.Models
/// <param name="ipAddress"></param> /// <param name="ipAddress"></param>
/// <param name="port"></param> /// <param name="port"></param>
/// <param name="enableSsl"></param> /// <param name="enableSsl"></param>
public TransparentProxyEndPoint(IPAddress ipAddress, int port, bool enableSsl) public TransparentProxyEndPoint(IPAddress ipAddress, int port, bool enableSsl) : base(ipAddress, port, enableSsl)
: base(ipAddress, port, enableSsl)
{ {
GenericCertificateName = "localhost"; GenericCertificateName = "localhost";
} }
......
...@@ -81,14 +81,10 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -81,14 +81,10 @@ namespace Titanium.Web.Proxy.Network.Certificate
if (hostName != null) if (hostName != null)
{ {
//add subject alternative names //add subject alternative names
var subjectAlternativeNames = new Asn1Encodable[] var subjectAlternativeNames = new Asn1Encodable[] { new GeneralName(GeneralName.DnsName, hostName), };
{
new GeneralName(GeneralName.DnsName, hostName),
};
var subjectAlternativeNamesExtension = new DerSequence(subjectAlternativeNames); var subjectAlternativeNamesExtension = new DerSequence(subjectAlternativeNames);
certificateGenerator.AddExtension( certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName.Id, false, subjectAlternativeNamesExtension);
X509Extensions.SubjectAlternativeName.Id, false, subjectAlternativeNamesExtension);
} }
// Subject Public Key // Subject Public Key
var keyGenerationParameters = new KeyGenerationParameters(secureRandom, keyStrength); var keyGenerationParameters = new KeyGenerationParameters(secureRandom, keyStrength);
...@@ -118,7 +114,8 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -118,7 +114,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
} }
var rsa = RsaPrivateKeyStructure.GetInstance(seq); var rsa = RsaPrivateKeyStructure.GetInstance(seq);
var rsaparams = new RsaPrivateCrtKeyParameters(rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient); var rsaparams = new RsaPrivateCrtKeyParameters(rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1,
rsa.Exponent2, rsa.Coefficient);
// Set private key onto certificate instance // Set private key onto certificate instance
x509Certificate.PrivateKey = DotNetUtilities.ToRSA(rsaparams); x509Certificate.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
...@@ -138,9 +135,8 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -138,9 +135,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// <param name="signingCertificate">The signing certificate.</param> /// <param name="signingCertificate">The signing certificate.</param>
/// <returns>X509Certificate2 instance.</returns> /// <returns>X509Certificate2 instance.</returns>
/// <exception cref="System.ArgumentException">You must specify a Signing Certificate if and only if you are not creating a root.</exception> /// <exception cref="System.ArgumentException">You must specify a Signing Certificate if and only if you are not creating a root.</exception>
private X509Certificate2 MakeCertificateInternal(bool isRoot, private X509Certificate2 MakeCertificateInternal(bool isRoot, string hostName, string subjectName, DateTime validFrom, DateTime validTo,
string hostName, string subjectName, X509Certificate2 signingCertificate)
DateTime validFrom, DateTime validTo, X509Certificate2 signingCertificate)
{ {
if (isRoot != (null == signingCertificate)) if (isRoot != (null == signingCertificate))
{ {
...@@ -149,7 +145,8 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -149,7 +145,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
return isRoot return isRoot
? GenerateCertificate(null, subjectName, subjectName, validFrom, validTo) ? GenerateCertificate(null, subjectName, subjectName, validFrom, validTo)
: GenerateCertificate(hostName, subjectName, signingCertificate.Subject, validFrom, validTo, issuerPrivateKey: DotNetUtilities.GetKeyPair(signingCertificate.PrivateKey).Private); : GenerateCertificate(hostName, subjectName, signingCertificate.Subject, validFrom, validTo,
issuerPrivateKey: DotNetUtilities.GetKeyPair(signingCertificate.PrivateKey).Private);
} }
/// <summary> /// <summary>
...@@ -187,7 +184,8 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -187,7 +184,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
return certificate; return certificate;
} }
return MakeCertificateInternal(isRoot, subject, $"CN={subject}", DateTime.UtcNow.AddDays(-certificateGraceDays), DateTime.UtcNow.AddDays(certificateValidDays), isRoot ? null : signingCert); return MakeCertificateInternal(isRoot, subject, $"CN={subject}", DateTime.UtcNow.AddDays(-certificateGraceDays),
DateTime.UtcNow.AddDays(certificateValidDays), isRoot ? null : signingCert);
} }
} }
} }
...@@ -239,8 +239,6 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -239,8 +239,6 @@ namespace Titanium.Web.Proxy.Network.Certificate
typeX509Enrollment.InvokeMember("CertificateFriendlyName", BindingFlags.PutDispProperty, null, x509Enrollment, typeValue); typeX509Enrollment.InvokeMember("CertificateFriendlyName", BindingFlags.PutDispProperty, null, x509Enrollment, typeValue);
} }
var members = typeX509Enrollment.GetMembers();
typeValue[0] = 0; typeValue[0] = 0;
var createCertRequest = typeX509Enrollment.InvokeMember("CreateRequest", BindingFlags.InvokeMethod, null, x509Enrollment, typeValue); var createCertRequest = typeX509Enrollment.InvokeMember("CreateRequest", BindingFlags.InvokeMethod, null, x509Enrollment, typeValue);
...@@ -251,7 +249,7 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -251,7 +249,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
try try
{ {
var empty = (string)typeX509Enrollment.InvokeMember("CreatePFX", BindingFlags.InvokeMethod, null, x509Enrollment, typeValue); string empty = (string)typeX509Enrollment.InvokeMember("CreatePFX", BindingFlags.InvokeMethod, null, x509Enrollment, typeValue);
return new X509Certificate2(Convert.FromBase64String(empty), string.Empty, X509KeyStorageFlags.Exportable); return new X509Certificate2(Convert.FromBase64String(empty), string.Empty, X509KeyStorageFlags.Exportable);
} }
catch (Exception) catch (Exception)
...@@ -281,15 +279,15 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -281,15 +279,15 @@ namespace Titanium.Web.Proxy.Network.Certificate
} }
//Subject //Subject
var fullSubject = $"CN={sSubjectCN}"; string fullSubject = $"CN={sSubjectCN}";
//Sig Algo //Sig Algo
var HashAlgo = "SHA256"; string HashAlgo = "SHA256";
//Grace Days //Grace Days
var GraceDays = -366; int GraceDays = -366;
//ValiDays //ValiDays
var ValidDays = 1825; int ValidDays = 1825;
//KeyLength //KeyLength
var keyLength = 2048; int keyLength = 2048;
var graceTime = DateTime.Now.AddDays(GraceDays); var graceTime = DateTime.Now.AddDays(GraceDays);
var now = DateTime.Now; var now = DateTime.Now;
......
...@@ -52,9 +52,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -52,9 +52,7 @@ namespace Titanium.Web.Proxy.Network
if (certEngine == null) if (certEngine == null)
{ {
certEngine = engine == CertificateEngine.BouncyCastle certEngine = engine == CertificateEngine.BouncyCastle ? (ICertificateMaker)new BCCertificateMaker() : new WinCertificateMaker();
? (ICertificateMaker)new BCCertificateMaker()
: new WinCertificateMaker();
} }
} }
} }
...@@ -134,7 +132,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -134,7 +132,7 @@ namespace Titanium.Web.Proxy.Network
private string GetRootCertificatePath() private string GetRootCertificatePath()
{ {
var assemblyLocation = Assembly.GetExecutingAssembly().Location; string assemblyLocation = Assembly.GetExecutingAssembly().Location;
// dynamically loaded assemblies returns string.Empty location // dynamically loaded assemblies returns string.Empty location
if (assemblyLocation == string.Empty) if (assemblyLocation == string.Empty)
...@@ -142,16 +140,18 @@ namespace Titanium.Web.Proxy.Network ...@@ -142,16 +140,18 @@ namespace Titanium.Web.Proxy.Network
assemblyLocation = Assembly.GetEntryAssembly().Location; assemblyLocation = Assembly.GetEntryAssembly().Location;
} }
var path = Path.GetDirectoryName(assemblyLocation); string path = Path.GetDirectoryName(assemblyLocation);
if (null == path) throw new NullReferenceException(); if (null == path)
var fileName = Path.Combine(path, "rootCert.pfx"); throw new NullReferenceException();
string fileName = Path.Combine(path, "rootCert.pfx");
return fileName; return fileName;
} }
private X509Certificate2 LoadRootCertificate() private X509Certificate2 LoadRootCertificate()
{ {
var fileName = GetRootCertificatePath(); string fileName = GetRootCertificatePath();
if (!File.Exists(fileName)) return null; if (!File.Exists(fileName))
return null;
try try
{ {
return new X509Certificate2(fileName, string.Empty, X509KeyStorageFlags.Exportable); return new X509Certificate2(fileName, string.Empty, X509KeyStorageFlags.Exportable);
...@@ -195,7 +195,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -195,7 +195,7 @@ namespace Titanium.Web.Proxy.Network
{ {
try try
{ {
var fileName = GetRootCertificatePath(); string fileName = GetRootCertificatePath();
File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12)); File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12));
} }
catch (Exception e) catch (Exception e)
...@@ -231,7 +231,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -231,7 +231,7 @@ namespace Titanium.Web.Proxy.Network
return false; return false;
} }
var fileName = Path.GetTempFileName(); string fileName = Path.GetTempFileName();
File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12)); File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12));
var info = new ProcessStartInfo var info = new ProcessStartInfo
...@@ -340,7 +340,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -340,7 +340,7 @@ namespace Titanium.Web.Proxy.Network
private X509Certificate2Collection FindCertificates(StoreName storeName, StoreLocation storeLocation, string findValue) private X509Certificate2Collection FindCertificates(StoreName storeName, StoreLocation storeLocation, string findValue)
{ {
X509Store x509Store = new X509Store(storeName, storeLocation); var x509Store = new X509Store(storeName, storeLocation);
try try
{ {
x509Store.Open(OpenFlags.OpenExistingOnly); x509Store.Open(OpenFlags.OpenExistingOnly);
...@@ -387,7 +387,10 @@ namespace Titanium.Web.Proxy.Network ...@@ -387,7 +387,10 @@ namespace Titanium.Web.Proxy.Network
} }
if (certificate != null && !certificateCache.ContainsKey(certificateName)) if (certificate != null && !certificateCache.ContainsKey(certificateName))
{ {
certificateCache.Add(certificateName, new CachedCertificate { Certificate = certificate }); certificateCache.Add(certificateName, new CachedCertificate
{
Certificate = certificate
});
} }
} }
else else
...@@ -422,9 +425,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -422,9 +425,7 @@ namespace Titanium.Web.Proxy.Network
{ {
var cutOff = DateTime.Now.AddMinutes(-1 * certificateCacheTimeOutMinutes); var cutOff = DateTime.Now.AddMinutes(-1 * certificateCacheTimeOutMinutes);
var outdated = certificateCache var outdated = certificateCache.Where(x => x.Value.LastAccess < cutOff).ToList();
.Where(x => x.Value.LastAccess < cutOff)
.ToList();
foreach (var cache in outdated) foreach (var cache in outdated)
certificateCache.Remove(cache.Key); certificateCache.Remove(cache.Key);
......
...@@ -29,22 +29,17 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -29,22 +29,17 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <param name="externalHttpProxy"></param> /// <param name="externalHttpProxy"></param>
/// <param name="externalHttpsProxy"></param> /// <param name="externalHttpsProxy"></param>
/// <returns></returns> /// <returns></returns>
internal async Task<TcpConnection> CreateClient(ProxyServer server, internal async Task<TcpConnection> CreateClient(ProxyServer server, string remoteHostName, int remotePort, Version httpVersion, bool isHttps,
string remoteHostName, int remotePort, Version httpVersion,
bool isHttps,
ExternalProxy externalHttpProxy, ExternalProxy externalHttpsProxy) ExternalProxy externalHttpProxy, ExternalProxy externalHttpsProxy)
{ {
bool useHttpProxy = false; bool useHttpProxy = false;
//check if external proxy is set for HTTP //check if external proxy is set for HTTP
if (!isHttps && externalHttpProxy != null if (!isHttps && externalHttpProxy != null && !(externalHttpProxy.HostName == remoteHostName && externalHttpProxy.Port == remotePort))
&& !(externalHttpProxy.HostName == remoteHostName
&& externalHttpProxy.Port == remotePort))
{ {
useHttpProxy = true; useHttpProxy = true;
//check if we need to ByPass //check if we need to ByPass
if (externalHttpProxy.BypassLocalhost if (externalHttpProxy.BypassLocalhost && NetworkHelper.IsLocalIpAddress(remoteHostName))
&& NetworkHelper.IsLocalIpAddress(remoteHostName))
{ {
useHttpProxy = false; useHttpProxy = false;
} }
...@@ -52,15 +47,12 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -52,15 +47,12 @@ namespace Titanium.Web.Proxy.Network.Tcp
bool useHttpsProxy = false; bool useHttpsProxy = false;
//check if external proxy is set for HTTPS //check if external proxy is set for HTTPS
if (isHttps && externalHttpsProxy != null if (isHttps && externalHttpsProxy != null && !(externalHttpsProxy.HostName == remoteHostName && externalHttpsProxy.Port == remotePort))
&& !(externalHttpsProxy.HostName == remoteHostName
&& externalHttpsProxy.Port == remotePort))
{ {
useHttpsProxy = true; useHttpsProxy = true;
//check if we need to ByPass //check if we need to ByPass
if (externalHttpsProxy.BypassLocalhost if (externalHttpsProxy.BypassLocalhost && NetworkHelper.IsLocalIpAddress(remoteHostName))
&& NetworkHelper.IsLocalIpAddress(remoteHostName))
{ {
useHttpsProxy = false; useHttpsProxy = false;
} }
...@@ -80,7 +72,10 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -80,7 +72,10 @@ namespace Titanium.Web.Proxy.Network.Tcp
await client.ConnectAsync(externalHttpsProxy.HostName, externalHttpsProxy.Port); await client.ConnectAsync(externalHttpsProxy.HostName, externalHttpsProxy.Port);
stream = new CustomBufferedStream(client.GetStream(), server.BufferSize); stream = new CustomBufferedStream(client.GetStream(), server.BufferSize);
using (var writer = new StreamWriter(stream, Encoding.ASCII, server.BufferSize, true) { NewLine = ProxyConstants.NewLine }) using (var writer = new StreamWriter(stream, Encoding.ASCII, server.BufferSize, true)
{
NewLine = ProxyConstants.NewLine
})
{ {
await writer.WriteLineAsync($"CONNECT {remoteHostName}:{remotePort} HTTP/{httpVersion}"); await writer.WriteLineAsync($"CONNECT {remoteHostName}:{remotePort} HTTP/{httpVersion}");
await writer.WriteLineAsync($"Host: {remoteHostName}:{remotePort}"); await writer.WriteLineAsync($"Host: {remoteHostName}:{remotePort}");
...@@ -89,7 +84,9 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -89,7 +84,9 @@ namespace Titanium.Web.Proxy.Network.Tcp
if (!string.IsNullOrEmpty(externalHttpsProxy.UserName) && externalHttpsProxy.Password != null) if (!string.IsNullOrEmpty(externalHttpsProxy.UserName) && externalHttpsProxy.Password != null)
{ {
await writer.WriteLineAsync("Proxy-Connection: keep-alive"); await writer.WriteLineAsync("Proxy-Connection: keep-alive");
await writer.WriteLineAsync("Proxy-Authorization" + ": Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(externalHttpsProxy.UserName + ":" + externalHttpsProxy.Password))); await writer.WriteLineAsync("Proxy-Authorization" + ": Basic " +
Convert.ToBase64String(Encoding.UTF8.GetBytes(
externalHttpsProxy.UserName + ":" + externalHttpsProxy.Password)));
} }
await writer.WriteLineAsync(); await writer.WriteLineAsync();
await writer.FlushAsync(); await writer.FlushAsync();
...@@ -98,7 +95,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -98,7 +95,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
using (var reader = new CustomBinaryReader(stream, server.BufferSize)) using (var reader = new CustomBinaryReader(stream, server.BufferSize))
{ {
var result = await reader.ReadLineAsync(); string result = await reader.ReadLineAsync();
if (!new[] { "200 OK", "connection established" }.Any(s => result.ContainsIgnoreCase(s))) if (!new[] { "200 OK", "connection established" }.Any(s => result.ContainsIgnoreCase(s)))
{ {
......
...@@ -11,21 +11,19 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -11,21 +11,19 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// </seealso> /// </seealso>
internal class TcpTable : IEnumerable<TcpRow> internal class TcpTable : IEnumerable<TcpRow>
{ {
private readonly IEnumerable<TcpRow> tcpRows;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="TcpTable"/> class. /// Initializes a new instance of the <see cref="TcpTable"/> class.
/// </summary> /// </summary>
/// <param name="tcpRows">TcpRow collection to initialize with.</param> /// <param name="tcpRows">TcpRow collection to initialize with.</param>
internal TcpTable(IEnumerable<TcpRow> tcpRows) internal TcpTable(IEnumerable<TcpRow> tcpRows)
{ {
this.tcpRows = tcpRows; this.TcpRows = tcpRows;
} }
/// <summary> /// <summary>
/// Gets the TCP rows. /// Gets the TCP rows.
/// </summary> /// </summary>
internal IEnumerable<TcpRow> TcpRows => tcpRows; internal IEnumerable<TcpRow> TcpRows { get; }
/// <summary> /// <summary>
/// Returns an enumerator that iterates through the collection. /// Returns an enumerator that iterates through the collection.
...@@ -33,7 +31,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -33,7 +31,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <returns>An enumerator that can be used to iterate through the collection.</returns> /// <returns>An enumerator that can be used to iterate through the collection.</returns>
public IEnumerator<TcpRow> GetEnumerator() public IEnumerator<TcpRow> GetEnumerator()
{ {
return tcpRows.GetEnumerator(); return TcpRows.GetEnumerator();
} }
/// <summary> /// <summary>
......
...@@ -27,229 +27,224 @@ ...@@ -27,229 +27,224 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //
using System;
namespace Titanium.Web.Proxy.Network.WinAuth.Security namespace Titanium.Web.Proxy.Network.WinAuth.Security
{ {
using System;
internal sealed class LittleEndian internal sealed class LittleEndian
{ {
private LittleEndian () private LittleEndian()
{ {
} }
unsafe private static byte[] GetUShortBytes (byte *bytes) private static unsafe byte[] GetUShortBytes(byte*bytes)
{ {
if (BitConverter.IsLittleEndian) if (BitConverter.IsLittleEndian)
{ {
return new byte[] { bytes[0], bytes[1] }; return new[] { bytes[0], bytes[1] };
}
else
{
return new byte[] { bytes[1], bytes[0] };
} }
return new[] { bytes[1], bytes[0] };
} }
unsafe private static byte[] GetUIntBytes (byte *bytes) private static unsafe byte[] GetUIntBytes(byte*bytes)
{ {
if (BitConverter.IsLittleEndian) if (BitConverter.IsLittleEndian)
{ {
return new byte[] { bytes[0], bytes[1], bytes[2], bytes[3] }; return new[] { bytes[0], bytes[1], bytes[2], bytes[3] };
}
else
{
return new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] };
} }
return new[] { bytes[3], bytes[2], bytes[1], bytes[0] };
} }
unsafe private static byte[] GetULongBytes (byte *bytes) private static unsafe byte[] GetULongBytes(byte*bytes)
{ {
if (BitConverter.IsLittleEndian) if (BitConverter.IsLittleEndian)
{ {
return new byte[] { bytes [0], bytes [1], bytes [2], bytes [3], return new[] { bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7] };
bytes [4], bytes [5], bytes [6], bytes [7] };
}
else
{
return new byte[] { bytes [7], bytes [6], bytes [5], bytes [4],
bytes [3], bytes [2], bytes [1], bytes [0] };
} }
return new[] { bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0] };
} }
unsafe internal static byte[] GetBytes (bool value) internal static byte[] GetBytes(bool value)
{ {
return new byte [] { value ? (byte)1 : (byte)0 }; return new[] { value ? (byte)1 : (byte)0 };
} }
unsafe internal static byte[] GetBytes (char value) internal static unsafe byte[] GetBytes(char value)
{ {
return GetUShortBytes ((byte *) &value); return GetUShortBytes((byte*)&value);
} }
unsafe internal static byte[] GetBytes (short value) internal static unsafe byte[] GetBytes(short value)
{ {
return GetUShortBytes ((byte *) &value); return GetUShortBytes((byte*)&value);
} }
unsafe internal static byte[] GetBytes (int value) internal static unsafe byte[] GetBytes(int value)
{ {
return GetUIntBytes ((byte *) &value); return GetUIntBytes((byte*)&value);
} }
unsafe internal static byte[] GetBytes (long value) internal static unsafe byte[] GetBytes(long value)
{ {
return GetULongBytes ((byte *) &value); return GetULongBytes((byte*)&value);
} }
unsafe internal static byte[] GetBytes (ushort value) internal static unsafe byte[] GetBytes(ushort value)
{ {
return GetUShortBytes ((byte *) &value); return GetUShortBytes((byte*)&value);
} }
unsafe internal static byte[] GetBytes (uint value) internal static unsafe byte[] GetBytes(uint value)
{ {
return GetUIntBytes ((byte *) &value); return GetUIntBytes((byte*)&value);
} }
unsafe internal static byte[] GetBytes (ulong value) internal static unsafe byte[] GetBytes(ulong value)
{ {
return GetULongBytes ((byte *) &value); return GetULongBytes((byte*)&value);
} }
unsafe internal static byte[] GetBytes (float value) internal static unsafe byte[] GetBytes(float value)
{ {
return GetUIntBytes ((byte *) &value); return GetUIntBytes((byte*)&value);
} }
unsafe internal static byte[] GetBytes (double value) internal static unsafe byte[] GetBytes(double value)
{ {
return GetULongBytes ((byte *) &value); return GetULongBytes((byte*)&value);
} }
unsafe private static void UShortFromBytes (byte *dst, byte[] src, int startIndex) private static unsafe void UShortFromBytes(byte*dst, byte[] src, int startIndex)
{ {
if (BitConverter.IsLittleEndian) if (BitConverter.IsLittleEndian)
{ {
dst [0] = src [startIndex]; dst[0] = src[startIndex];
dst [1] = src [startIndex + 1]; dst[1] = src[startIndex + 1];
} }
else else
{ {
dst [0] = src [startIndex + 1]; dst[0] = src[startIndex + 1];
dst [1] = src [startIndex]; dst[1] = src[startIndex];
} }
} }
unsafe private static void UIntFromBytes (byte *dst, byte[] src, int startIndex) private static unsafe void UIntFromBytes(byte*dst, byte[] src, int startIndex)
{ {
if (BitConverter.IsLittleEndian) if (BitConverter.IsLittleEndian)
{ {
dst [0] = src [startIndex]; dst[0] = src[startIndex];
dst [1] = src [startIndex + 1]; dst[1] = src[startIndex + 1];
dst [2] = src [startIndex + 2]; dst[2] = src[startIndex + 2];
dst [3] = src [startIndex + 3]; dst[3] = src[startIndex + 3];
} }
else else
{ {
dst [0] = src [startIndex + 3]; dst[0] = src[startIndex + 3];
dst [1] = src [startIndex + 2]; dst[1] = src[startIndex + 2];
dst [2] = src [startIndex + 1]; dst[2] = src[startIndex + 1];
dst [3] = src [startIndex]; dst[3] = src[startIndex];
} }
} }
unsafe private static void ULongFromBytes (byte *dst, byte[] src, int startIndex) private static unsafe void ULongFromBytes(byte*dst, byte[] src, int startIndex)
{
if (BitConverter.IsLittleEndian)
{ {
if (BitConverter.IsLittleEndian) {
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
dst [i] = src [startIndex + i]; dst[i] = src[startIndex + i];
} else { }
else
{
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
dst [i] = src [startIndex + (7 - i)]; dst[i] = src[startIndex + (7 - i)];
} }
} }
unsafe internal static bool ToBoolean (byte[] value, int startIndex) internal static bool ToBoolean(byte[] value, int startIndex)
{ {
return value [startIndex] != 0; return value[startIndex] != 0;
} }
unsafe internal static char ToChar (byte[] value, int startIndex) internal static unsafe char ToChar(byte[] value, int startIndex)
{ {
char ret; char ret;
UShortFromBytes ((byte *) &ret, value, startIndex); UShortFromBytes((byte*)&ret, value, startIndex);
return ret; return ret;
} }
unsafe internal static short ToInt16 (byte[] value, int startIndex) internal static unsafe short ToInt16(byte[] value, int startIndex)
{ {
short ret; short ret;
UShortFromBytes ((byte *) &ret, value, startIndex); UShortFromBytes((byte*)&ret, value, startIndex);
return ret; return ret;
} }
unsafe internal static int ToInt32 (byte[] value, int startIndex) internal static unsafe int ToInt32(byte[] value, int startIndex)
{ {
int ret; int ret;
UIntFromBytes ((byte *) &ret, value, startIndex); UIntFromBytes((byte*)&ret, value, startIndex);
return ret; return ret;
} }
unsafe internal static long ToInt64 (byte[] value, int startIndex) internal static unsafe long ToInt64(byte[] value, int startIndex)
{ {
long ret; long ret;
ULongFromBytes ((byte *) &ret, value, startIndex); ULongFromBytes((byte*)&ret, value, startIndex);
return ret; return ret;
} }
unsafe internal static ushort ToUInt16 (byte[] value, int startIndex) internal static unsafe ushort ToUInt16(byte[] value, int startIndex)
{ {
ushort ret; ushort ret;
UShortFromBytes ((byte *) &ret, value, startIndex); UShortFromBytes((byte*)&ret, value, startIndex);
return ret; return ret;
} }
unsafe internal static uint ToUInt32 (byte[] value, int startIndex) internal static unsafe uint ToUInt32(byte[] value, int startIndex)
{ {
uint ret; uint ret;
UIntFromBytes ((byte *) &ret, value, startIndex); UIntFromBytes((byte*)&ret, value, startIndex);
return ret; return ret;
} }
unsafe internal static ulong ToUInt64 (byte[] value, int startIndex) internal static unsafe ulong ToUInt64(byte[] value, int startIndex)
{ {
ulong ret; ulong ret;
ULongFromBytes ((byte *) &ret, value, startIndex); ULongFromBytes((byte*)&ret, value, startIndex);
return ret; return ret;
} }
unsafe internal static float ToSingle (byte[] value, int startIndex) internal static unsafe float ToSingle(byte[] value, int startIndex)
{ {
float ret; float ret;
UIntFromBytes ((byte *) &ret, value, startIndex); UIntFromBytes((byte*)&ret, value, startIndex);
return ret; return ret;
} }
unsafe internal static double ToDouble (byte[] value, int startIndex) internal static unsafe double ToDouble(byte[] value, int startIndex)
{ {
double ret; double ret;
ULongFromBytes ((byte *) &ret, value, startIndex); ULongFromBytes((byte*)&ret, value, startIndex);
return ret; return ret;
} }
......
...@@ -33,50 +33,37 @@ ...@@ -33,50 +33,37 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //
using System;
using System.Text;
namespace Titanium.Web.Proxy.Network.WinAuth.Security namespace Titanium.Web.Proxy.Network.WinAuth.Security
{ {
using System;
using System.Text;
internal class Message internal class Message
{ {
static private byte[] header = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00 }; private static readonly byte[] header = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00 };
internal Message (byte[] message) internal Message(byte[] message)
{ {
_type = 3; type = 3;
Decode (message); Decode(message);
} }
/// <summary> /// <summary>
/// Domain name /// Domain name
/// </summary> /// </summary>
internal string Domain internal string Domain { get; private set; }
{
get;
private set;
}
/// <summary> /// <summary>
/// Username /// Username
/// </summary> /// </summary>
internal string Username internal string Username { get; private set; }
{
get;
private set;
}
private int _type; private readonly int type;
private Common.NtlmFlags _flags;
internal Common.NtlmFlags Flags internal Common.NtlmFlags Flags { get; set; }
{
get { return _flags; }
set { _flags = value; }
}
// methods // methods
private void Decode (byte[] message) private void Decode(byte[] message)
{ {
//base.Decode (message); //base.Decode (message);
...@@ -95,10 +82,10 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security ...@@ -95,10 +82,10 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
throw new ArgumentException(msg, "message"); throw new ArgumentException(msg, "message");
} }
if (LittleEndian.ToUInt16 (message, 56) != message.Length) if (LittleEndian.ToUInt16(message, 56) != message.Length)
{ {
string msg = "Invalid Type3 message length."; string msg = "Invalid Type3 message length.";
throw new ArgumentException (msg, "message"); throw new ArgumentException(msg, "message");
} }
if (message.Length >= 64) if (message.Length >= 64)
...@@ -110,28 +97,25 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security ...@@ -110,28 +97,25 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
Flags = (Common.NtlmFlags)0x8201; Flags = (Common.NtlmFlags)0x8201;
} }
int dom_len = LittleEndian.ToUInt16 (message, 28); int domLen = LittleEndian.ToUInt16(message, 28);
int dom_off = LittleEndian.ToUInt16 (message, 32); int domOff = LittleEndian.ToUInt16(message, 32);
this.Domain = DecodeString (message, dom_off, dom_len); Domain = DecodeString(message, domOff, domLen);
int user_len = LittleEndian.ToUInt16 (message, 36); int userLen = LittleEndian.ToUInt16(message, 36);
int user_off = LittleEndian.ToUInt16 (message, 40); int userOff = LittleEndian.ToUInt16(message, 40);
this.Username = DecodeString (message, user_off, user_len); Username = DecodeString(message, userOff, userLen);
} }
string DecodeString (byte[] buffer, int offset, int len) string DecodeString(byte[] buffer, int offset, int len)
{ {
if ((Flags & Common.NtlmFlags.NegotiateUnicode) != 0) if ((Flags & Common.NtlmFlags.NegotiateUnicode) != 0)
{ {
return Encoding.Unicode.GetString(buffer, offset, len); return Encoding.Unicode.GetString(buffer, offset, len);
} }
else
{
return Encoding.ASCII.GetString(buffer, offset, len); return Encoding.ASCII.GetString(buffer, offset, len);
} }
}
protected bool CheckHeader(byte[] message) protected bool CheckHeader(byte[] message)
{ {
...@@ -140,8 +124,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security ...@@ -140,8 +124,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
if (message[i] != header[i]) if (message[i] != header[i])
return false; return false;
} }
return (LittleEndian.ToUInt32(message, 8) == _type); return (LittleEndian.ToUInt32(message, 8) == type);
} }
} }
} }
namespace Titanium.Web.Proxy.Network.WinAuth.Security using System;
{
using System;
namespace Titanium.Web.Proxy.Network.WinAuth.Security
{
/// <summary> /// <summary>
/// Status of authenticated session /// Status of authenticated session
/// </summary> /// </summary>
...@@ -9,10 +9,10 @@ ...@@ -9,10 +9,10 @@
{ {
internal State() internal State()
{ {
this.Credentials = new Common.SecurityHandle(0); Credentials = new Common.SecurityHandle(0);
this.Context = new Common.SecurityHandle(0); Context = new Common.SecurityHandle(0);
this.LastSeen = DateTime.Now; LastSeen = DateTime.Now;
} }
/// <summary> /// <summary>
...@@ -32,13 +32,13 @@ ...@@ -32,13 +32,13 @@
internal void ResetHandles() internal void ResetHandles()
{ {
this.Credentials.Reset(); Credentials.Reset();
this.Context.Reset(); Context.Reset();
} }
internal void UpdatePresence() internal void UpdatePresence()
{ {
this.LastSeen = DateTime.Now; LastSeen = DateTime.Now;
} }
} }
} }
// http://pinvoke.net/default.aspx/secur32/InitializeSecurityContext.html // http://pinvoke.net/default.aspx/secur32/InitializeSecurityContext.html
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.Network.WinAuth.Security namespace Titanium.Web.Proxy.Network.WinAuth.Security
{ {
using System;
using System.Linq;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security.Principal;
using static Common; using static Common;
using System.Threading.Tasks;
internal class WinAuthEndPoint internal class WinAuthEndPoint
{ {
/// <summary> /// <summary>
/// Keep track of auth states for reuse in final challenge response /// Keep track of auth states for reuse in final challenge response
/// </summary> /// </summary>
private static IDictionary<Guid, State> authStates private static readonly IDictionary<Guid, State> authStates = new ConcurrentDictionary<Guid, State>();
= new ConcurrentDictionary<Guid, State>();
/// <summary> /// <summary>
...@@ -27,17 +27,14 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security ...@@ -27,17 +27,14 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
/// <param name="authScheme"></param> /// <param name="authScheme"></param>
/// <param name="requestId"></param> /// <param name="requestId"></param>
/// <returns></returns> /// <returns></returns>
internal static byte[] AcquireInitialSecurityToken(string hostname, internal static byte[] AcquireInitialSecurityToken(string hostname, string authScheme, Guid requestId)
string authScheme, Guid requestId)
{ {
byte[] token = null; byte[] token;
//null for initial call //null for initial call
SecurityBufferDesciption serverToken var serverToken = new SecurityBufferDesciption();
= new SecurityBufferDesciption();
SecurityBufferDesciption clientToken var clientToken = new SecurityBufferDesciption(MaximumTokenSize);
= new SecurityBufferDesciption(MaximumTokenSize);
try try
{ {
...@@ -101,17 +98,14 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security ...@@ -101,17 +98,14 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
/// <param name="serverChallenge"></param> /// <param name="serverChallenge"></param>
/// <param name="requestId"></param> /// <param name="requestId"></param>
/// <returns></returns> /// <returns></returns>
internal static byte[] AcquireFinalSecurityToken(string hostname, internal static byte[] AcquireFinalSecurityToken(string hostname, byte[] serverChallenge, Guid requestId)
byte[] serverChallenge, Guid requestId)
{ {
byte[] token = null; byte[] token;
//user server challenge //user server challenge
SecurityBufferDesciption serverToken var serverToken = new SecurityBufferDesciption(serverChallenge);
= new SecurityBufferDesciption(serverChallenge);
SecurityBufferDesciption clientToken var clientToken = new SecurityBufferDesciption(MaximumTokenSize);
= new SecurityBufferDesciption(MaximumTokenSize);
try try
{ {
...@@ -161,9 +155,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security ...@@ -161,9 +155,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
{ {
var cutOff = DateTime.Now.AddMinutes(-1 * stateCacheTimeOutMinutes); var cutOff = DateTime.Now.AddMinutes(-1 * stateCacheTimeOutMinutes);
var outdated = authStates var outdated = authStates.Where(x => x.Value.LastSeen < cutOff).ToList();
.Where(x => x.Value.LastSeen < cutOff)
.ToList();
foreach (var cache in outdated) foreach (var cache in outdated)
{ {
...@@ -177,28 +169,28 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security ...@@ -177,28 +169,28 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
#region Native calls to secur32.dll #region Native calls to secur32.dll
[DllImport("secur32.dll", SetLastError = true)] [DllImport("secur32.dll", SetLastError = true)]
static extern int InitializeSecurityContext(ref SecurityHandle phCredential,//PCredHandle static extern int InitializeSecurityContext(ref SecurityHandle phCredential, //PCredHandle
IntPtr phContext, //PCtxtHandle IntPtr phContext, //PCtxtHandle
string pszTargetName, string pszTargetName,
int fContextReq, int fContextReq,
int Reserved1, int reserved1,
int TargetDataRep, int targetDataRep,
ref SecurityBufferDesciption pInput, //PSecBufferDesc SecBufferDesc ref SecurityBufferDesciption pInput, //PSecBufferDesc SecBufferDesc
int Reserved2, int reserved2,
out SecurityHandle phNewContext, //PCtxtHandle out SecurityHandle phNewContext, //PCtxtHandle
out SecurityBufferDesciption pOutput, //PSecBufferDesc SecBufferDesc out SecurityBufferDesciption pOutput, //PSecBufferDesc SecBufferDesc
out uint pfContextAttr, //managed ulong == 64 bits!!! out uint pfContextAttr, //managed ulong == 64 bits!!!
out SecurityInteger ptsExpiry); //PTimeStamp out SecurityInteger ptsExpiry); //PTimeStamp
[DllImport("secur32", CharSet = CharSet.Auto, SetLastError = true)] [DllImport("secur32", CharSet = CharSet.Auto, SetLastError = true)]
static extern int InitializeSecurityContext(ref SecurityHandle phCredential,//PCredHandle static extern int InitializeSecurityContext(ref SecurityHandle phCredential, //PCredHandle
ref SecurityHandle phContext, //PCtxtHandle ref SecurityHandle phContext, //PCtxtHandle
string pszTargetName, string pszTargetName,
int fContextReq, int fContextReq,
int Reserved1, int reserved1,
int TargetDataRep, int targetDataRep,
ref SecurityBufferDesciption SecBufferDesc, //PSecBufferDesc SecBufferDesc ref SecurityBufferDesciption secBufferDesc, //PSecBufferDesc SecBufferDesc
int Reserved2, int reserved2,
out SecurityHandle phNewContext, //PCtxtHandle out SecurityHandle phNewContext, //PCtxtHandle
out SecurityBufferDesciption pOutput, //PSecBufferDesc SecBufferDesc out SecurityBufferDesciption pOutput, //PSecBufferDesc SecBufferDesc
out uint pfContextAttr, //managed ulong == 64 bits!!! out uint pfContextAttr, //managed ulong == 64 bits!!!
...@@ -209,13 +201,12 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security ...@@ -209,13 +201,12 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
string pszPrincipal, //SEC_CHAR* string pszPrincipal, //SEC_CHAR*
string pszPackage, //SEC_CHAR* //"Kerberos","NTLM","Negotiative" string pszPackage, //SEC_CHAR* //"Kerberos","NTLM","Negotiative"
int fCredentialUse, int fCredentialUse,
IntPtr PAuthenticationID, //_LUID AuthenticationID,//pvLogonID, //PLUID IntPtr pAuthenticationId, //_LUID AuthenticationID,//pvLogonID, //PLUID
IntPtr pAuthData, //PVOID IntPtr pAuthData, //PVOID
int pGetKeyFn, //SEC_GET_KEY_FN int pGetKeyFn, //SEC_GET_KEY_FN
IntPtr pvGetKeyArgument, //PVOID IntPtr pvGetKeyArgument, //PVOID
ref Common.SecurityHandle phCredential, //SecHandle //PCtxtHandle ref ref SecurityHandle phCredential, //SecHandle //PCtxtHandle ref
ref Common.SecurityInteger ptsExpiry); //PTimeStamp //TimeStamp ref ref SecurityInteger ptsExpiry); //PTimeStamp //TimeStamp ref
#endregion #endregion
} }
......
using Titanium.Web.Proxy.Network.WinAuth.Security; using System;
using System; using Titanium.Web.Proxy.Network.WinAuth.Security;
namespace Titanium.Web.Proxy.Network.WinAuth namespace Titanium.Web.Proxy.Network.WinAuth
{ {
...@@ -18,8 +18,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth ...@@ -18,8 +18,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth
/// <param name="authScheme"></param> /// <param name="authScheme"></param>
/// <param name="requestId"></param> /// <param name="requestId"></param>
/// <returns></returns> /// <returns></returns>
public static string GetInitialAuthToken(string serverHostname, public static string GetInitialAuthToken(string serverHostname, string authScheme, Guid requestId)
string authScheme, Guid requestId)
{ {
var tokenBytes = WinAuthEndPoint.AcquireInitialSecurityToken(serverHostname, authScheme, requestId); var tokenBytes = WinAuthEndPoint.AcquireInitialSecurityToken(serverHostname, authScheme, requestId);
return string.Concat(" ", Convert.ToBase64String(tokenBytes)); return string.Concat(" ", Convert.ToBase64String(tokenBytes));
...@@ -33,14 +32,11 @@ namespace Titanium.Web.Proxy.Network.WinAuth ...@@ -33,14 +32,11 @@ namespace Titanium.Web.Proxy.Network.WinAuth
/// <param name="serverToken"></param> /// <param name="serverToken"></param>
/// <param name="requestId"></param> /// <param name="requestId"></param>
/// <returns></returns> /// <returns></returns>
public static string GetFinalAuthToken(string serverHostname, public static string GetFinalAuthToken(string serverHostname, string serverToken, Guid requestId)
string serverToken, Guid requestId)
{ {
var tokenBytes = WinAuthEndPoint.AcquireFinalSecurityToken(serverHostname, var tokenBytes = WinAuthEndPoint.AcquireFinalSecurityToken(serverHostname, Convert.FromBase64String(serverToken), requestId);
Convert.FromBase64String(serverToken), requestId);
return string.Concat(" ", Convert.ToBase64String(tokenBytes)); return string.Concat(" ", Convert.ToBase64String(tokenBytes));
} }
} }
} }
...@@ -30,8 +30,9 @@ namespace Titanium.Web.Proxy ...@@ -30,8 +30,9 @@ namespace Titanium.Web.Proxy
} }
var header = httpHeaders.FirstOrDefault(t => t.Name == "Proxy-Authorization"); var header = httpHeaders.FirstOrDefault(t => t.Name == "Proxy-Authorization");
if (header == null) throw new NullReferenceException(); if (header == null)
var headerValue = header.Value.Trim(); throw new NullReferenceException();
string headerValue = header.Value.Trim();
if (!headerValue.StartsWith("basic", StringComparison.CurrentCultureIgnoreCase)) if (!headerValue.StartsWith("basic", StringComparison.CurrentCultureIgnoreCase))
{ {
//Return not authorized //Return not authorized
...@@ -41,7 +42,7 @@ namespace Titanium.Web.Proxy ...@@ -41,7 +42,7 @@ namespace Titanium.Web.Proxy
headerValue = headerValue.Substring(5).Trim(); headerValue = headerValue.Substring(5).Trim();
var decoded = Encoding.UTF8.GetString(Convert.FromBase64String(headerValue)); string decoded = Encoding.UTF8.GetString(Convert.FromBase64String(headerValue));
if (decoded.Contains(":") == false) if (decoded.Contains(":") == false)
{ {
//Return not authorized //Return not authorized
...@@ -49,8 +50,8 @@ namespace Titanium.Web.Proxy ...@@ -49,8 +50,8 @@ namespace Titanium.Web.Proxy
return false; return false;
} }
var username = decoded.Substring(0, decoded.IndexOf(':')); string username = decoded.Substring(0, decoded.IndexOf(':'));
var password = decoded.Substring(decoded.IndexOf(':') + 1); string password = decoded.Substring(decoded.IndexOf(':') + 1);
return await AuthenticateUserFunc(username, password); return await AuthenticateUserFunc(username, password);
} }
catch (Exception e) catch (Exception e)
......
...@@ -67,9 +67,7 @@ namespace Titanium.Web.Proxy ...@@ -67,9 +67,7 @@ namespace Titanium.Web.Proxy
/// <summary> /// <summary>
/// Set firefox to use default system proxy /// Set firefox to use default system proxy
/// </summary> /// </summary>
private FireFoxProxySettingsManager firefoxProxySettingsManager private readonly FireFoxProxySettingsManager firefoxProxySettingsManager = new FireFoxProxySettingsManager();
= new FireFoxProxySettingsManager();
/// <summary> /// <summary>
/// Buffer size used throughout this proxy /// Buffer size used throughout this proxy
...@@ -255,15 +253,13 @@ namespace Titanium.Web.Proxy ...@@ -255,15 +253,13 @@ namespace Titanium.Web.Proxy
/// <summary> /// <summary>
/// List of supported Ssl versions /// List of supported Ssl versions
/// </summary> /// </summary>
public SslProtocols SupportedSslProtocols { get; set; } = SslProtocols.Tls public SslProtocols SupportedSslProtocols { get; set; } = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Ssl3;
| SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Ssl3;
/// <summary> /// <summary>
/// Total number of active client connections /// Total number of active client connections
/// </summary> /// </summary>
public int ClientConnectionCount => clientConnectionCount; public int ClientConnectionCount => clientConnectionCount;
/// <summary> /// <summary>
/// Total number of active server connections /// Total number of active server connections
/// </summary> /// </summary>
...@@ -312,8 +308,7 @@ namespace Titanium.Web.Proxy ...@@ -312,8 +308,7 @@ namespace Titanium.Web.Proxy
/// <param name="endPoint"></param> /// <param name="endPoint"></param>
public void AddEndPoint(ProxyEndPoint endPoint) public void AddEndPoint(ProxyEndPoint endPoint)
{ {
if (ProxyEndPoints.Any(x => x.IpAddress.Equals(endPoint.IpAddress) if (ProxyEndPoints.Any(x => x.IpAddress.Equals(endPoint.IpAddress) && endPoint.Port != 0 && x.Port == endPoint.Port))
&& endPoint.Port != 0 && x.Port == endPoint.Port))
{ {
throw new Exception("Cannot add another endpoint to same port & ip address"); throw new Exception("Cannot add another endpoint to same port & ip address");
} }
...@@ -412,7 +407,9 @@ namespace Titanium.Web.Proxy ...@@ -412,7 +407,9 @@ namespace Titanium.Web.Proxy
systemProxySettingsManager.SetProxy( systemProxySettingsManager.SetProxy(
Equals(endPoint.IpAddress, IPAddress.Any) | Equals(endPoint.IpAddress, IPAddress.Any) |
Equals(endPoint.IpAddress, IPAddress.Loopback) ? "127.0.0.1" : endPoint.IpAddress.ToString(), Equals(endPoint.IpAddress, IPAddress.Loopback)
? "127.0.0.1"
: endPoint.IpAddress.ToString(),
endPoint.Port, endPoint.Port,
protocolType); protocolType);
...@@ -565,7 +562,7 @@ namespace Titanium.Web.Proxy ...@@ -565,7 +562,7 @@ namespace Titanium.Web.Proxy
if (!RunTime.IsRunningOnMono) if (!RunTime.IsRunningOnMono)
{ {
var setAsSystemProxy = ProxyEndPoints.OfType<ExplicitProxyEndPoint>().Any(x => x.IsSystemHttpProxy || x.IsSystemHttpsProxy); bool setAsSystemProxy = ProxyEndPoints.OfType<ExplicitProxyEndPoint>().Any(x => x.IsSystemHttpProxy || x.IsSystemHttpsProxy);
if (setAsSystemProxy) if (setAsSystemProxy)
{ {
...@@ -618,7 +615,8 @@ namespace Titanium.Web.Proxy ...@@ -618,7 +615,8 @@ namespace Titanium.Web.Proxy
/// <param name="endPoint"></param> /// <param name="endPoint"></param>
private void ValidateEndPointAsSystemProxy(ExplicitProxyEndPoint endPoint) private void ValidateEndPointAsSystemProxy(ExplicitProxyEndPoint endPoint)
{ {
if (endPoint == null) throw new ArgumentNullException(nameof(endPoint)); if (endPoint == null)
throw new ArgumentNullException(nameof(endPoint));
if (ProxyEndPoints.Contains(endPoint) == false) if (ProxyEndPoints.Contains(endPoint) == false)
{ {
throw new Exception("Cannot set endPoints not added to proxy as system proxy"); throw new Exception("Cannot set endPoints not added to proxy as system proxy");
......
This diff is collapsed.
...@@ -32,13 +32,13 @@ namespace Titanium.Web.Proxy ...@@ -32,13 +32,13 @@ namespace Titanium.Web.Proxy
await args.WebSession.ReceiveResponse(); await args.WebSession.ReceiveResponse();
//check for windows authentication //check for windows authentication
if(EnableWinAuth if (EnableWinAuth
&& !RunTime.IsRunningOnMono && !RunTime.IsRunningOnMono
&& args.WebSession.Response.ResponseStatusCode == "401") && args.WebSession.Response.ResponseStatusCode == "401")
{ {
var disposed = await Handle401UnAuthorized(args); bool disposed = await Handle401UnAuthorized(args);
if(disposed) if (disposed)
{ {
return true; return true;
} }
...@@ -58,7 +58,7 @@ namespace Titanium.Web.Proxy ...@@ -58,7 +58,7 @@ namespace Titanium.Web.Proxy
{ {
//clear current response //clear current response
await args.ClearResponse(); await args.ClearResponse();
var disposed = await HandleHttpSessionRequestInternal(args.WebSession.ServerConnection, args, false); bool disposed = await HandleHttpSessionRequestInternal(args.WebSession.ServerConnection, args, false);
return disposed; return disposed;
} }
...@@ -67,14 +67,12 @@ namespace Titanium.Web.Proxy ...@@ -67,14 +67,12 @@ namespace Titanium.Web.Proxy
//Write back to client 100-conitinue response if that's what server returned //Write back to client 100-conitinue response if that's what server returned
if (args.WebSession.Response.Is100Continue) if (args.WebSession.Response.Is100Continue)
{ {
await WriteResponseStatus(args.WebSession.Response.HttpVersion, "100", await WriteResponseStatus(args.WebSession.Response.HttpVersion, "100", "Continue", args.ProxyClient.ClientStreamWriter);
"Continue", args.ProxyClient.ClientStreamWriter);
await args.ProxyClient.ClientStreamWriter.WriteLineAsync(); await args.ProxyClient.ClientStreamWriter.WriteLineAsync();
} }
else if (args.WebSession.Response.ExpectationFailed) else if (args.WebSession.Response.ExpectationFailed)
{ {
await WriteResponseStatus(args.WebSession.Response.HttpVersion, "417", await WriteResponseStatus(args.WebSession.Response.HttpVersion, "417", "Expectation Failed", args.ProxyClient.ClientStreamWriter);
"Expectation Failed", args.ProxyClient.ClientStreamWriter);
await args.ProxyClient.ClientStreamWriter.WriteLineAsync(); await args.ProxyClient.ClientStreamWriter.WriteLineAsync();
} }
...@@ -84,8 +82,8 @@ namespace Titanium.Web.Proxy ...@@ -84,8 +82,8 @@ namespace Titanium.Web.Proxy
if (args.WebSession.Response.ResponseBodyRead) if (args.WebSession.Response.ResponseBodyRead)
{ {
var isChunked = args.WebSession.Response.IsChunked; bool isChunked = args.WebSession.Response.IsChunked;
var contentEncoding = args.WebSession.Response.ContentEncoding; string contentEncoding = args.WebSession.Response.ContentEncoding;
if (contentEncoding != null) if (contentEncoding != null)
{ {
...@@ -110,20 +108,17 @@ namespace Titanium.Web.Proxy ...@@ -110,20 +108,17 @@ namespace Titanium.Web.Proxy
//Write body only if response is chunked or content length >0 //Write body only if response is chunked or content length >0
//Is none are true then check if connection:close header exist, if so write response until server or client terminates the connection //Is none are true then check if connection:close header exist, if so write response until server or client terminates the connection
if (args.WebSession.Response.IsChunked || args.WebSession.Response.ContentLength > 0 if (args.WebSession.Response.IsChunked || args.WebSession.Response.ContentLength > 0 || !args.WebSession.Response.ResponseKeepAlive)
|| !args.WebSession.Response.ResponseKeepAlive)
{ {
await args.WebSession.ServerConnection.StreamReader await args.WebSession.ServerConnection.StreamReader.WriteResponseBody(BufferSize, args.ProxyClient.ClientStream,
.WriteResponseBody(BufferSize, args.ProxyClient.ClientStream, args.WebSession.Response.IsChunked, args.WebSession.Response.IsChunked, args.WebSession.Response.ContentLength);
args.WebSession.Response.ContentLength);
} }
//write response if connection:keep-alive header exist and when version is http/1.0 //write response if connection:keep-alive header exist and when version is http/1.0
//Because in Http 1.0 server can return a response without content-length (expectation being client would read until end of stream) //Because in Http 1.0 server can return a response without content-length (expectation being client would read until end of stream)
else if (args.WebSession.Response.ResponseKeepAlive && args.WebSession.Response.HttpVersion.Minor == 0) else if (args.WebSession.Response.ResponseKeepAlive && args.WebSession.Response.HttpVersion.Minor == 0)
{ {
await args.WebSession.ServerConnection.StreamReader await args.WebSession.ServerConnection.StreamReader.WriteResponseBody(BufferSize, args.ProxyClient.ClientStream,
.WriteResponseBody(BufferSize, args.ProxyClient.ClientStream, args.WebSession.Response.IsChunked, args.WebSession.Response.IsChunked, args.WebSession.Response.ContentLength);
args.WebSession.Response.ContentLength);
} }
} }
...@@ -132,8 +127,8 @@ namespace Titanium.Web.Proxy ...@@ -132,8 +127,8 @@ namespace Titanium.Web.Proxy
catch (Exception e) catch (Exception e)
{ {
ExceptionFunc(new ProxyHttpException("Error occured whilst handling session response", e, args)); ExceptionFunc(new ProxyHttpException("Error occured whilst handling session response", e, args));
Dispose(args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamReader, Dispose(args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamReader, args.ProxyClient.ClientStreamWriter,
args.ProxyClient.ClientStreamWriter, args.WebSession.ServerConnection); args.WebSession.ServerConnection);
return true; return true;
} }
...@@ -162,8 +157,7 @@ namespace Titanium.Web.Proxy ...@@ -162,8 +157,7 @@ namespace Titanium.Web.Proxy
/// <param name="description"></param> /// <param name="description"></param>
/// <param name="responseWriter"></param> /// <param name="responseWriter"></param>
/// <returns></returns> /// <returns></returns>
private async Task WriteResponseStatus(Version version, string code, string description, private async Task WriteResponseStatus(Version version, string code, string description, StreamWriter responseWriter)
StreamWriter responseWriter)
{ {
await responseWriter.WriteLineAsync($"HTTP/{version.Major}.{version.Minor} {code} {description}"); await responseWriter.WriteLineAsync($"HTTP/{version.Major}.{version.Minor} {code} {description}");
} }
...@@ -204,8 +198,8 @@ namespace Titanium.Web.Proxy ...@@ -204,8 +198,8 @@ namespace Titanium.Web.Proxy
private void FixProxyHeaders(Dictionary<string, HttpHeader> headers) private void FixProxyHeaders(Dictionary<string, HttpHeader> headers)
{ {
//If proxy-connection close was returned inform to close the connection //If proxy-connection close was returned inform to close the connection
var hasProxyHeader = headers.ContainsKey("proxy-connection"); bool hasProxyHeader = headers.ContainsKey("proxy-connection");
var hasConnectionheader = headers.ContainsKey("connection"); bool hasConnectionheader = headers.ContainsKey("connection");
if (hasProxyHeader) if (hasProxyHeader)
{ {
...@@ -231,10 +225,7 @@ namespace Titanium.Web.Proxy ...@@ -231,10 +225,7 @@ namespace Titanium.Web.Proxy
/// <param name="clientStreamReader"></param> /// <param name="clientStreamReader"></param>
/// <param name="clientStreamWriter"></param> /// <param name="clientStreamWriter"></param>
/// <param name="serverConnection"></param> /// <param name="serverConnection"></param>
private void Dispose(Stream clientStream, private void Dispose(Stream clientStream, CustomBinaryReader clientStreamReader, StreamWriter clientStreamWriter, TcpConnection serverConnection)
CustomBinaryReader clientStreamReader,
StreamWriter clientStreamWriter,
TcpConnection serverConnection)
{ {
clientStream?.Close(); clientStream?.Close();
clientStream?.Dispose(); clientStream?.Dispose();
......
...@@ -16,8 +16,7 @@ namespace Titanium.Web.Proxy.Shared ...@@ -16,8 +16,7 @@ namespace Titanium.Web.Proxy.Shared
internal static readonly byte[] NewLineBytes = Encoding.ASCII.GetBytes(NewLine); internal static readonly byte[] NewLineBytes = Encoding.ASCII.GetBytes(NewLine);
internal static readonly byte[] ChunkEnd = internal static readonly byte[] ChunkEnd = Encoding.ASCII.GetBytes(0.ToString("x2") + NewLine + NewLine);
Encoding.ASCII.GetBytes(0.ToString("x2") + NewLine + NewLine);
internal const string NewLine = "\r\n"; internal const string NewLine = "\r\n";
} }
......
...@@ -5,16 +5,14 @@ using System.Threading.Tasks; ...@@ -5,16 +5,14 @@ using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments; using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network.WinAuth; using Titanium.Web.Proxy.Network.WinAuth;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers;
namespace Titanium.Web.Proxy namespace Titanium.Web.Proxy
{ {
public partial class ProxyServer public partial class ProxyServer
{ {
//possible header names //possible header names
private static List<string> authHeaderNames private static readonly List<string> authHeaderNames = new List<string>
= new List<string>() { {
"WWW-Authenticate", "WWW-Authenticate",
//IIS 6.0 messed up names below //IIS 6.0 messed up names below
"WWWAuthenticate", "WWWAuthenticate",
...@@ -23,8 +21,8 @@ namespace Titanium.Web.Proxy ...@@ -23,8 +21,8 @@ namespace Titanium.Web.Proxy
"KerberosAuthorization" "KerberosAuthorization"
}; };
private static List<string> authSchemes private static readonly List<string> authSchemes = new List<string>
= new List<string>() { {
"NTLM", "NTLM",
"Negotiate", "Negotiate",
"Kerberos" "Kerberos"
...@@ -45,10 +43,9 @@ namespace Titanium.Web.Proxy ...@@ -45,10 +43,9 @@ namespace Titanium.Web.Proxy
HttpHeader authHeader = null; HttpHeader authHeader = null;
//check in non-unique headers first //check in non-unique headers first
var header = args.WebSession.Response var header =
.NonUniqueResponseHeaders args.WebSession.Response.NonUniqueResponseHeaders.FirstOrDefault(
.FirstOrDefault(x => x => authHeaderNames.Any(y => x.Key.Equals(y, StringComparison.OrdinalIgnoreCase)));
authHeaderNames.Any(y => x.Key.Equals(y, StringComparison.OrdinalIgnoreCase)));
if (!header.Equals(new KeyValuePair<string, List<HttpHeader>>())) if (!header.Equals(new KeyValuePair<string, List<HttpHeader>>()))
{ {
...@@ -57,20 +54,16 @@ namespace Titanium.Web.Proxy ...@@ -57,20 +54,16 @@ namespace Titanium.Web.Proxy
if (headerName != null) if (headerName != null)
{ {
authHeader = args.WebSession.Response authHeader = args.WebSession.Response.NonUniqueResponseHeaders[headerName]
.NonUniqueResponseHeaders[headerName] .FirstOrDefault(x => authSchemes.Any(y => x.Value.StartsWith(y, StringComparison.OrdinalIgnoreCase)));
.Where(x => authSchemes.Any(y => x.Value.StartsWith(y, StringComparison.OrdinalIgnoreCase)))
.FirstOrDefault();
} }
//check in unique headers //check in unique headers
if (authHeader == null) if (authHeader == null)
{ {
//check in non-unique headers first //check in non-unique headers first
var uHeader = args.WebSession.Response var uHeader =
.ResponseHeaders args.WebSession.Response.ResponseHeaders.FirstOrDefault(x => authHeaderNames.Any(y => x.Key.Equals(y, StringComparison.OrdinalIgnoreCase)));
.FirstOrDefault(x =>
authHeaderNames.Any(y => x.Key.Equals(y, StringComparison.OrdinalIgnoreCase)));
if (!uHeader.Equals(new KeyValuePair<string, HttpHeader>())) if (!uHeader.Equals(new KeyValuePair<string, HttpHeader>()))
{ {
...@@ -79,15 +72,16 @@ namespace Titanium.Web.Proxy ...@@ -79,15 +72,16 @@ namespace Titanium.Web.Proxy
if (headerName != null) if (headerName != null)
{ {
authHeader = authSchemes.Any(x => args.WebSession.Response authHeader = authSchemes.Any(x => args.WebSession.Response.ResponseHeaders[headerName].Value
.ResponseHeaders[headerName].Value.StartsWith(x, StringComparison.OrdinalIgnoreCase)) ? .StartsWith(x, StringComparison.OrdinalIgnoreCase))
args.WebSession.Response.ResponseHeaders[headerName] : null; ? args.WebSession.Response.ResponseHeaders[headerName]
: null;
} }
} }
if (authHeader != null) if (authHeader != null)
{ {
var scheme = authSchemes.FirstOrDefault(x => authHeader.Value.Equals(x, StringComparison.OrdinalIgnoreCase)); string scheme = authSchemes.FirstOrDefault(x => authHeader.Value.Equals(x, StringComparison.OrdinalIgnoreCase));
//clear any existing headers to avoid confusing bad servers //clear any existing headers to avoid confusing bad servers
if (args.WebSession.Request.NonUniqueRequestHeaders.ContainsKey("Authorization")) if (args.WebSession.Request.NonUniqueRequestHeaders.ContainsKey("Authorization"))
...@@ -98,7 +92,7 @@ namespace Titanium.Web.Proxy ...@@ -98,7 +92,7 @@ namespace Titanium.Web.Proxy
//initial value will match exactly any of the schemes //initial value will match exactly any of the schemes
if (scheme != null) if (scheme != null)
{ {
var clientToken = WinAuthHandler.GetInitialAuthToken(args.WebSession.Request.Host, scheme, args.Id); string clientToken = WinAuthHandler.GetInitialAuthToken(args.WebSession.Request.Host, scheme, args.Id);
var auth = new HttpHeader("Authorization", string.Concat(scheme, clientToken)); var auth = new HttpHeader("Authorization", string.Concat(scheme, clientToken));
...@@ -113,32 +107,28 @@ namespace Titanium.Web.Proxy ...@@ -113,32 +107,28 @@ namespace Titanium.Web.Proxy
} }
//don't need to send body for Authorization request //don't need to send body for Authorization request
if(args.WebSession.Request.HasBody) if (args.WebSession.Request.HasBody)
{ {
args.WebSession.Request.ContentLength = 0; args.WebSession.Request.ContentLength = 0;
} }
} }
//challenge value will start with any of the scheme selected //challenge value will start with any of the scheme selected
else else
{ {
scheme = authSchemes.FirstOrDefault(x => authHeader.Value.StartsWith(x, StringComparison.OrdinalIgnoreCase) scheme = authSchemes.FirstOrDefault(x => authHeader.Value.StartsWith(x, StringComparison.OrdinalIgnoreCase) &&
&& authHeader.Value.Length > x.Length + 1); authHeader.Value.Length > x.Length + 1);
var serverToken = authHeader.Value.Substring(scheme.Length + 1); string serverToken = authHeader.Value.Substring(scheme.Length + 1);
var clientToken = WinAuthHandler.GetFinalAuthToken(args.WebSession.Request.Host, serverToken, args.Id); string clientToken = WinAuthHandler.GetFinalAuthToken(args.WebSession.Request.Host, serverToken, args.Id);
//there will be an existing header from initial client request //there will be an existing header from initial client request
args.WebSession.Request.RequestHeaders["Authorization"] args.WebSession.Request.RequestHeaders["Authorization"] = new HttpHeader("Authorization", string.Concat(scheme, clientToken));
= new HttpHeader("Authorization", string.Concat(scheme, clientToken));
//send body for final auth request //send body for final auth request
if (args.WebSession.Request.HasBody) if (args.WebSession.Request.HasBody)
{ {
args.WebSession.Request.ContentLength args.WebSession.Request.ContentLength = args.WebSession.Request.RequestBody.Length;
= args.WebSession.Request.RequestBody.Length;
} }
} }
//Need to revisit this. //Need to revisit this.
...@@ -150,13 +140,11 @@ namespace Titanium.Web.Proxy ...@@ -150,13 +140,11 @@ namespace Titanium.Web.Proxy
//request again with updated authorization header //request again with updated authorization header
//and server cookies //and server cookies
var disposed = await HandleHttpSessionRequestInternal(args.WebSession.ServerConnection, args, false); bool disposed = await HandleHttpSessionRequestInternal(args.WebSession.ServerConnection, args, false);
return disposed; return disposed;
} }
return false; return false;
} }
} }
} }
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