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

Commit bbbb0c5

Browse files
Merge pull request #244 from justcoding121/beta
Stable
2 parents 5a68386 + a3562f0 commit bbbb0c5

35 files changed

+938
-707
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
4+
namespace Titanium.Web.Proxy.Examples.Basic.Helpers
5+
{
6+
/// <summary>
7+
/// Adapated from
8+
/// http://stackoverflow.com/questions/13656846/how-to-programmatic-disable-c-sharp-console-applications-quick-edit-mode
9+
/// </summary>
10+
internal static class ConsoleHelper
11+
{
12+
const uint ENABLE_QUICK_EDIT = 0x0040;
13+
14+
// STD_INPUT_HANDLE (DWORD): -10 is the standard input device.
15+
const int STD_INPUT_HANDLE = -10;
16+
17+
[DllImport("kernel32.dll", SetLastError = true)]
18+
static extern IntPtr GetStdHandle(int nStdHandle);
19+
20+
[DllImport("kernel32.dll")]
21+
static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
22+
23+
[DllImport("kernel32.dll")]
24+
static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
25+
26+
internal static bool DisableQuickEditMode()
27+
{
28+
29+
IntPtr consoleHandle = GetStdHandle(STD_INPUT_HANDLE);
30+
31+
// get current console mode
32+
uint consoleMode;
33+
if (!GetConsoleMode(consoleHandle, out consoleMode))
34+
{
35+
// ERROR: Unable to get console mode.
36+
return false;
37+
}
38+
39+
// Clear the quick edit bit in the mode flags
40+
consoleMode &= ~ENABLE_QUICK_EDIT;
41+
42+
// set the new mode
43+
if (!SetConsoleMode(consoleHandle, consoleMode))
44+
{
45+
// ERROR: Unable to set console mode
46+
return false;
47+
}
48+
49+
return true;
50+
}
51+
}
52+
}

Examples/Titanium.Web.Proxy.Examples.Basic/Program.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
2+
using System.Diagnostics;
23
using System.Runtime.InteropServices;
4+
using Titanium.Web.Proxy.Examples.Basic.Helpers;
35

46
namespace Titanium.Web.Proxy.Examples.Basic
57
{
@@ -9,11 +11,13 @@ public class Program
911

1012
public static void Main(string[] args)
1113
{
14+
//fix console hang due to QuickEdit mode
15+
ConsoleHelper.DisableQuickEditMode();
16+
1217
//On Console exit make sure we also exit the proxy
1318
NativeMethods.Handler = ConsoleEventCallback;
1419
NativeMethods.SetConsoleCtrlHandler(NativeMethods.Handler, true);
1520

16-
1721
//Start proxy controller
1822
controller.StartProxy();
1923

@@ -50,5 +54,7 @@ internal static class NativeMethods
5054

5155
// Pinvoke
5256
internal delegate bool ConsoleEventDelegate(int eventType);
57+
5358
}
54-
}
59+
60+
}

Examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.IO;
43
using System.Net;
4+
using System.Net.Security;
55
using System.Threading.Tasks;
66
using Titanium.Web.Proxy.EventArguments;
77
using Titanium.Web.Proxy.Models;
@@ -47,18 +47,18 @@ public void StartProxy()
4747
//Exclude Https addresses you don't want to proxy
4848
//Useful for clients that use certificate pinning
4949
//for example google.com and dropbox.com
50-
ExcludedHttpsHostNameRegex = new List<string>() { "dropbox.com" }
50+
ExcludedHttpsHostNameRegex = new List<string> { "dropbox.com" }
5151

5252
//Include Https addresses you want to proxy (others will be excluded)
5353
//for example github.com
54-
// IncludedHttpsHostNameRegex = new List<string>() { "github.com" }
54+
//IncludedHttpsHostNameRegex = new List<string> { "github.com" }
5555

5656
//You can set only one of the ExcludedHttpsHostNameRegex and IncludedHttpsHostNameRegex properties, otherwise ArgumentException will be thrown
5757

5858
//Use self-issued generic certificate on all https requests
5959
//Optimizes performance by not creating a certificate for each https-enabled domain
6060
//Useful when certificate trust is not required by proxy clients
61-
// GenericCertificate = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "genericcert.pfx"), "password")
61+
//GenericCertificate = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "genericcert.pfx"), "password")
6262
};
6363

