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
internal static bool DisableQuickEditMode()
{
IntPtr consoleHandle = GetStdHandle(STD_INPUT_HANDLE);
var consoleHandle = GetStdHandle(STD_INPUT_HANDLE);
// get current console mode
uint consoleMode;
......
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Titanium.Web.Proxy.Examples.Basic.Helpers;
namespace Titanium.Web.Proxy.Examples.Basic
......
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
using System.Net.Security;
......@@ -55,7 +54,10 @@ namespace Titanium.Web.Proxy.Examples.Basic
//Exclude Https addresses you don't want to proxy
//Useful for clients that use certificate pinning
//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)
//for example github.com
......@@ -91,8 +93,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
//proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
foreach (var endPoint in proxyServer.ProxyEndPoints)
Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ",
endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);
Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);
//Only explicit proxies can be set as system proxy!
//proxyServer.SetAsSystemHttpProxy(explicitEndPoint);
......@@ -125,7 +126,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
if (e.WebSession.Request.HasBody)
{
//Get/Set request body bytes
byte[] bodyBytes = await e.GetRequestBody();
var bodyBytes = await e.GetRequestBody();
await e.SetRequestBody(bodyBytes);
//Get/Set request body as string
......@@ -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"))
{
byte[] bodyBytes = await e.GetResponseBody();
var bodyBytes = await e.GetResponseBody();
await e.SetResponseBody(bodyBytes);
string body = await e.GetResponseBodyAsString();
......
......@@ -18,7 +18,7 @@ namespace Titanium.Web.Proxy.IntegrationTests
{
//expand this to stress test to find
//why in long run proxy becomes unresponsive as per issue #184
var testUrl = "https://google.com";
string testUrl = "https://google.com";
int proxyPort = 8086;
var proxy = new ProxyTestController();
proxy.StartProxy(proxyPort);
......
......@@ -25,7 +25,7 @@ namespace Titanium.Web.Proxy.UnitTests
for (int i = 0; i < 1000; i++)
{
foreach (var host in hostNames)
foreach (string host in hostNames)
{
tasks.Add(Task.Run(async () =>
{
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Titanium.Web.Proxy.Helpers;
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;
namespace Titanium.Web.Proxy.UnitTests
......@@ -10,7 +10,7 @@ namespace Titanium.Web.Proxy.UnitTests
[TestMethod]
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);
}
}
......
<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: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_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/=CN/@EntryIndexedValue">CN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DN/@EntryIndexedValue">DN</s:String>
......
......@@ -16,11 +16,7 @@ namespace Titanium.Web.Proxy
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns></returns>
internal bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
internal bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
//if user callback is registered then do it
if (ServerCertificateValidationCallback != null)
......@@ -56,22 +52,15 @@ namespace Titanium.Web.Proxy
/// <param name="remoteCertificate"></param>
/// <param name="acceptableIssuers"></param>
/// <returns></returns>
internal X509Certificate SelectClientCertificate(
object sender,
string targetHost,
X509CertificateCollection localCertificates,
X509Certificate remoteCertificate,
string[] acceptableIssuers)
internal X509Certificate SelectClientCertificate(object sender, string targetHost, X509CertificateCollection localCertificates,
X509Certificate remoteCertificate, string[] acceptableIssuers)
{
X509Certificate clientCertificate = null;
if (acceptableIssuers != null &&
acceptableIssuers.Length > 0 &&
localCertificates != null &&
localCertificates.Count > 0)
if (acceptableIssuers != null && acceptableIssuers.Length > 0 && localCertificates != null && localCertificates.Count > 0)
{
// Use the first certificate that is from an acceptable issuer.
foreach (X509Certificate certificate in localCertificates)
foreach (var certificate in localCertificates)
{
string issuer = certificate.Issuer;
if (Array.IndexOf(acceptableIssuers, issuer) != -1)
......@@ -81,8 +70,7 @@ namespace Titanium.Web.Proxy
}
}
if (localCertificates != null &&
localCertificates.Count > 0)
if (localCertificates != null && localCertificates.Count > 0)
{
clientCertificate = localCertificates[0];
}
......
......@@ -48,7 +48,6 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary>
public Guid Id => WebSession.RequestId;
/// <summary>
/// Should we send the request again
/// </summary>
......@@ -59,8 +58,7 @@ namespace Titanium.Web.Proxy.EventArguments
{
if (WebSession.Response.ResponseStatusCode == null)
{
throw new Exception("Response status code is null. Cannot request again a request "
+ "which was never send to server.");
throw new Exception("Response status code is null. Cannot request again a request " + "which was never send to server.");
}
reRequest = value;
......@@ -113,8 +111,7 @@ namespace Titanium.Web.Proxy.EventArguments
//GET request don't have a request body to read
if (!WebSession.Request.HasBody)
{
throw new BodyNotFoundException("Request don't have a body. " +
"Please verify that this request is a Http POST/PUT/PATCH and request " +
throw new BodyNotFoundException("Request don't have a body. " + "Please verify that this request is a Http POST/PUT/PATCH and request " +
"content length is greater than zero before accessing the body.");
}
......@@ -135,16 +132,14 @@ namespace Titanium.Web.Proxy.EventArguments
if (WebSession.Request.ContentLength > 0)
{
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response
await ProxyClient.ClientStreamReader.CopyBytesToStream(requestBodyStream,
WebSession.Request.ContentLength);
await ProxyClient.ClientStreamReader.CopyBytesToStream(requestBodyStream, WebSession.Request.ContentLength);
}
else if (WebSession.Request.HttpVersion.Major == 1 && WebSession.Request.HttpVersion.Minor == 0)
{
await WebSession.ServerConnection.StreamReader.CopyBytesToStream(requestBodyStream, long.MaxValue);
}
}
WebSession.Request.RequestBody = await GetDecompressedResponseBody(WebSession.Request.ContentEncoding,
requestBodyStream.ToArray());
WebSession.Request.RequestBody = await GetDecompressedResponseBody(WebSession.Request.ContentEncoding, requestBodyStream.ToArray());
}
//Now set the flag to true
......@@ -185,17 +180,16 @@ namespace Titanium.Web.Proxy.EventArguments
if (WebSession.Response.ContentLength > 0)
{
//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,
WebSession.Response.ContentLength);
await WebSession.ServerConnection.StreamReader.CopyBytesToStream(responseBodyStream, 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);
}
}
WebSession.Response.ResponseBody = await GetDecompressedResponseBody(WebSession.Response.ContentEncoding,
responseBodyStream.ToArray());
WebSession.Response.ResponseBody = await GetDecompressedResponseBody(WebSession.Response.ContentEncoding, responseBodyStream.ToArray());
}
//set this to true for caching
WebSession.Response.ResponseBodyRead = true;
......@@ -236,7 +230,8 @@ namespace Titanium.Web.Proxy.EventArguments
await ReadRequestBody();
}
//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>
......@@ -316,8 +311,8 @@ namespace Titanium.Web.Proxy.EventArguments
await GetResponseBody();
return WebSession.Response.ResponseBodyString ??
(WebSession.Response.ResponseBodyString = WebSession.Response.Encoding.GetString(WebSession.Response.ResponseBody));
return WebSession.Response.ResponseBodyString ?? (WebSession.Response.ResponseBodyString =
WebSession.Response.Encoding.GetString(WebSession.Response.ResponseBody));
}
/// <summary>
......
......@@ -9,8 +9,7 @@
/// Constructor.
/// </summary>
/// <param name="message"></param>
public BodyNotFoundException(string message)
: base(message)
public BodyNotFoundException(string message) : base(message)
{
}
}
......
......@@ -7,8 +7,8 @@ namespace Titanium.Web.Proxy.Extensions
{
public static void InvokeParallel<T>(this Func<object, T, Task> callback, object sender, T args)
{
Delegate[] invocationList = callback.GetInvocationList();
Task[] handlerTasks = new Task[invocationList.Length];
var invocationList = callback.GetInvocationList();
var handlerTasks = new Task[invocationList.Length];
for (int i = 0; i < invocationList.Length; i++)
{
......@@ -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)
{
Delegate[] invocationList = callback.GetInvocationList();
Task[] handlerTasks = new Task[invocationList.Length];
var invocationList = callback.GetInvocationList();
var handlerTasks = new Task[invocationList.Length];
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.Http;
......
using System;
using System.Text;
using System.Text;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http;
......
......@@ -39,7 +39,7 @@ namespace Titanium.Web.Proxy.Extensions
/// <returns></returns>
internal static async Task CopyBytesToStream(this CustomBinaryReader streamReader, Stream stream, long totalBytesToRead)
{
byte[] buffer = streamReader.Buffer;
var buffer = streamReader.Buffer;
long remainingBytes = totalBytesToRead;
while (remainingBytes > 0)
......@@ -72,8 +72,8 @@ namespace Titanium.Web.Proxy.Extensions
{
while (true)
{
var chuchkHead = await clientStreamReader.ReadLineAsync();
var chunkSize = int.Parse(chuchkHead, NumberStyles.HexNumber);
string chuchkHead = await clientStreamReader.ReadLineAsync();
int chunkSize = int.Parse(chuchkHead, NumberStyles.HexNumber);
if (chunkSize != 0)
{
......@@ -119,7 +119,8 @@ namespace Titanium.Web.Proxy.Extensions
/// <param name="isChunked"></param>
/// <param name="contentLength"></param>
/// <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)
{
......@@ -147,8 +148,8 @@ namespace Titanium.Web.Proxy.Extensions
{
while (true)
{
var chunkHead = await inStreamReader.ReadLineAsync();
var chunkSize = int.Parse(chunkHead, NumberStyles.HexNumber);
string chunkHead = await inStreamReader.ReadLineAsync();
int chunkSize = int.Parse(chunkHead, NumberStyles.HexNumber);
if (chunkSize != 0)
{
......
......@@ -13,7 +13,7 @@ namespace Titanium.Web.Proxy.Extensions
internal static bool IsConnected(this Socket client)
{
// This is how you can determine whether a socket is still connected.
var blockingState = client.Blocking;
bool blockingState = client.Blocking;
try
{
......
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Concurrent;
namespace Titanium.Web.Proxy.Helpers
{
......
......@@ -34,7 +34,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns></returns>
internal async Task<string> ReadLineAsync()
{
var lastChar = default(byte);
byte lastChar = default(byte);
int bufferDataLength = 0;
......@@ -43,7 +43,7 @@ namespace Titanium.Web.Proxy.Helpers
while (stream.DataAvailable || await stream.FillBufferAsync())
{
var newChar = stream.ReadByteFromBuffer();
byte newChar = stream.ReadByteFromBuffer();
buffer[bufferDataLength] = newChar;
//if new line
......
......@@ -35,7 +35,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="bufferSize">Size of the buffer.</param>
public CustomBufferedStream(Stream baseStream, int bufferSize)
{
readCallback = new AsyncCallback(ReadCallback);
readCallback = ReadCallback;
this.baseStream = baseStream;
streamBuffer = BufferPool.GetBuffer(bufferSize);
}
......@@ -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>
protected override void Dispose(bool disposing)
{
if(!disposed)
if (!disposed)
{
disposed = true;
baseStream.Dispose();
......@@ -367,7 +367,6 @@ namespace Titanium.Web.Proxy.Helpers
streamBuffer = null;
readCallback = null;
}
}
/// <summary>
......
......@@ -16,9 +16,9 @@ namespace Titanium.Web.Proxy.Helpers
try
{
var myProfileDirectory =
new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +
"\\Mozilla\\Firefox\\Profiles\\").GetDirectories("*.default");
var myFfPrefFile = myProfileDirectory[0].FullName + "\\prefs.js";
new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Mozilla\\Firefox\\Profiles\\")
.GetDirectories("*.default");
string myFfPrefFile = myProfileDirectory[0].FullName + "\\prefs.js";
if (!File.Exists(myFfPrefFile))
{
return;
......@@ -26,18 +26,17 @@ namespace Titanium.Web.Proxy.Helpers
// We have a pref file so let''s make sure it has the proxy setting
var myReader = new StreamReader(myFfPrefFile);
var myPrefContents = myReader.ReadToEnd();
string myPrefContents = myReader.ReadToEnd();
myReader.Close();
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))
{
// Add the proxy enable line and write it back to the file
myPrefContents = myPrefContents.Replace(searchStr,
"user_pref(\"network.proxy.type\", 5);");
myPrefContents = myPrefContents.Replace(searchStr, "user_pref(\"network.proxy.type\", 5);");
}
}
......
......@@ -20,7 +20,7 @@ namespace Titanium.Web.Proxy.Helpers
//extract the encoding by finding the charset
var parameters = contentType.Split(ProxyConstants.SemiColonSplit);
foreach (var parameter in parameters)
foreach (string parameter in parameters)
{
var encodingSplit = parameter.Split(ProxyConstants.EqualSplit, 2);
if (encodingSplit.Length == 2 && encodingSplit[0].Trim().Equals("charset", StringComparison.CurrentCultureIgnoreCase))
......@@ -66,9 +66,8 @@ namespace Titanium.Web.Proxy.Helpers
if (hostname.Split(ProxyConstants.DotSplit).Length > 2)
{
int idx = hostname.IndexOf(ProxyConstants.DotSplit);
var rootDomain = hostname.Substring(idx + 1);
string rootDomain = hostname.Substring(idx + 1);
return "*." + rootDomain;
}
//return as it is
......
......@@ -15,7 +15,7 @@ namespace Titanium.Web.Proxy.Helpers
internal static int GetProcessIdFromPort(int port, bool ipV6Enabled)
{
var processId = FindProcessIdFromLocalPort(port, IpVersion.Ipv4);
int processId = FindProcessIdFromLocalPort(port, IpVersion.Ipv4);
if (processId > 0 && !ipV6Enabled)
{
......@@ -43,10 +43,10 @@ namespace Titanium.Web.Proxy.Helpers
{
bool isLocalhost = false;
IPHostEntry localhost = Dns.GetHostEntry("127.0.0.1");
var localhost = Dns.GetHostEntry("127.0.0.1");
if (hostName == localhost.HostName)
{
IPHostEntry hostEntry = Dns.GetHostEntry(hostName);
var hostEntry = Dns.GetHostEntry(hostName);
isLocalhost = hostEntry.AddressList.Any(IPAddress.IsLoopback);
}
......
......@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.Helpers
{
......@@ -37,14 +36,14 @@ namespace Titanium.Web.Proxy.Helpers
if (proxyServer != null)
{
Proxies = GetSystemProxyValues(proxyServer).ToDictionary(x=>x.ProtocolType);
Proxies = GetSystemProxyValues(proxyServer).ToDictionary(x => x.ProtocolType);
}
if (proxyOverride != null)
{
var overrides = proxyOverride.Split(';');
var overrides2 = new List<string>();
foreach (var overrideHost in overrides)
foreach (string overrideHost in overrides)
{
if (overrideHost == "<-loopback>")
{
......@@ -71,7 +70,8 @@ namespace Titanium.Web.Proxy.Helpers
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 rawString1;
string empty2;
......@@ -174,7 +174,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns></returns>
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);
if (equalsIndex >= 0)
......
......@@ -11,9 +11,8 @@ namespace Titanium.Web.Proxy.Helpers
/// cache for mono runtime check
/// </summary>
/// <returns></returns>
private static Lazy<bool> isRunningOnMono
= new Lazy<bool>(()=> Type.GetType("Mono.Runtime") != null);
private static readonly Lazy<bool> isRunningOnMono = new Lazy<bool>(() => Type.GetType("Mono.Runtime") != null);
/// <summary>
/// Is running on Mono?
/// </summary>
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.Win32;
......@@ -34,8 +33,7 @@ namespace Titanium.Web.Proxy.Helpers
internal partial class NativeMethods
{
[DllImport("wininet.dll")]
internal static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer,
int dwBufferLength);
internal static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);
[DllImport("kernel32.dll")]
internal static extern IntPtr GetConsoleWindow();
......@@ -129,7 +127,7 @@ namespace Titanium.Web.Proxy.Helpers
SaveOriginalProxyConfiguration(reg);
PrepareRegistry(reg);
var exisitingContent = reg.GetValue(regProxyServer) as string;
string exisitingContent = reg.GetValue(regProxyServer) as string;
var existingSystemProxyValues = ProxyInfo.GetSystemProxyValues(exisitingContent);
existingSystemProxyValues.RemoveAll(x => (protocolType & x.ProtocolType) != 0);
if ((protocolType & ProxyProtocolType.Http) != 0)
......@@ -175,7 +173,7 @@ namespace Titanium.Web.Proxy.Helpers
if (reg.GetValue(regProxyServer) != null)
{
var exisitingContent = reg.GetValue(regProxyServer) as string;
string exisitingContent = reg.GetValue(regProxyServer) as string;
var existingSystemProxyValues = ProxyInfo.GetSystemProxyValues(exisitingContent);
existingSystemProxyValues.RemoveAll(x => (protocolType & x.ProtocolType) != 0);
......@@ -305,11 +303,7 @@ namespace Titanium.Web.Proxy.Helpers
private ProxyInfo GetProxyInfoFromRegistry(RegistryKey reg)
{
var pi = new ProxyInfo(
null,
reg.GetValue(regAutoConfigUrl) as string,
reg.GetValue(regProxyEnable) as int?,
reg.GetValue(regProxyServer) as string,
var pi = new ProxyInfo(null, reg.GetValue(regAutoConfigUrl) as string, reg.GetValue(regProxyEnable) as int?, reg.GetValue(regProxyServer) as string,
reg.GetValue(regProxyOverride) as string);
return pi;
......
......@@ -83,12 +83,12 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns>Collection of <see cref="TcpRow"/>.</returns>
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;
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)
{
......@@ -97,9 +97,9 @@ namespace Titanium.Web.Proxy.Helpers
tcpTable = Marshal.AllocHGlobal(tcpTableLength);
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)
{
......@@ -126,10 +126,10 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns><see cref="TcpRow"/>.</returns>
internal static TcpRow GetTcpRowByLocalPort(IpVersion ipVersion, int localPort)
{
IntPtr tcpTable = IntPtr.Zero;
var tcpTable = IntPtr.Zero;
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)
{
......@@ -138,9 +138,9 @@ namespace Titanium.Web.Proxy.Helpers
tcpTable = Marshal.AllocHGlobal(tcpTableLength);
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)
{
......@@ -181,11 +181,8 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="tcpConnectionFactory"></param>
/// <param name="connection"></param>
/// <returns></returns>
internal static async Task SendRaw(ProxyServer server,
string remoteHostName, int remotePort,
string httpCmd, Version httpVersion, Dictionary<string, HttpHeader> requestHeaders,
bool isHttps,
Stream clientStream, TcpConnectionFactory tcpConnectionFactory,
internal static async Task SendRaw(ProxyServer server, string remoteHostName, int remotePort, string httpCmd, Version httpVersion,
Dictionary<string, HttpHeader> requestHeaders, bool isHttps, Stream clientStream, TcpConnectionFactory tcpConnectionFactory,
TcpConnection connection = null)
{
//prepare the prefix content
......@@ -202,7 +199,7 @@ namespace Titanium.Web.Proxy.Helpers
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(ProxyConstants.NewLine);
......@@ -218,10 +215,7 @@ namespace Titanium.Web.Proxy.Helpers
//create new connection if connection is null
if (connection == null)
{
tcpConnection = await tcpConnectionFactory.CreateClient(server,
remoteHostName, remotePort,
httpVersion, isHttps,
null, null);
tcpConnection = await tcpConnectionFactory.CreateClient(server, remoteHostName, remotePort, httpVersion, isHttps, null, null);
connectionCreated = true;
}
......@@ -232,7 +226,7 @@ namespace Titanium.Web.Proxy.Helpers
try
{
Stream tunnelStream = tcpConnection.Stream;
var tunnelStream = tcpConnection.Stream;
//Now async relay all server=>client & client=>server data
var sendRelay = clientStream.CopyToAsync(sb?.ToString() ?? string.Empty, tunnelStream);
......
......@@ -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);
[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)]
internal static extern bool WinHttpCloseHandle(IntPtr httpSession);
......@@ -62,8 +63,8 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
public AutoProxyFlags Flags;
public AutoDetectType AutoDetectFlags;
[MarshalAs(UnmanagedType.LPWStr)] public string AutoConfigUrl;
private IntPtr lpvReserved;
private int dwReserved;
private readonly IntPtr lpvReserved;
private readonly int dwReserved;
public bool AutoLogonIfChallenged;
}
......
......@@ -16,4 +16,4 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
public override bool IsInvalid => handle == IntPtr.Zero;
}
}
\ No newline at end of file
}
......@@ -21,12 +21,12 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
public bool BypassLoopback { get; internal set; }
public bool BypassOnLocal { get; internal set; }
public Uri AutomaticConfigurationScript { get; internal set; }
public bool AutomaticallyDetectSettings { get; internal set; }
private WebProxy Proxy { get; set; }
private WebProxy proxy { get; set; }
public WinHttpWebProxyFinder()
{
......@@ -89,26 +89,26 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
return null;
}
string proxy = proxies[0];
string proxyStr = proxies[0];
int port = 80;
if (proxy.Contains(":"))
if (proxyStr.Contains(":"))
{
var parts = proxy.Split(new[] { ':' }, 2);
proxy = parts[0];
var parts = proxyStr.Split(new[] { ':' }, 2);
proxyStr = parts[0];
port = int.Parse(parts[1]);
}
// TODO: Apply authorization
var systemProxy = new ExternalProxy
{
HostName = proxy,
HostName = proxyStr,
Port = port,
};
return systemProxy;
}
if (Proxy?.IsBypassed(destination) == true)
if (proxy?.IsBypassed(destination) == true)
return null;
var protocolType = ProxyInfo.ParseProtocolType(destination.Scheme);
......@@ -138,7 +138,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
AutomaticConfigurationScript = pi.AutoConfigUrl == null ? null : new Uri(pi.AutoConfigUrl);
BypassLoopback = pi.BypassLoopback;
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()
......@@ -214,7 +214,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
if (!WinHttpGetProxyForUrl(destination.ToString(), ref autoProxyOptions, out proxyListString))
{
num = GetLastWin32Error();
if (num == (int)NativeMethods.WinHttp.ErrorCodes.LoginFailure && Credentials != null)
{
autoProxyOptions.AutoLogonIfChallenged = true;
......@@ -329,4 +329,4 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
Completed,
}
}
}
\ No newline at end of file
}
......@@ -8,8 +8,7 @@ namespace Titanium.Web.Proxy.Http
{
internal static class HeaderParser
{
internal static async Task ReadHeaders(CustomBinaryReader reader,
Dictionary<string, List<HttpHeader>> nonUniqueResponseHeaders,
internal static async Task ReadHeaders(CustomBinaryReader reader, Dictionary<string, List<HttpHeader>> nonUniqueResponseHeaders,
Dictionary<string, HttpHeader> headers)
{
string tmpLine;
......@@ -29,7 +28,11 @@ namespace Titanium.Web.Proxy.Http
{
var existing = headers[newHeader.Name];
var nonUniqueHeaders = new List<HttpHeader> { existing, newHeader };
var nonUniqueHeaders = new List<HttpHeader>
{
existing,
newHeader
};
nonUniqueResponseHeaders.Add(newHeader.Name, nonUniqueHeaders);
headers.Remove(newHeader.Name);
......
......@@ -84,8 +84,8 @@ namespace Titanium.Web.Proxy.Http
//Send Authentication to Upstream proxy if needed
if (ServerConnection.UpStreamHttpProxy != null
&& ServerConnection.IsHttps == false
if (ServerConnection.UpStreamHttpProxy != null
&& ServerConnection.IsHttps == false
&& !string.IsNullOrEmpty(ServerConnection.UpStreamHttpProxy.UserName)
&& ServerConnection.UpStreamHttpProxy.Password != null)
{
......@@ -118,7 +118,7 @@ namespace Titanium.Web.Proxy.Http
requestLines.AppendLine();
var request = requestLines.ToString();
string request = requestLines.ToString();
var requestBytes = Encoding.ASCII.GetBytes(request);
await stream.WriteAsync(requestBytes, 0, requestBytes.Length);
......@@ -129,8 +129,8 @@ namespace Titanium.Web.Proxy.Http
if (Request.ExpectContinue)
{
var httpResult = (await ServerConnection.StreamReader.ReadLineAsync()).Split(ProxyConstants.SpaceSplit, 3);
var responseStatusCode = httpResult[1].Trim();
var responseStatusDescription = httpResult[2].Trim();
string responseStatusCode = httpResult[1].Trim();
string responseStatusDescription = httpResult[2].Trim();
//find if server is willing for expect continue
if (responseStatusCode.Equals("100")
......@@ -156,7 +156,8 @@ namespace Titanium.Web.Proxy.Http
internal async Task ReceiveResponse()
{
//return if this is already read
if (Response.ResponseStatusCode != null) return;
if (Response.ResponseStatusCode != null)
return;
string line = await ServerConnection.StreamReader.ReadLineAsync();
if (line == null)
......@@ -172,7 +173,7 @@ namespace Titanium.Web.Proxy.Http
httpResult = (await ServerConnection.StreamReader.ReadLineAsync()).Split(ProxyConstants.SpaceSplit, 3);
}
var httpVersion = httpResult[0];
string httpVersion = httpResult[0];
var version = HttpHeader.Version11;
if (string.Equals(httpVersion, "HTTP/1.0", StringComparison.OrdinalIgnoreCase))
......
using System;
using System.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Models;
......@@ -41,12 +41,12 @@ namespace Titanium.Web.Proxy.Http
{
get
{
var hasHeader = RequestHeaders.ContainsKey("host");
bool hasHeader = RequestHeaders.ContainsKey("host");
return hasHeader ? RequestHeaders["host"].Value : null;
}
set
{
var hasHeader = RequestHeaders.ContainsKey("host");
bool hasHeader = RequestHeaders.ContainsKey("host");
if (hasHeader)
{
RequestHeaders["host"].Value = value;
......@@ -65,7 +65,7 @@ namespace Titanium.Web.Proxy.Http
{
get
{
var hasHeader = RequestHeaders.ContainsKey("content-encoding");
bool hasHeader = RequestHeaders.ContainsKey("content-encoding");
if (hasHeader)
{
......@@ -83,7 +83,7 @@ namespace Titanium.Web.Proxy.Http
{
get
{
var hasHeader = RequestHeaders.ContainsKey("content-length");
bool hasHeader = RequestHeaders.ContainsKey("content-length");
if (hasHeader == false)
{
......@@ -103,7 +103,7 @@ namespace Titanium.Web.Proxy.Http
}
set
{
var hasHeader = RequestHeaders.ContainsKey("content-length");
bool hasHeader = RequestHeaders.ContainsKey("content-length");
var header = RequestHeaders["content-length"];
......@@ -137,7 +137,7 @@ namespace Titanium.Web.Proxy.Http
{
get
{
var hasHeader = RequestHeaders.ContainsKey("content-type");
bool hasHeader = RequestHeaders.ContainsKey("content-type");
if (hasHeader)
{
......@@ -149,7 +149,7 @@ namespace Titanium.Web.Proxy.Http
}
set
{
var hasHeader = RequestHeaders.ContainsKey("content-type");
bool hasHeader = RequestHeaders.ContainsKey("content-type");
if (hasHeader)
{
......@@ -170,7 +170,7 @@ namespace Titanium.Web.Proxy.Http
{
get
{
var hasHeader = RequestHeaders.ContainsKey("transfer-encoding");
bool hasHeader = RequestHeaders.ContainsKey("transfer-encoding");
if (hasHeader)
{
......@@ -183,7 +183,7 @@ namespace Titanium.Web.Proxy.Http
}
set
{
var hasHeader = RequestHeaders.ContainsKey("transfer-encoding");
bool hasHeader = RequestHeaders.ContainsKey("transfer-encoding");
if (value)
{
......@@ -216,9 +216,10 @@ namespace Titanium.Web.Proxy.Http
{
get
{
var hasHeader = RequestHeaders.ContainsKey("expect");
bool hasHeader = RequestHeaders.ContainsKey("expect");
if (!hasHeader) return false;
if (!hasHeader)
return false;
var header = RequestHeaders["expect"];
return header.Value.Equals("100-continue");
......@@ -267,7 +268,7 @@ namespace Titanium.Web.Proxy.Http
{
get
{
var hasHeader = RequestHeaders.ContainsKey("upgrade");
bool hasHeader = RequestHeaders.ContainsKey("upgrade");
if (hasHeader == false)
{
......@@ -317,8 +318,7 @@ namespace Titanium.Web.Proxy.Http
/// <returns></returns>
public bool HeaderExists(string name)
{
if (RequestHeaders.ContainsKey(name)
|| NonUniqueRequestHeaders.ContainsKey(name))
if (RequestHeaders.ContainsKey(name) || NonUniqueRequestHeaders.ContainsKey(name))
{
return true;
}
......@@ -336,9 +336,12 @@ namespace Titanium.Web.Proxy.Http
{
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]);
}
......@@ -387,8 +390,11 @@ namespace Titanium.Web.Proxy.Http
var existing = RequestHeaders[newHeader.Name];
RequestHeaders.Remove(newHeader.Name);
NonUniqueRequestHeaders.Add(newHeader.Name,
new List<HttpHeader>() { existing, newHeader });
NonUniqueRequestHeaders.Add(newHeader.Name, new List<HttpHeader>
{
existing,
newHeader
});
}
else
{
......@@ -409,7 +415,7 @@ namespace Titanium.Web.Proxy.Http
RequestHeaders.Remove(headerName);
return true;
}
else if (NonUniqueRequestHeaders.ContainsKey(headerName))
if (NonUniqueRequestHeaders.ContainsKey(headerName))
{
NonUniqueRequestHeaders.Remove(headerName);
return true;
......@@ -431,12 +437,10 @@ namespace Titanium.Web.Proxy.Http
RequestHeaders.Remove(header.Name);
return true;
}
}
else if (NonUniqueRequestHeaders.ContainsKey(header.Name))
{
if (NonUniqueRequestHeaders[header.Name]
.RemoveAll(x => x.Equals(header)) > 0)
if (NonUniqueRequestHeaders[header.Name].RemoveAll(x => x.Equals(header)) > 0)
{
return true;
}
......@@ -460,7 +464,5 @@ namespace Titanium.Web.Proxy.Http
RequestBody = null;
RequestBody = null;
}
}
}
using System;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Models;
......@@ -35,9 +34,10 @@ namespace Titanium.Web.Proxy.Http
{
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"];
return header.Value.Trim();
......@@ -56,7 +56,7 @@ namespace Titanium.Web.Proxy.Http
{
get
{
var hasHeader = ResponseHeaders.ContainsKey("connection");
bool hasHeader = ResponseHeaders.ContainsKey("connection");
if (hasHeader)
{
......@@ -79,7 +79,7 @@ namespace Titanium.Web.Proxy.Http
{
get
{
var hasHeader = ResponseHeaders.ContainsKey("content-type");
bool hasHeader = ResponseHeaders.ContainsKey("content-type");
if (hasHeader)
{
......@@ -99,7 +99,7 @@ namespace Titanium.Web.Proxy.Http
{
get
{
var hasHeader = ResponseHeaders.ContainsKey("content-length");
bool hasHeader = ResponseHeaders.ContainsKey("content-length");
if (hasHeader == false)
{
......@@ -119,7 +119,7 @@ namespace Titanium.Web.Proxy.Http
}
set
{
var hasHeader = ResponseHeaders.ContainsKey("content-length");
bool hasHeader = ResponseHeaders.ContainsKey("content-length");
if (value >= 0)
{
......@@ -152,7 +152,7 @@ namespace Titanium.Web.Proxy.Http
{
get
{
var hasHeader = ResponseHeaders.ContainsKey("transfer-encoding");
bool hasHeader = ResponseHeaders.ContainsKey("transfer-encoding");
if (hasHeader)
{
......@@ -168,7 +168,7 @@ namespace Titanium.Web.Proxy.Http
}
set
{
var hasHeader = ResponseHeaders.ContainsKey("transfer-encoding");
bool hasHeader = ResponseHeaders.ContainsKey("transfer-encoding");
if (value)
{
......@@ -250,8 +250,7 @@ namespace Titanium.Web.Proxy.Http
/// <returns></returns>
public bool HeaderExists(string name)
{
if(ResponseHeaders.ContainsKey(name)
|| NonUniqueResponseHeaders.ContainsKey(name))
if (ResponseHeaders.ContainsKey(name) || NonUniqueResponseHeaders.ContainsKey(name))
{
return true;
}
......@@ -269,9 +268,12 @@ namespace Titanium.Web.Proxy.Http
{
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]);
}
......@@ -320,8 +322,11 @@ namespace Titanium.Web.Proxy.Http
var existing = ResponseHeaders[newHeader.Name];
ResponseHeaders.Remove(newHeader.Name);
NonUniqueResponseHeaders.Add(newHeader.Name,
new List<HttpHeader>() { existing, newHeader });
NonUniqueResponseHeaders.Add(newHeader.Name, new List<HttpHeader>
{
existing,
newHeader
});
}
else
{
......@@ -337,12 +342,12 @@ namespace Titanium.Web.Proxy.Http
/// False if no header exists with given name</returns>
public bool RemoveHeader(string headerName)
{
if(ResponseHeaders.ContainsKey(headerName))
if (ResponseHeaders.ContainsKey(headerName))
{
ResponseHeaders.Remove(headerName);
return true;
}
else if (NonUniqueResponseHeaders.ContainsKey(headerName))
if (NonUniqueResponseHeaders.ContainsKey(headerName))
{
NonUniqueResponseHeaders.Remove(headerName);
return true;
......@@ -364,12 +369,10 @@ namespace Titanium.Web.Proxy.Http
ResponseHeaders.Remove(header.Name);
return true;
}
}
else if (NonUniqueResponseHeaders.ContainsKey(header.Name))
{
if (NonUniqueResponseHeaders[header.Name]
.RemoveAll(x => x.Equals(header)) > 0)
if (NonUniqueResponseHeaders[header.Name].RemoveAll(x => x.Equals(header)) > 0)
{
return true;
}
......
......@@ -53,7 +53,6 @@ namespace Titanium.Web.Proxy.Models
public bool IpV6Enabled => Equals(IpAddress, IPAddress.IPv6Any)
|| Equals(IpAddress, IPAddress.IPv6Loopback)
|| Equals(IpAddress, IPAddress.IPv6None);
}
/// <summary>
......@@ -120,11 +119,14 @@ namespace Titanium.Web.Proxy.Models
/// <param name="ipAddress"></param>
/// <param name="port"></param>
/// <param name="enableSsl"></param>
public ExplicitProxyEndPoint(IPAddress ipAddress, int port, bool enableSsl)
: base(ipAddress, port, enableSsl)
public ExplicitProxyEndPoint(IPAddress ipAddress, int port, bool enableSsl) : base(ipAddress, port, enableSsl)
{
//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
/// <param name="ipAddress"></param>
/// <param name="port"></param>
/// <param name="enableSsl"></param>
public TransparentProxyEndPoint(IPAddress ipAddress, int port, bool enableSsl)
: base(ipAddress, port, enableSsl)
public TransparentProxyEndPoint(IPAddress ipAddress, int port, bool enableSsl) : base(ipAddress, port, enableSsl)
{
GenericCertificateName = "localhost";
}
......
......@@ -81,14 +81,10 @@ namespace Titanium.Web.Proxy.Network.Certificate
if (hostName != null)
{
//add subject alternative names
var subjectAlternativeNames = new Asn1Encodable[]
{
new GeneralName(GeneralName.DnsName, hostName),
};
var subjectAlternativeNames = new Asn1Encodable[] { new GeneralName(GeneralName.DnsName, hostName), };
var subjectAlternativeNamesExtension = new DerSequence(subjectAlternativeNames);
certificateGenerator.AddExtension(
X509Extensions.SubjectAlternativeName.Id, false, subjectAlternativeNamesExtension);
certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName.Id, false, subjectAlternativeNamesExtension);
}
// Subject Public Key
var keyGenerationParameters = new KeyGenerationParameters(secureRandom, keyStrength);
......@@ -118,7 +114,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
}
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
x509Certificate.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
......@@ -138,9 +135,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// <param name="signingCertificate">The signing certificate.</param>
/// <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>
private X509Certificate2 MakeCertificateInternal(bool isRoot,
string hostName, string subjectName,
DateTime validFrom, DateTime validTo, X509Certificate2 signingCertificate)
private X509Certificate2 MakeCertificateInternal(bool isRoot, string hostName, string subjectName, DateTime validFrom, DateTime validTo,
X509Certificate2 signingCertificate)
{
if (isRoot != (null == signingCertificate))
{
......@@ -149,7 +145,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
return isRoot
? 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>
......@@ -187,7 +184,8 @@ namespace Titanium.Web.Proxy.Network.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
typeX509Enrollment.InvokeMember("CertificateFriendlyName", BindingFlags.PutDispProperty, null, x509Enrollment, typeValue);
}
var members = typeX509Enrollment.GetMembers();
typeValue[0] = 0;
var createCertRequest = typeX509Enrollment.InvokeMember("CreateRequest", BindingFlags.InvokeMethod, null, x509Enrollment, typeValue);
......@@ -251,7 +249,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
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);
}
catch (Exception)
......@@ -281,15 +279,15 @@ namespace Titanium.Web.Proxy.Network.Certificate
}
//Subject
var fullSubject = $"CN={sSubjectCN}";
string fullSubject = $"CN={sSubjectCN}";
//Sig Algo
var HashAlgo = "SHA256";
string HashAlgo = "SHA256";
//Grace Days
var GraceDays = -366;
int GraceDays = -366;
//ValiDays
var ValidDays = 1825;
int ValidDays = 1825;
//KeyLength
var keyLength = 2048;
int keyLength = 2048;
var graceTime = DateTime.Now.AddDays(GraceDays);
var now = DateTime.Now;
......
......@@ -52,9 +52,7 @@ namespace Titanium.Web.Proxy.Network
if (certEngine == null)
{
certEngine = engine == CertificateEngine.BouncyCastle
? (ICertificateMaker)new BCCertificateMaker()
: new WinCertificateMaker();
certEngine = engine == CertificateEngine.BouncyCastle ? (ICertificateMaker)new BCCertificateMaker() : new WinCertificateMaker();
}
}
}
......@@ -134,7 +132,7 @@ namespace Titanium.Web.Proxy.Network
private string GetRootCertificatePath()
{
var assemblyLocation = Assembly.GetExecutingAssembly().Location;
string assemblyLocation = Assembly.GetExecutingAssembly().Location;
// dynamically loaded assemblies returns string.Empty location
if (assemblyLocation == string.Empty)
......@@ -142,16 +140,18 @@ namespace Titanium.Web.Proxy.Network
assemblyLocation = Assembly.GetEntryAssembly().Location;
}
var path = Path.GetDirectoryName(assemblyLocation);
if (null == path) throw new NullReferenceException();
var fileName = Path.Combine(path, "rootCert.pfx");
string path = Path.GetDirectoryName(assemblyLocation);
if (null == path)
throw new NullReferenceException();
string fileName = Path.Combine(path, "rootCert.pfx");
return fileName;
}
private X509Certificate2 LoadRootCertificate()
{
var fileName = GetRootCertificatePath();
if (!File.Exists(fileName)) return null;
string fileName = GetRootCertificatePath();
if (!File.Exists(fileName))
return null;
try
{
return new X509Certificate2(fileName, string.Empty, X509KeyStorageFlags.Exportable);
......@@ -195,7 +195,7 @@ namespace Titanium.Web.Proxy.Network
{
try
{
var fileName = GetRootCertificatePath();
string fileName = GetRootCertificatePath();
File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12));
}
catch (Exception e)
......@@ -231,7 +231,7 @@ namespace Titanium.Web.Proxy.Network
return false;
}
var fileName = Path.GetTempFileName();
string fileName = Path.GetTempFileName();
File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12));
var info = new ProcessStartInfo
......@@ -340,7 +340,7 @@ namespace Titanium.Web.Proxy.Network
private X509Certificate2Collection FindCertificates(StoreName storeName, StoreLocation storeLocation, string findValue)
{
X509Store x509Store = new X509Store(storeName, storeLocation);
var x509Store = new X509Store(storeName, storeLocation);
try
{
x509Store.Open(OpenFlags.OpenExistingOnly);
......@@ -351,7 +351,7 @@ namespace Titanium.Web.Proxy.Network
x509Store.Close();
}
}
/// <summary>
/// Create an SSL certificate
/// </summary>
......@@ -387,7 +387,10 @@ namespace Titanium.Web.Proxy.Network
}
if (certificate != null && !certificateCache.ContainsKey(certificateName))
{
certificateCache.Add(certificateName, new CachedCertificate { Certificate = certificate });
certificateCache.Add(certificateName, new CachedCertificate
{
Certificate = certificate
});
}
}
else
......@@ -422,9 +425,7 @@ namespace Titanium.Web.Proxy.Network
{
var cutOff = DateTime.Now.AddMinutes(-1 * certificateCacheTimeOutMinutes);
var outdated = certificateCache
.Where(x => x.Value.LastAccess < cutOff)
.ToList();
var outdated = certificateCache.Where(x => x.Value.LastAccess < cutOff).ToList();
foreach (var cache in outdated)
certificateCache.Remove(cache.Key);
......
......@@ -29,22 +29,17 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <param name="externalHttpProxy"></param>
/// <param name="externalHttpsProxy"></param>
/// <returns></returns>
internal async Task<TcpConnection> CreateClient(ProxyServer server,
string remoteHostName, int remotePort, Version httpVersion,
bool isHttps,
internal async Task<TcpConnection> CreateClient(ProxyServer server, string remoteHostName, int remotePort, Version httpVersion, bool isHttps,
ExternalProxy externalHttpProxy, ExternalProxy externalHttpsProxy)
{
bool useHttpProxy = false;
bool useHttpProxy = false;
//check if external proxy is set for HTTP
if (!isHttps && externalHttpProxy != null
&& !(externalHttpProxy.HostName == remoteHostName
&& externalHttpProxy.Port == remotePort))
if (!isHttps && externalHttpProxy != null && !(externalHttpProxy.HostName == remoteHostName && externalHttpProxy.Port == remotePort))
{
useHttpProxy = true;
//check if we need to ByPass
if (externalHttpProxy.BypassLocalhost
&& NetworkHelper.IsLocalIpAddress(remoteHostName))
if (externalHttpProxy.BypassLocalhost && NetworkHelper.IsLocalIpAddress(remoteHostName))
{
useHttpProxy = false;
}
......@@ -52,15 +47,12 @@ namespace Titanium.Web.Proxy.Network.Tcp
bool useHttpsProxy = false;
//check if external proxy is set for HTTPS
if (isHttps && externalHttpsProxy != null
&& !(externalHttpsProxy.HostName == remoteHostName
&& externalHttpsProxy.Port == remotePort))
if (isHttps && externalHttpsProxy != null && !(externalHttpsProxy.HostName == remoteHostName && externalHttpsProxy.Port == remotePort))
{
useHttpsProxy = true;
//check if we need to ByPass
if (externalHttpsProxy.BypassLocalhost
&& NetworkHelper.IsLocalIpAddress(remoteHostName))
if (externalHttpsProxy.BypassLocalhost && NetworkHelper.IsLocalIpAddress(remoteHostName))
{
useHttpsProxy = false;
}
......@@ -80,7 +72,10 @@ namespace Titanium.Web.Proxy.Network.Tcp
await client.ConnectAsync(externalHttpsProxy.HostName, externalHttpsProxy.Port);
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($"Host: {remoteHostName}:{remotePort}");
......@@ -89,7 +84,9 @@ namespace Titanium.Web.Proxy.Network.Tcp
if (!string.IsNullOrEmpty(externalHttpsProxy.UserName) && externalHttpsProxy.Password != null)
{
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.FlushAsync();
......@@ -98,7 +95,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
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)))
{
......
......@@ -11,21 +11,19 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// </seealso>
internal class TcpTable : IEnumerable<TcpRow>
{
private readonly IEnumerable<TcpRow> tcpRows;
/// <summary>
/// Initializes a new instance of the <see cref="TcpTable"/> class.
/// </summary>
/// <param name="tcpRows">TcpRow collection to initialize with.</param>
internal TcpTable(IEnumerable<TcpRow> tcpRows)
{
this.tcpRows = tcpRows;
this.TcpRows = tcpRows;
}
/// <summary>
/// Gets the TCP rows.
/// </summary>
internal IEnumerable<TcpRow> TcpRows => tcpRows;
internal IEnumerable<TcpRow> TcpRows { get; }
/// <summary>
/// Returns an enumerator that iterates through the collection.
......@@ -33,7 +31,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <returns>An enumerator that can be used to iterate through the collection.</returns>
public IEnumerator<TcpRow> GetEnumerator()
{
return tcpRows.GetEnumerator();
return TcpRows.GetEnumerator();
}
/// <summary>
......
namespace Titanium.Web.Proxy.Network.WinAuth.Security
{
using System;
using System.Runtime.InteropServices;
using System;
using System.Runtime.InteropServices;
namespace Titanium.Web.Proxy.Network.WinAuth.Security
{
internal class Common
{
#region Private constants
private const int ISC_REQ_REPLAY_DETECT = 0x00000004;
private const int ISC_REQ_SEQUENCE_DETECT = 0x00000008;
private const int ISC_REQ_CONFIDENTIALITY = 0x00000010;
private const int ISC_REQ_CONNECTION = 0x00000800;
#endregion
internal static uint NewContextAttributes = 0;
internal static Common.SecurityInteger NewLifeTime = new SecurityInteger(0);
internal static SecurityInteger NewLifeTime = new SecurityInteger(0);
#region internal constants
internal const int StandardContextAttributes = ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_CONNECTION;
internal const int SecurityNativeDataRepresentation = 0x10;
internal const int MaximumTokenSize = 12288;
internal const int SecurityCredentialsOutbound = 2;
internal const int SuccessfulResult = 0;
internal const int IntermediateResult = 0x90312;
#endregion
#region internal enumerations
internal enum SecurityBufferType
{
SECBUFFER_VERSION = 0,
......@@ -34,26 +39,35 @@
}
[Flags]
internal enum NtlmFlags : int
internal enum NtlmFlags
{
// The client sets this flag to indicate that it supports Unicode strings.
NegotiateUnicode = 0x00000001,
// This is set to indicate that the client supports OEM strings.
NegotiateOem = 0x00000002,
// This requests that the server send the authentication target with the Type 2 reply.
RequestTarget = 0x00000004,
// Indicates that NTLM authentication is supported.
NegotiateNtlm = 0x00000200,
// When set, the client will send with the message the name of the domain in which the workstation has membership.
NegotiateDomainSupplied = 0x00001000,
// Indicates that the client is sending its workstation name with the message.
NegotiateWorkstationSupplied = 0x00002000,
// Indicates that communication between the client and server after authentication should carry a "dummy" signature.
NegotiateAlwaysSign = 0x00008000,
// Indicates that this client supports the NTLM2 signing and sealing scheme; if negotiated, this can also affect the response calculations.
NegotiateNtlm2Key = 0x00080000,
// Indicates that this client supports strong (128-bit) encryption.
Negotiate128 = 0x20000000,
// Indicates that this client supports medium (56-bit) encryption.
Negotiate56 = (unchecked((int)0x80000000))
}
......@@ -74,9 +88,11 @@
/* Use NTLMv2 only. */
NTLMv2_only,
}
#endregion
#region internal structures
[StructLayout(LayoutKind.Sequential)]
internal struct SecurityHandle
{
......@@ -102,6 +118,7 @@
{
internal uint LowPart;
internal int HighPart;
internal SecurityInteger(int dummy)
{
LowPart = 0;
......@@ -152,7 +169,6 @@
[StructLayout(LayoutKind.Sequential)]
internal struct SecurityBufferDesciption : IDisposable
{
internal int ulVersion;
internal int cBuffers;
internal IntPtr pBuffers; //Point to SecBuffer
......@@ -161,18 +177,18 @@
{
ulVersion = (int)SecurityBufferType.SECBUFFER_VERSION;
cBuffers = 1;
Common.SecurityBuffer ThisSecBuffer = new Common.SecurityBuffer(bufferSize);
pBuffers = Marshal.AllocHGlobal(Marshal.SizeOf(ThisSecBuffer));
Marshal.StructureToPtr(ThisSecBuffer, pBuffers, false);
var thisSecBuffer = new SecurityBuffer(bufferSize);
pBuffers = Marshal.AllocHGlobal(Marshal.SizeOf(thisSecBuffer));
Marshal.StructureToPtr(thisSecBuffer, pBuffers, false);
}
internal SecurityBufferDesciption(byte[] secBufferBytes)
{
ulVersion = (int)SecurityBufferType.SECBUFFER_VERSION;
cBuffers = 1;
Common.SecurityBuffer ThisSecBuffer = new Common.SecurityBuffer(secBufferBytes);
pBuffers = Marshal.AllocHGlobal(Marshal.SizeOf(ThisSecBuffer));
Marshal.StructureToPtr(ThisSecBuffer, pBuffers, false);
var thisSecBuffer = new SecurityBuffer(secBufferBytes);
pBuffers = Marshal.AllocHGlobal(Marshal.SizeOf(thisSecBuffer));
Marshal.StructureToPtr(thisSecBuffer, pBuffers, false);
}
public void Dispose()
......@@ -181,12 +197,12 @@
{
if (cBuffers == 1)
{
Common.SecurityBuffer ThisSecBuffer = (Common.SecurityBuffer)Marshal.PtrToStructure(pBuffers, typeof(Common.SecurityBuffer));
ThisSecBuffer.Dispose();
var thisSecBuffer = (SecurityBuffer)Marshal.PtrToStructure(pBuffers, typeof(SecurityBuffer));
thisSecBuffer.Dispose();
}
else
{
for (int Index = 0; Index < cBuffers; Index++)
for (int index = 0; index < cBuffers; index++)
{
//The bits were written out the following order:
//int cbBuffer;
......@@ -194,9 +210,9 @@
//pvBuffer;
//What we need to do here is to grab a hold of the pvBuffer allocate by the individual
//SecBuffer and release it...
int CurrentOffset = Index * Marshal.SizeOf(typeof(Buffer));
IntPtr SecBufferpvBuffer = Marshal.ReadIntPtr(pBuffers, CurrentOffset + Marshal.SizeOf(typeof(int)) + Marshal.SizeOf(typeof(int)));
Marshal.FreeHGlobal(SecBufferpvBuffer);
int currentOffset = index * Marshal.SizeOf(typeof(Buffer));
var secBufferpvBuffer = Marshal.ReadIntPtr(pBuffers, currentOffset + Marshal.SizeOf(typeof(int)) + Marshal.SizeOf(typeof(int)));
Marshal.FreeHGlobal(secBufferpvBuffer);
}
}
......@@ -207,7 +223,7 @@
internal byte[] GetBytes()
{
byte[] Buffer = null;
byte[] buffer = null;
if (pBuffers == IntPtr.Zero)
{
......@@ -216,32 +232,32 @@
if (cBuffers == 1)
{
Common.SecurityBuffer ThisSecBuffer = (Common.SecurityBuffer)Marshal.PtrToStructure(pBuffers, typeof(Common.SecurityBuffer));
var thisSecBuffer = (SecurityBuffer)Marshal.PtrToStructure(pBuffers, typeof(SecurityBuffer));
if (ThisSecBuffer.cbBuffer > 0)
if (thisSecBuffer.cbBuffer > 0)
{
Buffer = new byte[ThisSecBuffer.cbBuffer];
Marshal.Copy(ThisSecBuffer.pvBuffer, Buffer, 0, ThisSecBuffer.cbBuffer);
buffer = new byte[thisSecBuffer.cbBuffer];
Marshal.Copy(thisSecBuffer.pvBuffer, buffer, 0, thisSecBuffer.cbBuffer);
}
}
else
{
int BytesToAllocate = 0;
int bytesToAllocate = 0;
for (int Index = 0; Index < cBuffers; Index++)
for (int index = 0; index < cBuffers; index++)
{
//The bits were written out the following order:
//int cbBuffer;
//int BufferType;
//pvBuffer;
//What we need to do here calculate the total number of bytes we need to copy...
int CurrentOffset = Index * Marshal.SizeOf(typeof(Buffer));
BytesToAllocate += Marshal.ReadInt32(pBuffers, CurrentOffset);
int currentOffset = index * Marshal.SizeOf(typeof(Buffer));
bytesToAllocate += Marshal.ReadInt32(pBuffers, currentOffset);
}
Buffer = new byte[BytesToAllocate];
buffer = new byte[bytesToAllocate];
for (int Index = 0, BufferIndex = 0; Index < cBuffers; Index++)
for (int index = 0, bufferIndex = 0; index < cBuffers; index++)
{
//The bits were written out the following order:
//int cbBuffer;
......@@ -249,17 +265,18 @@
//pvBuffer;
//Now iterate over the individual buffers and put them together into a
//byte array...
int CurrentOffset = Index * Marshal.SizeOf(typeof(Buffer));
int BytesToCopy = Marshal.ReadInt32(pBuffers, CurrentOffset);
IntPtr SecBufferpvBuffer = Marshal.ReadIntPtr(pBuffers, CurrentOffset + Marshal.SizeOf(typeof(int)) + Marshal.SizeOf(typeof(int)));
Marshal.Copy(SecBufferpvBuffer, Buffer, BufferIndex, BytesToCopy);
BufferIndex += BytesToCopy;
int currentOffset = index * Marshal.SizeOf(typeof(Buffer));
int bytesToCopy = Marshal.ReadInt32(pBuffers, currentOffset);
var secBufferpvBuffer = Marshal.ReadIntPtr(pBuffers, currentOffset + Marshal.SizeOf(typeof(int)) + Marshal.SizeOf(typeof(int)));
Marshal.Copy(secBufferpvBuffer, buffer, bufferIndex, bytesToCopy);
bufferIndex += bytesToCopy;
}
}
return (Buffer);
return (buffer);
}
}
#endregion
}
}
......@@ -27,231 +27,226 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
namespace Titanium.Web.Proxy.Network.WinAuth.Security
{
using System;
internal sealed class LittleEndian
{
private LittleEndian()
{
}
private static unsafe byte[] GetUShortBytes(byte*bytes)
{
if (BitConverter.IsLittleEndian)
{
return new[] { bytes[0], bytes[1] };
}
internal sealed class LittleEndian
{
private LittleEndian ()
{
}
return new[] { bytes[1], bytes[0] };
}
unsafe private static byte[] GetUShortBytes (byte *bytes)
{
private static unsafe byte[] GetUIntBytes(byte*bytes)
{
if (BitConverter.IsLittleEndian)
{
return new byte[] { bytes[0], bytes[1] };
return new[] { bytes[0], bytes[1], bytes[2], bytes[3] };
}
else
return new[] { bytes[3], bytes[2], bytes[1], bytes[0] };
}
private static unsafe byte[] GetULongBytes(byte*bytes)
{
if (BitConverter.IsLittleEndian)
{
return new byte[] { bytes[1], bytes[0] };
return new[] { bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7] };
}
}
unsafe private static byte[] GetUIntBytes (byte *bytes)
{
return new[] { bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0] };
}
internal static byte[] GetBytes(bool value)
{
return new[] { value ? (byte)1 : (byte)0 };
}
internal static unsafe byte[] GetBytes(char value)
{
return GetUShortBytes((byte*)&value);
}
internal static unsafe byte[] GetBytes(short value)
{
return GetUShortBytes((byte*)&value);
}
internal static unsafe byte[] GetBytes(int value)
{
return GetUIntBytes((byte*)&value);
}
internal static unsafe byte[] GetBytes(long value)
{
return GetULongBytes((byte*)&value);
}
internal static unsafe byte[] GetBytes(ushort value)
{
return GetUShortBytes((byte*)&value);
}
internal static unsafe byte[] GetBytes(uint value)
{
return GetUIntBytes((byte*)&value);
}
internal static unsafe byte[] GetBytes(ulong value)
{
return GetULongBytes((byte*)&value);
}
internal static unsafe byte[] GetBytes(float value)
{
return GetUIntBytes((byte*)&value);
}
internal static unsafe byte[] GetBytes(double value)
{
return GetULongBytes((byte*)&value);
}
private static unsafe void UShortFromBytes(byte*dst, byte[] src, int startIndex)
{
if (BitConverter.IsLittleEndian)
{
return new byte[] { bytes[0], bytes[1], bytes[2], bytes[3] };
dst[0] = src[startIndex];
dst[1] = src[startIndex + 1];
}
else
{
return new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] };
dst[0] = src[startIndex + 1];
dst[1] = src[startIndex];
}
}
}
unsafe private static byte[] GetULongBytes (byte *bytes)
{
private static unsafe void UIntFromBytes(byte*dst, byte[] src, int startIndex)
{
if (BitConverter.IsLittleEndian)
{
return new byte[] { bytes [0], bytes [1], bytes [2], bytes [3],
bytes [4], bytes [5], bytes [6], bytes [7] };
dst[0] = src[startIndex];
dst[1] = src[startIndex + 1];
dst[2] = src[startIndex + 2];
dst[3] = src[startIndex + 3];
}
else
{
return new byte[] { bytes [7], bytes [6], bytes [5], bytes [4],
bytes [3], bytes [2], bytes [1], bytes [0] };
dst[0] = src[startIndex + 3];
dst[1] = src[startIndex + 2];
dst[2] = src[startIndex + 1];
dst[3] = src[startIndex];
}
}
unsafe internal static byte[] GetBytes (bool value)
{
return new byte [] { value ? (byte)1 : (byte)0 };
}
unsafe internal static byte[] GetBytes (char value)
{
return GetUShortBytes ((byte *) &value);
}
unsafe internal static byte[] GetBytes (short value)
{
return GetUShortBytes ((byte *) &value);
}
unsafe internal static byte[] GetBytes (int value)
{
return GetUIntBytes ((byte *) &value);
}
unsafe internal static byte[] GetBytes (long value)
{
return GetULongBytes ((byte *) &value);
}
unsafe internal static byte[] GetBytes (ushort value)
{
return GetUShortBytes ((byte *) &value);
}
unsafe internal static byte[] GetBytes (uint value)
{
return GetUIntBytes ((byte *) &value);
}
unsafe internal static byte[] GetBytes (ulong value)
{
return GetULongBytes ((byte *) &value);
}
unsafe internal static byte[] GetBytes (float value)
{
return GetUIntBytes ((byte *) &value);
}
unsafe internal static byte[] GetBytes (double value)
{
return GetULongBytes ((byte *) &value);
}
unsafe private static void UShortFromBytes (byte *dst, byte[] src, int startIndex)
{
if (BitConverter.IsLittleEndian)
{
dst [0] = src [startIndex];
dst [1] = src [startIndex + 1];
}
else
{
dst [0] = src [startIndex + 1];
dst [1] = src [startIndex];
}
}
unsafe private static void UIntFromBytes (byte *dst, byte[] src, int startIndex)
{
if (BitConverter.IsLittleEndian)
}
private static unsafe void ULongFromBytes(byte*dst, byte[] src, int startIndex)
{
if (BitConverter.IsLittleEndian)
{
dst [0] = src [startIndex];
dst [1] = src [startIndex + 1];
dst [2] = src [startIndex + 2];
dst [3] = src [startIndex + 3];
}
else
for (int i = 0; i < 8; ++i)
dst[i] = src[startIndex + i];
}
else
{
dst [0] = src [startIndex + 3];
dst [1] = src [startIndex + 2];
dst [2] = src [startIndex + 1];
dst [3] = src [startIndex];
}
}
unsafe private static void ULongFromBytes (byte *dst, byte[] src, int startIndex)
{
if (BitConverter.IsLittleEndian) {
for (int i = 0; i < 8; ++i)
dst [i] = src [startIndex + i];
} else {
for (int i = 0; i < 8; ++i)
dst [i] = src [startIndex + (7 - i)];
}
}
for (int i = 0; i < 8; ++i)
dst[i] = src[startIndex + (7 - i)];
}
}
unsafe internal static bool ToBoolean (byte[] value, int startIndex)
{
return value [startIndex] != 0;
}
internal static bool ToBoolean(byte[] value, int startIndex)
{
return value[startIndex] != 0;
}
unsafe internal static char ToChar (byte[] value, int startIndex)
{
char ret;
internal static unsafe char ToChar(byte[] value, int startIndex)
{
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)
{
short ret;
internal static unsafe short ToInt16(byte[] value, int startIndex)
{
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)
{
int ret;
internal static unsafe int ToInt32(byte[] value, int startIndex)
{
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)
{
long ret;
internal static unsafe long ToInt64(byte[] value, int startIndex)
{
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)
{
ushort ret;
internal static unsafe ushort ToUInt16(byte[] value, int startIndex)
{
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)
{
uint ret;
internal static unsafe uint ToUInt32(byte[] value, int startIndex)
{
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)
{
ulong ret;
internal static unsafe ulong ToUInt64(byte[] value, int startIndex)
{
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)
{
float ret;
internal static unsafe float ToSingle(byte[] value, int startIndex)
{
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)
{
double ret;
internal static unsafe double ToDouble(byte[] value, int startIndex)
{
double ret;
ULongFromBytes ((byte *) &ret, value, startIndex);
ULongFromBytes((byte*)&ret, value, startIndex);
return ret;
}
}
return ret;
}
}
}
......@@ -33,51 +33,38 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Titanium.Web.Proxy.Network.WinAuth.Security
{
using System;
using System.Text;
using System;
using System.Text;
internal class Message
namespace Titanium.Web.Proxy.Network.WinAuth.Security
{
internal class Message
{
static private byte[] header = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00 };
internal Message (byte[] message)
{
_type = 3;
Decode (message);
}
/// <summary>
/// Domain name
/// </summary>
internal string Domain
private static readonly byte[] header = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00 };
internal Message(byte[] message)
{
get;
private set;
type = 3;
Decode(message);
}
/// <summary>
/// Domain name
/// </summary>
internal string Domain { get; private set; }
/// <summary>
/// Username
/// </summary>
internal string Username
{
get;
private set;
}
internal string Username { get; private set; }
private int _type;
private Common.NtlmFlags _flags;
private readonly int type;
internal Common.NtlmFlags Flags
{
get { return _flags; }
set { _flags = value; }
}
internal Common.NtlmFlags Flags { get; set; }
// methods
private void Decode (byte[] message)
{
// methods
private void Decode(byte[] message)
{
//base.Decode (message);
if (message == null)
......@@ -95,11 +82,11 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
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.";
throw new ArgumentException (msg, "message");
}
string msg = "Invalid Type3 message length.";
throw new ArgumentException(msg, "message");
}
if (message.Length >= 64)
{
......@@ -109,28 +96,25 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
{
Flags = (Common.NtlmFlags)0x8201;
}
int dom_len = LittleEndian.ToUInt16 (message, 28);
int dom_off = LittleEndian.ToUInt16 (message, 32);
this.Domain = DecodeString (message, dom_off, dom_len);
int domLen = LittleEndian.ToUInt16(message, 28);
int domOff = LittleEndian.ToUInt16(message, 32);
int user_len = LittleEndian.ToUInt16 (message, 36);
int user_off = LittleEndian.ToUInt16 (message, 40);
Domain = DecodeString(message, domOff, domLen);
this.Username = DecodeString (message, user_off, user_len);
}
int userLen = LittleEndian.ToUInt16(message, 36);
int userOff = LittleEndian.ToUInt16(message, 40);
string DecodeString (byte[] buffer, int offset, int len)
{
Username = DecodeString(message, userOff, userLen);
}
string DecodeString(byte[] buffer, int offset, int len)
{
if ((Flags & Common.NtlmFlags.NegotiateUnicode) != 0)
{
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)
......@@ -140,8 +124,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
if (message[i] != header[i])
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>
/// Status of authenticated session
/// </summary>
......@@ -9,10 +9,10 @@
{
internal State()
{
this.Credentials = new Common.SecurityHandle(0);
this.Context = new Common.SecurityHandle(0);
Credentials = new Common.SecurityHandle(0);
Context = new Common.SecurityHandle(0);
this.LastSeen = DateTime.Now;
LastSeen = DateTime.Now;
}
/// <summary>
......@@ -32,13 +32,13 @@
internal void ResetHandles()
{
this.Credentials.Reset();
this.Context.Reset();
Credentials.Reset();
Context.Reset();
}
internal void UpdatePresence()
{
this.LastSeen = DateTime.Now;
LastSeen = DateTime.Now;
}
}
}
// 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
{
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 System.Threading.Tasks;
internal class WinAuthEndPoint
{
/// <summary>
/// Keep track of auth states for reuse in final challenge response
/// </summary>
private static IDictionary<Guid, State> authStates
= new ConcurrentDictionary<Guid, State>();
private static readonly IDictionary<Guid, State> authStates = new ConcurrentDictionary<Guid, State>();
/// <summary>
......@@ -27,17 +27,14 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
/// <param name="authScheme"></param>
/// <param name="requestId"></param>
/// <returns></returns>
internal static byte[] AcquireInitialSecurityToken(string hostname,
string authScheme, Guid requestId)
internal static byte[] AcquireInitialSecurityToken(string hostname, string authScheme, Guid requestId)
{
byte[] token = null;
byte[] token;
//null for initial call
SecurityBufferDesciption serverToken
= new SecurityBufferDesciption();
var serverToken = new SecurityBufferDesciption();
SecurityBufferDesciption clientToken
= new SecurityBufferDesciption(MaximumTokenSize);
var clientToken = new SecurityBufferDesciption(MaximumTokenSize);
try
{
......@@ -53,7 +50,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
IntPtr.Zero,
0,
IntPtr.Zero,
ref state.Credentials,
ref state.Credentials,
ref NewLifeTime);
if (result != SuccessfulResult)
......@@ -70,9 +67,9 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
SecurityNativeDataRepresentation,
ref serverToken,
0,
out state.Context,
out state.Context,
out clientToken,
out NewContextAttributes,
out NewContextAttributes,
out NewLifeTime);
......@@ -101,17 +98,14 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
/// <param name="serverChallenge"></param>
/// <param name="requestId"></param>
/// <returns></returns>
internal static byte[] AcquireFinalSecurityToken(string hostname,
byte[] serverChallenge, Guid requestId)
internal static byte[] AcquireFinalSecurityToken(string hostname, byte[] serverChallenge, Guid requestId)
{
byte[] token = null;
byte[] token;
//user server challenge
SecurityBufferDesciption serverToken
= new SecurityBufferDesciption(serverChallenge);
var serverToken = new SecurityBufferDesciption(serverChallenge);
SecurityBufferDesciption clientToken
= new SecurityBufferDesciption(MaximumTokenSize);
var clientToken = new SecurityBufferDesciption(MaximumTokenSize);
try
{
......@@ -140,7 +134,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
// Client challenge issue operation failed.
return null;
}
authStates.Remove(requestId);
token = clientToken.GetBytes();
}
......@@ -152,7 +146,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
return token;
}
/// <summary>
/// Clear any hanging states
/// </summary>
......@@ -161,9 +155,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
{
var cutOff = DateTime.Now.AddMinutes(-1 * stateCacheTimeOutMinutes);
var outdated = authStates
.Where(x => x.Value.LastSeen < cutOff)
.ToList();
var outdated = authStates.Where(x => x.Value.LastSeen < cutOff).ToList();
foreach (var cache in outdated)
{
......@@ -177,46 +169,45 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
#region Native calls to secur32.dll
[DllImport("secur32.dll", SetLastError = true)]
static extern int InitializeSecurityContext(ref SecurityHandle phCredential,//PCredHandle
IntPtr phContext, //PCtxtHandle
string pszTargetName,
int fContextReq,
int Reserved1,
int TargetDataRep,
ref SecurityBufferDesciption pInput, //PSecBufferDesc SecBufferDesc
int Reserved2,
out SecurityHandle phNewContext, //PCtxtHandle
out SecurityBufferDesciption pOutput, //PSecBufferDesc SecBufferDesc
out uint pfContextAttr, //managed ulong == 64 bits!!!
out SecurityInteger ptsExpiry); //PTimeStamp
static extern int InitializeSecurityContext(ref SecurityHandle phCredential, //PCredHandle
IntPtr phContext, //PCtxtHandle
string pszTargetName,
int fContextReq,
int reserved1,
int targetDataRep,
ref SecurityBufferDesciption pInput, //PSecBufferDesc SecBufferDesc
int reserved2,
out SecurityHandle phNewContext, //PCtxtHandle
out SecurityBufferDesciption pOutput, //PSecBufferDesc SecBufferDesc
out uint pfContextAttr, //managed ulong == 64 bits!!!
out SecurityInteger ptsExpiry); //PTimeStamp
[DllImport("secur32", CharSet = CharSet.Auto, SetLastError = true)]
static extern int InitializeSecurityContext(ref SecurityHandle phCredential,//PCredHandle
ref SecurityHandle phContext, //PCtxtHandle
string pszTargetName,
int fContextReq,
int Reserved1,
int TargetDataRep,
ref SecurityBufferDesciption SecBufferDesc, //PSecBufferDesc SecBufferDesc
int Reserved2,
out SecurityHandle phNewContext, //PCtxtHandle
out SecurityBufferDesciption pOutput, //PSecBufferDesc SecBufferDesc
out uint pfContextAttr, //managed ulong == 64 bits!!!
out SecurityInteger ptsExpiry); //PTimeStamp
static extern int InitializeSecurityContext(ref SecurityHandle phCredential, //PCredHandle
ref SecurityHandle phContext, //PCtxtHandle
string pszTargetName,
int fContextReq,
int reserved1,
int targetDataRep,
ref SecurityBufferDesciption secBufferDesc, //PSecBufferDesc SecBufferDesc
int reserved2,
out SecurityHandle phNewContext, //PCtxtHandle
out SecurityBufferDesciption pOutput, //PSecBufferDesc SecBufferDesc
out uint pfContextAttr, //managed ulong == 64 bits!!!
out SecurityInteger ptsExpiry); //PTimeStamp
[DllImport("secur32.dll", CharSet = CharSet.Auto, SetLastError = false)]
private static extern int AcquireCredentialsHandle(
string pszPrincipal, //SEC_CHAR*
string pszPackage, //SEC_CHAR* //"Kerberos","NTLM","Negotiative"
string pszPrincipal, //SEC_CHAR*
string pszPackage, //SEC_CHAR* //"Kerberos","NTLM","Negotiative"
int fCredentialUse,
IntPtr PAuthenticationID, //_LUID AuthenticationID,//pvLogonID, //PLUID
IntPtr pAuthData, //PVOID
int pGetKeyFn, //SEC_GET_KEY_FN
IntPtr pvGetKeyArgument, //PVOID
ref Common.SecurityHandle phCredential, //SecHandle //PCtxtHandle ref
ref Common.SecurityInteger ptsExpiry); //PTimeStamp //TimeStamp ref
IntPtr pAuthenticationId, //_LUID AuthenticationID,//pvLogonID, //PLUID
IntPtr pAuthData, //PVOID
int pGetKeyFn, //SEC_GET_KEY_FN
IntPtr pvGetKeyArgument, //PVOID
ref SecurityHandle phCredential, //SecHandle //PCtxtHandle ref
ref SecurityInteger ptsExpiry); //PTimeStamp //TimeStamp ref
#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
{
......@@ -18,11 +18,10 @@ namespace Titanium.Web.Proxy.Network.WinAuth
/// <param name="authScheme"></param>
/// <param name="requestId"></param>
/// <returns></returns>
public static string GetInitialAuthToken(string serverHostname,
string authScheme, Guid requestId)
public static string GetInitialAuthToken(string serverHostname, string authScheme, Guid requestId)
{
var tokenBytes = WinAuthEndPoint.AcquireInitialSecurityToken(serverHostname, authScheme, requestId);
return string.Concat(" ", Convert.ToBase64String(tokenBytes));
var tokenBytes = WinAuthEndPoint.AcquireInitialSecurityToken(serverHostname, authScheme, requestId);
return string.Concat(" ", Convert.ToBase64String(tokenBytes));
}
......@@ -33,14 +32,11 @@ namespace Titanium.Web.Proxy.Network.WinAuth
/// <param name="serverToken"></param>
/// <param name="requestId"></param>
/// <returns></returns>
public static string GetFinalAuthToken(string serverHostname,
string serverToken, Guid requestId)
public static string GetFinalAuthToken(string serverHostname, string serverToken, Guid requestId)
{
var tokenBytes = WinAuthEndPoint.AcquireFinalSecurityToken(serverHostname,
Convert.FromBase64String(serverToken), requestId);
var tokenBytes = WinAuthEndPoint.AcquireFinalSecurityToken(serverHostname, Convert.FromBase64String(serverToken), requestId);
return string.Concat(" ", Convert.ToBase64String(tokenBytes));
}
}
}
......@@ -30,8 +30,9 @@ namespace Titanium.Web.Proxy
}
var header = httpHeaders.FirstOrDefault(t => t.Name == "Proxy-Authorization");
if (header == null) throw new NullReferenceException();
var headerValue = header.Value.Trim();
if (header == null)
throw new NullReferenceException();
string headerValue = header.Value.Trim();
if (!headerValue.StartsWith("basic", StringComparison.CurrentCultureIgnoreCase))
{
//Return not authorized
......@@ -41,7 +42,7 @@ namespace Titanium.Web.Proxy
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)
{
//Return not authorized
......@@ -49,8 +50,8 @@ namespace Titanium.Web.Proxy
return false;
}
var username = decoded.Substring(0, decoded.IndexOf(':'));
var password = decoded.Substring(decoded.IndexOf(':') + 1);
string username = decoded.Substring(0, decoded.IndexOf(':'));
string password = decoded.Substring(decoded.IndexOf(':') + 1);
return await AuthenticateUserFunc(username, password);
}
catch (Exception e)
......
......@@ -67,9 +67,7 @@ namespace Titanium.Web.Proxy
/// <summary>
/// Set firefox to use default system proxy
/// </summary>
private FireFoxProxySettingsManager firefoxProxySettingsManager
= new FireFoxProxySettingsManager();
private readonly FireFoxProxySettingsManager firefoxProxySettingsManager = new FireFoxProxySettingsManager();
/// <summary>
/// Buffer size used throughout this proxy
......@@ -255,15 +253,13 @@ namespace Titanium.Web.Proxy
/// <summary>
/// List of supported Ssl versions
/// </summary>
public SslProtocols SupportedSslProtocols { get; set; } = SslProtocols.Tls
| SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Ssl3;
public SslProtocols SupportedSslProtocols { get; set; } = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Ssl3;
/// <summary>
/// Total number of active client connections
/// </summary>
public int ClientConnectionCount => clientConnectionCount;
/// <summary>
/// Total number of active server connections
/// </summary>
......@@ -293,7 +289,7 @@ namespace Titanium.Web.Proxy
{
systemProxySettingsManager = new SystemProxyManager();
}
CertificateManager = new CertificateManager(ExceptionFunc);
if (rootCertificateName != null)
{
......@@ -312,8 +308,7 @@ namespace Titanium.Web.Proxy
/// <param name="endPoint"></param>
public void AddEndPoint(ProxyEndPoint endPoint)
{
if (ProxyEndPoints.Any(x => x.IpAddress.Equals(endPoint.IpAddress)
&& endPoint.Port != 0 && x.Port == endPoint.Port))
if (ProxyEndPoints.Any(x => x.IpAddress.Equals(endPoint.IpAddress) && endPoint.Port != 0 && x.Port == endPoint.Port))
{
throw new Exception("Cannot add another endpoint to same port & ip address");
}
......@@ -412,7 +407,9 @@ namespace Titanium.Web.Proxy
systemProxySettingsManager.SetProxy(
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,
protocolType);
......@@ -524,7 +521,7 @@ namespace Titanium.Web.Proxy
}
}
if (ForwardToUpstreamGateway
if (ForwardToUpstreamGateway
&& GetCustomUpStreamHttpProxyFunc == null && GetCustomUpStreamHttpsProxyFunc == null
&& systemProxySettingsManager != null)
{
......@@ -565,7 +562,7 @@ namespace Titanium.Web.Proxy
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)
{
......@@ -618,7 +615,8 @@ namespace Titanium.Web.Proxy
/// <param name="endPoint"></param>
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)
{
throw new Exception("Cannot set endPoints not added to proxy as system proxy");
......
......@@ -33,19 +33,22 @@ namespace Titanium.Web.Proxy
/// <returns></returns>
private async Task HandleClient(ExplicitProxyEndPoint endPoint, TcpClient tcpClient)
{
var disposed = false;
bool disposed = false;
var clientStream = new CustomBufferedStream(tcpClient.GetStream(), BufferSize);
var clientStreamReader = new CustomBinaryReader(clientStream, BufferSize);
var clientStreamWriter = new StreamWriter(clientStream) { NewLine = ProxyConstants.NewLine };
var clientStreamWriter = new StreamWriter(clientStream)
{
NewLine = ProxyConstants.NewLine
};
Uri httpRemoteUri;
try
{
//read the first line HTTP command
var httpCmd = await clientStreamReader.ReadLineAsync();
string httpCmd = await clientStreamReader.ReadLineAsync();
if (string.IsNullOrEmpty(httpCmd))
{
......@@ -56,7 +59,7 @@ namespace Titanium.Web.Proxy
var httpCmdSplit = httpCmd.Split(ProxyConstants.SpaceSplit, 3);
//Find the request Verb
var httpVerb = httpCmdSplit[0].ToUpper();
string httpVerb = httpCmdSplit[0].ToUpper();
httpRemoteUri = httpVerb == "CONNECT" ? new Uri("http://" + httpCmdSplit[1]) : new Uri(httpCmdSplit[1]);
......@@ -64,7 +67,7 @@ namespace Titanium.Web.Proxy
var version = HttpHeader.Version11;
if (httpCmdSplit.Length == 3)
{
var httpVersion = httpCmdSplit[2].Trim();
string httpVersion = httpCmdSplit[2].Trim();
if (string.Equals(httpVersion, "HTTP/1.0", StringComparison.OrdinalIgnoreCase))
{
......@@ -88,8 +91,7 @@ namespace Titanium.Web.Proxy
List<HttpHeader> connectRequestHeaders = null;
//Client wants to create a secure tcp tunnel (its a HTTPS request)
if (httpVerb == "CONNECT" && !excluded
&& endPoint.RemoteHttpsPorts.Contains(httpRemoteUri.Port))
if (httpVerb == "CONNECT" && !excluded && endPoint.RemoteHttpsPorts.Contains(httpRemoteUri.Port))
{
httpRemoteUri = new Uri("https://" + httpCmdSplit[1]);
connectRequestHeaders = new List<HttpHeader>();
......@@ -115,21 +117,22 @@ namespace Titanium.Web.Proxy
{
sslStream = new SslStream(clientStream);
var certName = HttpHelper.GetWildCardDomainName(httpRemoteUri.Host);
string certName = HttpHelper.GetWildCardDomainName(httpRemoteUri.Host);
var certificate = endPoint.GenericCertificate ??
CertificateManager.CreateCertificate(certName, false);
var certificate = endPoint.GenericCertificate ?? CertificateManager.CreateCertificate(certName, false);
//Successfully managed to authenticate the client using the fake certificate
await sslStream.AuthenticateAsServerAsync(certificate, false,
SupportedSslProtocols, false);
await sslStream.AuthenticateAsServerAsync(certificate, false, SupportedSslProtocols, false);
//HTTPS server created - we can now decrypt the client's traffic
clientStream = new CustomBufferedStream(sslStream, BufferSize);
clientStreamReader.Dispose();
clientStreamReader = new CustomBinaryReader(clientStream, BufferSize);
clientStreamWriter = new StreamWriter(clientStream) { NewLine = ProxyConstants.NewLine };
clientStreamWriter = new StreamWriter(clientStream)
{
NewLine = ProxyConstants.NewLine
};
}
catch
{
......@@ -160,8 +163,7 @@ namespace Titanium.Web.Proxy
//Now create the request
disposed = await HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter,
httpRemoteUri.Scheme == Uri.UriSchemeHttps ? httpRemoteUri.Host : null, endPoint,
connectRequestHeaders);
httpRemoteUri.Scheme == Uri.UriSchemeHttps ? httpRemoteUri.Host : null, endPoint, connectRequestHeaders);
}
catch (Exception e)
{
......@@ -202,17 +204,19 @@ namespace Titanium.Web.Proxy
var certificate = CertificateManager.CreateCertificate(endPoint.GenericCertificateName, false);
//Successfully managed to authenticate the client using the fake certificate
await sslStream.AuthenticateAsServerAsync(certificate, false,
SslProtocols.Tls, false);
await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls, false);
//HTTPS server created - we can now decrypt the client's traffic
}
clientStreamReader = new CustomBinaryReader(clientStream, BufferSize);
clientStreamWriter = new StreamWriter(clientStream) { NewLine = ProxyConstants.NewLine };
clientStreamWriter = new StreamWriter(clientStream)
{
NewLine = ProxyConstants.NewLine
};
//now read the request line
var httpCmd = await clientStreamReader.ReadLineAsync();
string httpCmd = await clientStreamReader.ReadLineAsync();
//Now create the request
disposed = await HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter,
......@@ -283,13 +287,13 @@ namespace Titanium.Web.Proxy
//break up the line into three components (method, remote URL & Http Version)
var httpCmdSplit = httpCmd.Split(ProxyConstants.SpaceSplit, 3);
var httpMethod = httpCmdSplit[0];
string httpMethod = httpCmdSplit[0];
//find the request HTTP version
var httpVersion = HttpHeader.Version11;
if (httpCmdSplit.Length == 3)
{
var httpVersionString = httpCmdSplit[2].Trim();
string httpVersionString = httpCmdSplit[2].Trim();
if (string.Equals(httpVersionString, "HTTP/1.0", StringComparison.OrdinalIgnoreCase))
{
......@@ -313,9 +317,7 @@ namespace Titanium.Web.Proxy
args.ProxyClient.ClientStreamWriter = clientStreamWriter;
//proxy authorization check
if (httpsConnectHostname == null &&
await CheckAuthorization(clientStreamWriter,
args.WebSession.Request.RequestHeaders.Values) == false)
if (httpsConnectHostname == null && await CheckAuthorization(clientStreamWriter, args.WebSession.Request.RequestHeaders.Values) == false)
{
args.Dispose();
break;
......@@ -327,9 +329,7 @@ namespace Titanium.Web.Proxy
//if win auth is enabled
//we need a cache of request body
//so that we can send it after authentication in WinAuthHandler.cs
if (EnableWinAuth
&& !RunTime.IsRunningOnMono
&& args.WebSession.Request.HasBody)
if (EnableWinAuth && !RunTime.IsRunningOnMono && args.WebSession.Request.HasBody)
{
await args.GetRequestBody();
}
......@@ -349,10 +349,8 @@ namespace Titanium.Web.Proxy
//if upgrading to websocket then relay the requet without reading the contents
if (args.WebSession.Request.UpgradeToWebSocket)
{
await TcpHelper.SendRaw(this,
httpRemoteUri.Host, httpRemoteUri.Port,
httpCmd, httpVersion, args.WebSession.Request.RequestHeaders, args.IsHttps,
clientStream, tcpConnectionFactory, connection);
await TcpHelper.SendRaw(this, httpRemoteUri.Host, httpRemoteUri.Port, httpCmd, httpVersion, args.WebSession.Request.RequestHeaders,
args.IsHttps, clientStream, tcpConnectionFactory, connection);
args.Dispose();
break;
......@@ -363,8 +361,7 @@ namespace Titanium.Web.Proxy
connection = await GetServerConnection(args);
}
//create a new connection if hostname changes
else if (!connection.HostName.Equals(args.WebSession.Request.RequestUri.Host,
StringComparison.OrdinalIgnoreCase))
else if (!connection.HostName.Equals(args.WebSession.Request.RequestUri.Host, StringComparison.OrdinalIgnoreCase))
{
connection.Dispose();
Interlocked.Decrement(ref serverConnectionCount);
......@@ -380,7 +377,7 @@ namespace Titanium.Web.Proxy
args.Dispose();
break;
}
//if connection is closing exit
if (args.WebSession.Response.ResponseKeepAlive == false)
{
......@@ -415,8 +412,7 @@ namespace Titanium.Web.Proxy
/// <param name="args"></param>
/// <param name="closeConnection"></param>
/// <returns></returns>
private async Task<bool> HandleHttpSessionRequestInternal(TcpConnection connection,
SessionEventArgs args, bool closeConnection)
private async Task<bool> HandleHttpSessionRequestInternal(TcpConnection connection, SessionEventArgs args, bool closeConnection)
{
bool disposed = false;
bool keepAlive = false;
......@@ -438,14 +434,12 @@ namespace Titanium.Web.Proxy
{
if (args.WebSession.Request.Is100Continue)
{
await WriteResponseStatus(args.WebSession.Response.HttpVersion, "100",
"Continue", args.ProxyClient.ClientStreamWriter);
await WriteResponseStatus(args.WebSession.Response.HttpVersion, "100", "Continue", args.ProxyClient.ClientStreamWriter);
await args.ProxyClient.ClientStreamWriter.WriteLineAsync();
}
else if (args.WebSession.Request.ExpectationFailed)
{
await WriteResponseStatus(args.WebSession.Response.HttpVersion, "417",
"Expectation Failed", args.ProxyClient.ClientStreamWriter);
await WriteResponseStatus(args.WebSession.Response.HttpVersion, "417", "Expectation Failed", args.ProxyClient.ClientStreamWriter);
await args.ProxyClient.ClientStreamWriter.WriteLineAsync();
}
}
......@@ -465,7 +459,8 @@ namespace Titanium.Web.Proxy
{
if (args.WebSession.Request.ContentEncoding != null)
{
args.WebSession.Request.RequestBody = await GetCompressedResponseBody(args.WebSession.Request.ContentEncoding, args.WebSession.Request.RequestBody);
args.WebSession.Request.RequestBody =
await GetCompressedResponseBody(args.WebSession.Request.ContentEncoding, args.WebSession.Request.RequestBody);
}
//chunked send is not supported as of now
args.WebSession.Request.ContentLength = args.WebSession.Request.RequestBody.Length;
......@@ -520,7 +515,8 @@ namespace Titanium.Web.Proxy
if (!disposed && !keepAlive)
{
//dispose
Dispose(args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamReader, args.ProxyClient.ClientStreamWriter, args.WebSession.ServerConnection);
Dispose(args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamReader, args.ProxyClient.ClientStreamWriter,
args.WebSession.ServerConnection);
}
}
......@@ -532,8 +528,7 @@ namespace Titanium.Web.Proxy
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
private async Task<TcpConnection> GetServerConnection(
SessionEventArgs args)
private async Task<TcpConnection> GetServerConnection(SessionEventArgs args)
{
ExternalProxy customUpStreamHttpProxy = null;
ExternalProxy customUpStreamHttpsProxy = null;
......@@ -574,8 +569,7 @@ namespace Titanium.Web.Proxy
/// <returns></returns>
private async Task WriteConnectResponse(StreamWriter clientStreamWriter, Version httpVersion)
{
await clientStreamWriter.WriteLineAsync(
$"HTTP/{httpVersion.Major}.{httpVersion.Minor} 200 Connection established");
await clientStreamWriter.WriteLineAsync($"HTTP/{httpVersion.Major}.{httpVersion.Minor} 200 Connection established");
await clientStreamWriter.WriteLineAsync($"Timestamp: {DateTime.Now}");
await clientStreamWriter.WriteLineAsync();
await clientStreamWriter.FlushAsync();
......
......@@ -32,13 +32,13 @@ namespace Titanium.Web.Proxy
await args.WebSession.ReceiveResponse();
//check for windows authentication
if(EnableWinAuth
if (EnableWinAuth
&& !RunTime.IsRunningOnMono
&& args.WebSession.Response.ResponseStatusCode == "401")
{
var disposed = await Handle401UnAuthorized(args);
if(disposed)
bool disposed = await Handle401UnAuthorized(args);
if (disposed)
{
return true;
}
......@@ -58,7 +58,7 @@ namespace Titanium.Web.Proxy
{
//clear current response
await args.ClearResponse();
var disposed = await HandleHttpSessionRequestInternal(args.WebSession.ServerConnection, args, false);
bool disposed = await HandleHttpSessionRequestInternal(args.WebSession.ServerConnection, args, false);
return disposed;
}
......@@ -67,14 +67,12 @@ namespace Titanium.Web.Proxy
//Write back to client 100-conitinue response if that's what server returned
if (args.WebSession.Response.Is100Continue)
{
await WriteResponseStatus(args.WebSession.Response.HttpVersion, "100",
"Continue", args.ProxyClient.ClientStreamWriter);
await WriteResponseStatus(args.WebSession.Response.HttpVersion, "100", "Continue", args.ProxyClient.ClientStreamWriter);
await args.ProxyClient.ClientStreamWriter.WriteLineAsync();
}
else if (args.WebSession.Response.ExpectationFailed)
{
await WriteResponseStatus(args.WebSession.Response.HttpVersion, "417",
"Expectation Failed", args.ProxyClient.ClientStreamWriter);
await WriteResponseStatus(args.WebSession.Response.HttpVersion, "417", "Expectation Failed", args.ProxyClient.ClientStreamWriter);
await args.ProxyClient.ClientStreamWriter.WriteLineAsync();
}
......@@ -84,8 +82,8 @@ namespace Titanium.Web.Proxy
if (args.WebSession.Response.ResponseBodyRead)
{
var isChunked = args.WebSession.Response.IsChunked;
var contentEncoding = args.WebSession.Response.ContentEncoding;
bool isChunked = args.WebSession.Response.IsChunked;
string contentEncoding = args.WebSession.Response.ContentEncoding;
if (contentEncoding != null)
{
......@@ -110,20 +108,17 @@ namespace Titanium.Web.Proxy
//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
if (args.WebSession.Response.IsChunked || args.WebSession.Response.ContentLength > 0
|| !args.WebSession.Response.ResponseKeepAlive)
if (args.WebSession.Response.IsChunked || args.WebSession.Response.ContentLength > 0 || !args.WebSession.Response.ResponseKeepAlive)
{
await args.WebSession.ServerConnection.StreamReader
.WriteResponseBody(BufferSize, args.ProxyClient.ClientStream, args.WebSession.Response.IsChunked,
args.WebSession.Response.ContentLength);
await args.WebSession.ServerConnection.StreamReader.WriteResponseBody(BufferSize, args.ProxyClient.ClientStream,
args.WebSession.Response.IsChunked, args.WebSession.Response.ContentLength);
}
//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)
else if (args.WebSession.Response.ResponseKeepAlive && args.WebSession.Response.HttpVersion.Minor == 0)
{
await args.WebSession.ServerConnection.StreamReader
.WriteResponseBody(BufferSize, args.ProxyClient.ClientStream, args.WebSession.Response.IsChunked,
args.WebSession.Response.ContentLength);
await args.WebSession.ServerConnection.StreamReader.WriteResponseBody(BufferSize, args.ProxyClient.ClientStream,
args.WebSession.Response.IsChunked, args.WebSession.Response.ContentLength);
}
}
......@@ -132,8 +127,8 @@ namespace Titanium.Web.Proxy
catch (Exception e)
{
ExceptionFunc(new ProxyHttpException("Error occured whilst handling session response", e, args));
Dispose(args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamReader,
args.ProxyClient.ClientStreamWriter, args.WebSession.ServerConnection);
Dispose(args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamReader, args.ProxyClient.ClientStreamWriter,
args.WebSession.ServerConnection);
return true;
}
......@@ -162,8 +157,7 @@ namespace Titanium.Web.Proxy
/// <param name="description"></param>
/// <param name="responseWriter"></param>
/// <returns></returns>
private async Task WriteResponseStatus(Version version, string code, string description,
StreamWriter responseWriter)
private async Task WriteResponseStatus(Version version, string code, string description, StreamWriter responseWriter)
{
await responseWriter.WriteLineAsync($"HTTP/{version.Major}.{version.Minor} {code} {description}");
}
......@@ -204,8 +198,8 @@ namespace Titanium.Web.Proxy
private void FixProxyHeaders(Dictionary<string, HttpHeader> headers)
{
//If proxy-connection close was returned inform to close the connection
var hasProxyHeader = headers.ContainsKey("proxy-connection");
var hasConnectionheader = headers.ContainsKey("connection");
bool hasProxyHeader = headers.ContainsKey("proxy-connection");
bool hasConnectionheader = headers.ContainsKey("connection");
if (hasProxyHeader)
{
......@@ -231,10 +225,7 @@ namespace Titanium.Web.Proxy
/// <param name="clientStreamReader"></param>
/// <param name="clientStreamWriter"></param>
/// <param name="serverConnection"></param>
private void Dispose(Stream clientStream,
CustomBinaryReader clientStreamReader,
StreamWriter clientStreamWriter,
TcpConnection serverConnection)
private void Dispose(Stream clientStream, CustomBinaryReader clientStreamReader, StreamWriter clientStreamWriter, TcpConnection serverConnection)
{
clientStream?.Close();
clientStream?.Dispose();
......
......@@ -16,8 +16,7 @@ namespace Titanium.Web.Proxy.Shared
internal static readonly byte[] NewLineBytes = Encoding.ASCII.GetBytes(NewLine);
internal static readonly byte[] ChunkEnd =
Encoding.ASCII.GetBytes(0.ToString("x2") + NewLine + NewLine);
internal static readonly byte[] ChunkEnd = Encoding.ASCII.GetBytes(0.ToString("x2") + NewLine + NewLine);
internal const string NewLine = "\r\n";
}
......
......@@ -5,30 +5,28 @@ using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network.WinAuth;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers;
namespace Titanium.Web.Proxy
{
public partial class ProxyServer
{
//possible header names
private static List<string> authHeaderNames
= new List<string>() {
"WWW-Authenticate",
//IIS 6.0 messed up names below
"WWWAuthenticate",
"NTLMAuthorization",
"NegotiateAuthorization",
"KerberosAuthorization"
};
private static List<string> authSchemes
= new List<string>() {
"NTLM",
"Negotiate",
"Kerberos"
};
private static readonly List<string> authHeaderNames = new List<string>
{
"WWW-Authenticate",
//IIS 6.0 messed up names below
"WWWAuthenticate",
"NTLMAuthorization",
"NegotiateAuthorization",
"KerberosAuthorization"
};
private static readonly List<string> authSchemes = new List<string>
{
"NTLM",
"Negotiate",
"Kerberos"
};
/// <summary>
/// Handle windows NTLM authentication
......@@ -45,32 +43,27 @@ namespace Titanium.Web.Proxy
HttpHeader authHeader = null;
//check in non-unique headers first
var header = args.WebSession.Response
.NonUniqueResponseHeaders
.FirstOrDefault(x =>
authHeaderNames.Any(y => x.Key.Equals(y, StringComparison.OrdinalIgnoreCase)));
var header =
args.WebSession.Response.NonUniqueResponseHeaders.FirstOrDefault(
x => authHeaderNames.Any(y => x.Key.Equals(y, StringComparison.OrdinalIgnoreCase)));
if (!header.Equals(new KeyValuePair<string, List<HttpHeader>>()))
{
headerName = header.Key;
}
if (headerName != null)
{
authHeader = args.WebSession.Response
.NonUniqueResponseHeaders[headerName]
.Where(x => authSchemes.Any(y => x.Value.StartsWith(y, StringComparison.OrdinalIgnoreCase)))
.FirstOrDefault();
authHeader = args.WebSession.Response.NonUniqueResponseHeaders[headerName]
.FirstOrDefault(x => authSchemes.Any(y => x.Value.StartsWith(y, StringComparison.OrdinalIgnoreCase)));
}
//check in unique headers
if (authHeader == null)
{
//check in non-unique headers first
var uHeader = args.WebSession.Response
.ResponseHeaders
.FirstOrDefault(x =>
authHeaderNames.Any(y => x.Key.Equals(y, StringComparison.OrdinalIgnoreCase)));
var uHeader =
args.WebSession.Response.ResponseHeaders.FirstOrDefault(x => authHeaderNames.Any(y => x.Key.Equals(y, StringComparison.OrdinalIgnoreCase)));
if (!uHeader.Equals(new KeyValuePair<string, HttpHeader>()))
{
......@@ -79,15 +72,16 @@ namespace Titanium.Web.Proxy
if (headerName != null)
{
authHeader = authSchemes.Any(x => args.WebSession.Response
.ResponseHeaders[headerName].Value.StartsWith(x, StringComparison.OrdinalIgnoreCase)) ?
args.WebSession.Response.ResponseHeaders[headerName] : null;
authHeader = authSchemes.Any(x => args.WebSession.Response.ResponseHeaders[headerName].Value
.StartsWith(x, StringComparison.OrdinalIgnoreCase))
? args.WebSession.Response.ResponseHeaders[headerName]
: 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
if (args.WebSession.Request.NonUniqueRequestHeaders.ContainsKey("Authorization"))
......@@ -98,10 +92,10 @@ namespace Titanium.Web.Proxy
//initial value will match exactly any of the schemes
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));
//replace existing authorization header if any
if (args.WebSession.Request.RequestHeaders.ContainsKey("Authorization"))
{
......@@ -113,32 +107,28 @@ namespace Titanium.Web.Proxy
}
//don't need to send body for Authorization request
if(args.WebSession.Request.HasBody)
if (args.WebSession.Request.HasBody)
{
args.WebSession.Request.ContentLength = 0;
}
}
//challenge value will start with any of the scheme selected
else
{
scheme = authSchemes.FirstOrDefault(x => authHeader.Value.StartsWith(x, StringComparison.OrdinalIgnoreCase)
&& authHeader.Value.Length > x.Length + 1);
scheme = authSchemes.FirstOrDefault(x => authHeader.Value.StartsWith(x, StringComparison.OrdinalIgnoreCase) &&
authHeader.Value.Length > x.Length + 1);
var serverToken = authHeader.Value.Substring(scheme.Length + 1);
var clientToken = WinAuthHandler.GetFinalAuthToken(args.WebSession.Request.Host, serverToken, args.Id);
string serverToken = authHeader.Value.Substring(scheme.Length + 1);
string clientToken = WinAuthHandler.GetFinalAuthToken(args.WebSession.Request.Host, serverToken, args.Id);
//there will be an existing header from initial client request
args.WebSession.Request.RequestHeaders["Authorization"]
= new HttpHeader("Authorization", string.Concat(scheme, clientToken));
args.WebSession.Request.RequestHeaders["Authorization"] = new HttpHeader("Authorization", string.Concat(scheme, clientToken));
//send body for final auth request
if (args.WebSession.Request.HasBody)
{
args.WebSession.Request.ContentLength
= args.WebSession.Request.RequestBody.Length;
args.WebSession.Request.ContentLength = args.WebSession.Request.RequestBody.Length;
}
}
//Need to revisit this.
......@@ -150,13 +140,11 @@ namespace Titanium.Web.Proxy
//request again with updated authorization header
//and server cookies
var disposed = await HandleHttpSessionRequestInternal(args.WebSession.ServerConnection, args, false);
bool disposed = await HandleHttpSessionRequestInternal(args.WebSession.ServerConnection, args, false);
return disposed;
}
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