6464
//An explicit endpoint is where the client knows about the existence of a proxy
@@ -107,7 +107,7 @@ public void Stop()
107107
//intecept & cancel redirect or update requests
108108
public async Task OnRequest(object sender, SessionEventArgs e)
109109
{
110-
Console.WriteLine("Active Client Connections:" + ((ProxyServer) sender).ClientConnectionCount);
110+
Console.WriteLine("Active Client Connections:" + ((ProxyServer)sender).ClientConnectionCount);
111111
Console.WriteLine(e.WebSession.Request.Url);
112112

113113
//read request headers
@@ -150,7 +150,7 @@ public async Task OnRequest(object sender, SessionEventArgs e)
150150
//Modify response
151151
public async Task OnResponse(object sender, SessionEventArgs e)
152152
{
153-
Console.WriteLine("Active Server Connections:" + (sender as ProxyServer).ServerConnectionCount);
153+
Console.WriteLine("Active Server Connections:" + ((ProxyServer)sender).ServerConnectionCount);
154154

155155
if (requestBodyHistory.ContainsKey(e.Id))
156156
{
@@ -189,7 +189,7 @@ public async Task OnResponse(object sender, SessionEventArgs e)
189189
public Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)
190190
{
191191
//set IsValid to true/false based on Certificate Errors
192-
if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
192+
if (e.SslPolicyErrors == SslPolicyErrors.None)
193193
{
194194
e.IsValid = true;
195195
}

Examples/Titanium.Web.Proxy.Examples.Basic/Titanium.Web.Proxy.Examples.Basic.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
<Reference Include="System.Xml" />
5656
</ItemGroup>
5757
<ItemGroup>
58+
<Compile Include="Helpers\ConsoleHelper.cs" />
5859
<Compile Include="Program.cs" />
5960
<Compile Include="Properties\AssemblyInfo.cs" />
6061
<Compile Include="ProxyTestController.cs" />

README.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ Features
1717
* Safely relays Web Socket requests over HTTP
1818
* Support mutual SSL authentication
1919
* Fully asynchronous proxy
20-
* Supports proxy authentication
21-
20+
* Supports proxy authentication & automatic proxy detection
2221

2322
Usage
2423
=====
@@ -204,10 +203,8 @@ public Task OnCertificateSelection(object sender, CertificateSelectionEventArgs
204203
```
205204
Future road map (Pull requests are welcome!)
206205
============
206+
* Implement Kerberos/NTLM authentication over HTTP protocols for windows domain
207207
* Support Server Name Indication (SNI) for transparent endpoints
208208
* Support HTTP 2.0
209-
* Support upstream AutoProxy detection
210209
* Support SOCKS protocol
211-
* Implement Kerberos/NTLM authentication over HTTP protocols for windows domain
212-
213210

Tests/Titanium.Web.Proxy.IntegrationTests/Properties/AssemblyInfo.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.Reflection;
2-
using System.Runtime.CompilerServices;
32
using System.Runtime.InteropServices;
43

54
// General Information about an assembly is controlled through the following

Tests/Titanium.Web.Proxy.IntegrationTests/SslTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
using System;
2-
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using System.Diagnostics;
33
using System.Net;
4+
using System.Net.Http;
5+
using System.Net.Security;
46
using System.Threading.Tasks;
7+
using Microsoft.VisualStudio.TestTools.UnitTesting;
58
using Titanium.Web.Proxy.EventArguments;
69
using Titanium.Web.Proxy.Models;
7-
using System.Net.Http;
8-
using System.Diagnostics;
910

1011
namespace Titanium.Web.Proxy.IntegrationTests
1112
{
1213
[TestClass]
1314
public class SslTests
1415
{
1516
[TestMethod]
16-
1717
public void TestSsl()
1818
{
1919
//expand this to stress test to find
@@ -103,7 +103,7 @@ public async Task OnResponse(object sender, SessionEventArgs e)
103103
public Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)
104104
{
105105
//set IsValid to true/false based on Certificate Errors
106-
if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
106+
if (e.SslPolicyErrors == SslPolicyErrors.None)
107107
{
108108
e.IsValid = true;
109109
}

Tests/Titanium.Web.Proxy.UnitTests/CertificateManagerTests.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
using System;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
24
using Microsoft.VisualStudio.TestTools.UnitTesting;
35
using Titanium.Web.Proxy.Network;
4-
using System.Threading.Tasks;
5-
using System.Collections.Generic;
66

77
namespace Titanium.Web.Proxy.UnitTests
88
{
99
[TestClass]
1010
public class CertificateManagerTests
1111
{
1212
private static readonly string[] hostNames
13-
= new string[] { "facebook.com", "youtube.com", "google.com",
14-
"bing.com", "yahoo.com"};
13+
= { "facebook.com", "youtube.com", "google.com", "bing.com", "yahoo.com" };
1514

1615
private readonly Random random = new Random();
1716

@@ -36,16 +35,13 @@ public async Task Simple_Create_Certificate_Stress_Test()
3635
var certificate = mgr.CreateCertificate(host, false);
3736

3837
Assert.IsNotNull(certificate);
39-
4038
}));
41-
4239
}
4340
}
4441

4542
await Task.WhenAll(tasks.ToArray());
4643

4744
mgr.StopClearIdleCertificates();
48-
4945
}
5046
}
5147
}

Titanium.Web.Proxy.sln.DotSettings

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
11
<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">
22
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean>
3+
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
4+
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
5+
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">240</s:Int64>
36
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BC/@EntryIndexedValue">BC</s:String>
7+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CN/@EntryIndexedValue">CN</s:String>
8+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DN/@EntryIndexedValue">DN</s:String>
9+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=EKU/@EntryIndexedValue">EKU</s:String>
10+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KU/@EntryIndexedValue">KU</s:String>
11+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MTA/@EntryIndexedValue">MTA</s:String>
12+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OID/@EntryIndexedValue">OID</s:String>
13+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OIDS/@EntryIndexedValue">OIDS</s:String>
414
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
515
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
616
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
717
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
8-
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=dda2ffa1_002D435c_002D4111_002D88eb_002D1a7c93c382f0/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static, Instance" AccessRightKinds="Private" Description="Property (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="PROPERTY" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String></wpf:ResourceDictionary>
18+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=dda2ffa1_002D435c_002D4111_002D88eb_002D1a7c93c382f0/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static, Instance" AccessRightKinds="Private" Description="Property (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="PROPERTY" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
19+
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
20+
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
21+
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

Titanium.Web.Proxy/CertificateHandler.cs

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
using System;
22
using System.Net.Security;
33
using System.Security.Cryptography.X509Certificates;
4-
using System.Threading.Tasks;
54
using Titanium.Web.Proxy.EventArguments;
5+
using Titanium.Web.Proxy.Extensions;
66

77
namespace Titanium.Web.Proxy
88
{
@@ -32,17 +32,8 @@ internal bool ValidateServerCertificate(
3232
SslPolicyErrors = sslPolicyErrors
3333
};
3434

35-
36-
Delegate[] invocationList = ServerCertificateValidationCallback.GetInvocationList();
37-
Task[] handlerTasks = new Task[invocationList.Length];
38-
39-
for (int i = 0; i < invocationList.Length; i++)
40-
{
41-
handlerTasks[i] = ((Func<object, CertificateValidationEventArgs, Task>) invocationList[i])(null, args);
42-
}
43-
44-
Task.WhenAll(handlerTasks).Wait();
45-
35+
//why is the sender null?
36+
ServerCertificateValidationCallback.InvokeParallel(this, args);
4637
return args.IsValid;
4738
}
4839

@@ -108,17 +99,8 @@ internal X509Certificate SelectClientCertificate(
10899
ClientCertificate = clientCertificate
109100
};
110101

111-
112-
Delegate[] invocationList = ClientCertificateSelectionCallback.GetInvocationList();
113-
Task[] handlerTasks = new Task[invocationList.Length];
114-
115-
for (int i = 0; i < invocationList.Length; i++)
116-
{
117-
handlerTasks[i] = ((Func<object, CertificateSelectionEventArgs, Task>) invocationList[i])(null, args);
118-
}
119-
120-
Task.WhenAll(handlerTasks).Wait();
121-
102+
//why is the sender null?
103+
ClientCertificateSelectionCallback.InvokeParallel(this, args);
122104
return args.ClientCertificate;
123105
}
124106

0 commit comments

Comments
 (0)