Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
T
Titanium-Web-Proxy
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Titanium-Web-Proxy
Commits
c706c9fa
Commit
c706c9fa
authored
Jun 17, 2017
by
Honfika
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Line length set to 160
parent
e2c392f9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
188 additions
and
242 deletions
+188
-242
ConsoleHelper.cs
...itanium.Web.Proxy.Examples.Basic/Helpers/ConsoleHelper.cs
+0
-1
ProxyTestController.cs
.../Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
+5
-3
Titanium.Web.Proxy.sln.DotSettings
Titanium.Web.Proxy.sln.DotSettings
+3
-1
CertificateHandler.cs
Titanium.Web.Proxy/CertificateHandler.cs
+5
-17
SessionEventArgs.cs
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
+12
-16
BodyNotFoundException.cs
Titanium.Web.Proxy/Exceptions/BodyNotFoundException.cs
+1
-2
StreamExtensions.cs
Titanium.Web.Proxy/Extensions/StreamExtensions.cs
+2
-1
Firefox.cs
Titanium.Web.Proxy/Helpers/Firefox.cs
+3
-4
ProxyInfo.cs
Titanium.Web.Proxy/Helpers/ProxyInfo.cs
+2
-1
RunTime.cs
Titanium.Web.Proxy/Helpers/RunTime.cs
+1
-2
SystemProxy.cs
Titanium.Web.Proxy/Helpers/SystemProxy.cs
+2
-7
Tcp.cs
Titanium.Web.Proxy/Helpers/Tcp.cs
+3
-9
NativeMethods.WinHttp.cs
Titanium.Web.Proxy/Helpers/WinHttp/NativeMethods.WinHttp.cs
+2
-1
HeaderParser.cs
Titanium.Web.Proxy/Http/HeaderParser.cs
+6
-3
HttpWebClient.cs
Titanium.Web.Proxy/Http/HttpWebClient.cs
+2
-1
Request.cs
Titanium.Web.Proxy/Http/Request.cs
+13
-8
Response.cs
Titanium.Web.Proxy/Http/Response.cs
+13
-8
EndPoint.cs
Titanium.Web.Proxy/Models/EndPoint.cs
+7
-5
BCCertificateMaker.cs
Titanium.Web.Proxy/Network/Certificate/BCCertificateMaker.cs
+10
-12
CertificateManager.cs
Titanium.Web.Proxy/Network/CertificateManager.cs
+10
-9
TcpConnectionFactory.cs
Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
+12
-15
LittleEndian.cs
Titanium.Web.Proxy/Network/WinAuth/Security/LittleEndian.cs
+2
-10
WinAuthEndPoint.cs
...ium.Web.Proxy/Network/WinAuth/Security/WinAuthEndPoint.cs
+8
-17
WinAuthHandler.cs
Titanium.Web.Proxy/Network/WinAuth/WinAuthHandler.cs
+3
-6
ProxyAuthorizationHandler.cs
Titanium.Web.Proxy/ProxyAuthorizationHandler.cs
+2
-1
ProxyServer.cs
Titanium.Web.Proxy/ProxyServer.cs
+4
-5
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+31
-37
ResponseHandler.cs
Titanium.Web.Proxy/ResponseHandler.cs
+11
-20
ProxyConstants.cs
Titanium.Web.Proxy/Shared/ProxyConstants.cs
+1
-2
WinAuthHandler.cs
Titanium.Web.Proxy/WinAuthHandler.cs
+12
-18
No files found.
Examples/Titanium.Web.Proxy.Examples.Basic/Helpers/ConsoleHelper.cs
View file @
c706c9fa
...
@@ -25,7 +25,6 @@ namespace Titanium.Web.Proxy.Examples.Basic.Helpers
...
@@ -25,7 +25,6 @@ namespace Titanium.Web.Proxy.Examples.Basic.Helpers
internal
static
bool
DisableQuickEditMode
()
internal
static
bool
DisableQuickEditMode
()
{
{
IntPtr
consoleHandle
=
GetStdHandle
(
STD_INPUT_HANDLE
);
IntPtr
consoleHandle
=
GetStdHandle
(
STD_INPUT_HANDLE
);
// get current console mode
// get current console mode
...
...
Examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
View file @
c706c9fa
...
@@ -54,7 +54,10 @@ namespace Titanium.Web.Proxy.Examples.Basic
...
@@ -54,7 +54,10 @@ namespace Titanium.Web.Proxy.Examples.Basic
//Exclude Https addresses you don't want to proxy
//Exclude Https addresses you don't want to proxy
//Useful for clients that use certificate pinning
//Useful for clients that use certificate pinning
//for example google.com and dropbox.com
//for example google.com and dropbox.com
ExcludedHttpsHostNameRegex
=
new
List
<
string
>
{
"dropbox.com"
}
ExcludedHttpsHostNameRegex
=
new
List
<
string
>
{
"dropbox.com"
}
//Include Https addresses you want to proxy (others will be excluded)
//Include Https addresses you want to proxy (others will be excluded)
//for example github.com
//for example github.com
...
@@ -90,8 +93,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
...
@@ -90,8 +93,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
//proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
//proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
foreach
(
var
endPoint
in
proxyServer
.
ProxyEndPoints
)
foreach
(
var
endPoint
in
proxyServer
.
ProxyEndPoints
)
Console
.
WriteLine
(
"Listening on '{0}' endpoint at Ip {1} and port: {2} "
,
Console
.
WriteLine
(
"Listening on '{0}' endpoint at Ip {1} and port: {2} "
,
endPoint
.
GetType
().
Name
,
endPoint
.
IpAddress
,
endPoint
.
Port
);
endPoint
.
GetType
().
Name
,
endPoint
.
IpAddress
,
endPoint
.
Port
);
//Only explicit proxies can be set as system proxy!
//Only explicit proxies can be set as system proxy!
//proxyServer.SetAsSystemHttpProxy(explicitEndPoint);
//proxyServer.SetAsSystemHttpProxy(explicitEndPoint);
...
...
Titanium.Web.Proxy.sln.DotSettings
View file @
c706c9fa
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_CASE_STATEMENT_STYLE/@EntryValue">LINE_BREAK</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_EMBEDDED_STATEMENT_STYLE/@EntryValue">LINE_BREAK</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">
24
0</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">
16
0</s:Int64>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BC/@EntryIndexedValue">BC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BC/@EntryIndexedValue">BC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CN/@EntryIndexedValue">CN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CN/@EntryIndexedValue">CN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DN/@EntryIndexedValue">DN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DN/@EntryIndexedValue">DN</s:String>
...
...
Titanium.Web.Proxy/CertificateHandler.cs
View file @
c706c9fa
...
@@ -16,11 +16,7 @@ namespace Titanium.Web.Proxy
...
@@ -16,11 +16,7 @@ namespace Titanium.Web.Proxy
/// <param name="chain"></param>
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns></returns>
/// <returns></returns>
internal
bool
ValidateServerCertificate
(
internal
bool
ValidateServerCertificate
(
object
sender
,
X509Certificate
certificate
,
X509Chain
chain
,
SslPolicyErrors
sslPolicyErrors
)
object
sender
,
X509Certificate
certificate
,
X509Chain
chain
,
SslPolicyErrors
sslPolicyErrors
)
{
{
//if user callback is registered then do it
//if user callback is registered then do it
if
(
ServerCertificateValidationCallback
!=
null
)
if
(
ServerCertificateValidationCallback
!=
null
)
...
@@ -56,19 +52,12 @@ namespace Titanium.Web.Proxy
...
@@ -56,19 +52,12 @@ namespace Titanium.Web.Proxy
/// <param name="remoteCertificate"></param>
/// <param name="remoteCertificate"></param>
/// <param name="acceptableIssuers"></param>
/// <param name="acceptableIssuers"></param>
/// <returns></returns>
/// <returns></returns>
internal
X509Certificate
SelectClientCertificate
(
internal
X509Certificate
SelectClientCertificate
(
object
sender
,
string
targetHost
,
X509CertificateCollection
localCertificates
,
object
sender
,
X509Certificate
remoteCertificate
,
string
[]
acceptableIssuers
)
string
targetHost
,
X509CertificateCollection
localCertificates
,
X509Certificate
remoteCertificate
,
string
[]
acceptableIssuers
)
{
{
X509Certificate
clientCertificate
=
null
;
X509Certificate
clientCertificate
=
null
;
if
(
acceptableIssuers
!=
null
&&
if
(
acceptableIssuers
!=
null
&&
acceptableIssuers
.
Length
>
0
&&
localCertificates
!=
null
&&
localCertificates
.
Count
>
0
)
acceptableIssuers
.
Length
>
0
&&
localCertificates
!=
null
&&
localCertificates
.
Count
>
0
)
{
{
// Use the first certificate that is from an acceptable issuer.
// Use the first certificate that is from an acceptable issuer.
foreach
(
X509Certificate
certificate
in
localCertificates
)
foreach
(
X509Certificate
certificate
in
localCertificates
)
...
@@ -81,8 +70,7 @@ namespace Titanium.Web.Proxy
...
@@ -81,8 +70,7 @@ namespace Titanium.Web.Proxy
}
}
}
}
if
(
localCertificates
!=
null
&&
if
(
localCertificates
!=
null
&&
localCertificates
.
Count
>
0
)
localCertificates
.
Count
>
0
)
{
{
clientCertificate
=
localCertificates
[
0
];
clientCertificate
=
localCertificates
[
0
];
}
}
...
...
Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
View file @
c706c9fa
...
@@ -58,8 +58,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -58,8 +58,7 @@ namespace Titanium.Web.Proxy.EventArguments
{
{
if
(
WebSession
.
Response
.
ResponseStatusCode
==
null
)
if
(
WebSession
.
Response
.
ResponseStatusCode
==
null
)
{
{
throw
new
Exception
(
"Response status code is null. Cannot request again a request "
throw
new
Exception
(
"Response status code is null. Cannot request again a request "
+
"which was never send to server."
);
+
"which was never send to server."
);
}
}
reRequest
=
value
;
reRequest
=
value
;
...
@@ -112,8 +111,7 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -112,8 +111,7 @@ namespace Titanium.Web.Proxy.EventArguments
//GET request don't have a request body to read
//GET request don't have a request body to read
if
(!
WebSession
.
Request
.
HasBody
)
if
(!
WebSession
.
Request
.
HasBody
)
{
{
throw
new
BodyNotFoundException
(
"Request don't have a body. "
+
throw
new
BodyNotFoundException
(
"Request don't have a body. "
+
"Please verify that this request is a Http POST/PUT/PATCH and request "
+
"Please verify that this request is a Http POST/PUT/PATCH and request "
+
"content length is greater than zero before accessing the body."
);
"content length is greater than zero before accessing the body."
);
}
}
...
@@ -134,16 +132,14 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -134,16 +132,14 @@ namespace Titanium.Web.Proxy.EventArguments
if
(
WebSession
.
Request
.
ContentLength
>
0
)
if
(
WebSession
.
Request
.
ContentLength
>
0
)
{
{
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response
await
ProxyClient
.
ClientStreamReader
.
CopyBytesToStream
(
requestBodyStream
,
await
ProxyClient
.
ClientStreamReader
.
CopyBytesToStream
(
requestBodyStream
,
WebSession
.
Request
.
ContentLength
);
WebSession
.
Request
.
ContentLength
);
}
}
else
if
(
WebSession
.
Request
.
HttpVersion
.
Major
==
1
&&
WebSession
.
Request
.
HttpVersion
.
Minor
==
0
)
else
if
(
WebSession
.
Request
.
HttpVersion
.
Major
==
1
&&
WebSession
.
Request
.
HttpVersion
.
Minor
==
0
)
{
{
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStream
(
requestBodyStream
,
long
.
MaxValue
);
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStream
(
requestBodyStream
,
long
.
MaxValue
);
}
}
}
}
WebSession
.
Request
.
RequestBody
=
await
GetDecompressedResponseBody
(
WebSession
.
Request
.
ContentEncoding
,
WebSession
.
Request
.
RequestBody
=
await
GetDecompressedResponseBody
(
WebSession
.
Request
.
ContentEncoding
,
requestBodyStream
.
ToArray
());
requestBodyStream
.
ToArray
());
}
}
//Now set the flag to true
//Now set the flag to true
...
@@ -184,17 +180,16 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -184,17 +180,16 @@ namespace Titanium.Web.Proxy.EventArguments
if
(
WebSession
.
Response
.
ContentLength
>
0
)
if
(
WebSession
.
Response
.
ContentLength
>
0
)
{
{
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStream
(
responseBodyStream
,
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStream
(
responseBodyStream
,
WebSession
.
Response
.
ContentLength
);
WebSession
.
Response
.
ContentLength
);
}
}
else
if
(
WebSession
.
Response
.
HttpVersion
.
Major
==
1
&&
WebSession
.
Response
.
HttpVersion
.
Minor
==
0
||
WebSession
.
Response
.
ContentLength
==
-
1
)
else
if
(
WebSession
.
Response
.
HttpVersion
.
Major
==
1
&&
WebSession
.
Response
.
HttpVersion
.
Minor
==
0
||
WebSession
.
Response
.
ContentLength
==
-
1
)
{
{
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStream
(
responseBodyStream
,
long
.
MaxValue
);
await
WebSession
.
ServerConnection
.
StreamReader
.
CopyBytesToStream
(
responseBodyStream
,
long
.
MaxValue
);
}
}
}
}
WebSession
.
Response
.
ResponseBody
=
await
GetDecompressedResponseBody
(
WebSession
.
Response
.
ContentEncoding
,
WebSession
.
Response
.
ResponseBody
=
await
GetDecompressedResponseBody
(
WebSession
.
Response
.
ContentEncoding
,
responseBodyStream
.
ToArray
());
responseBodyStream
.
ToArray
());
}
}
//set this to true for caching
//set this to true for caching
WebSession
.
Response
.
ResponseBodyRead
=
true
;
WebSession
.
Response
.
ResponseBodyRead
=
true
;
...
@@ -235,7 +230,8 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -235,7 +230,8 @@ namespace Titanium.Web.Proxy.EventArguments
await
ReadRequestBody
();
await
ReadRequestBody
();
}
}
//Use the encoding specified in request to decode the byte[] data to string
//Use the encoding specified in request to decode the byte[] data to string
return
WebSession
.
Request
.
RequestBodyString
??
(
WebSession
.
Request
.
RequestBodyString
=
WebSession
.
Request
.
Encoding
.
GetString
(
WebSession
.
Request
.
RequestBody
));
return
WebSession
.
Request
.
RequestBodyString
??
(
WebSession
.
Request
.
RequestBodyString
=
WebSession
.
Request
.
Encoding
.
GetString
(
WebSession
.
Request
.
RequestBody
));
}
}
/// <summary>
/// <summary>
...
@@ -315,8 +311,8 @@ namespace Titanium.Web.Proxy.EventArguments
...
@@ -315,8 +311,8 @@ namespace Titanium.Web.Proxy.EventArguments
await
GetResponseBody
();
await
GetResponseBody
();
return
WebSession
.
Response
.
ResponseBodyString
??
return
WebSession
.
Response
.
ResponseBodyString
??
(
WebSession
.
Response
.
ResponseBodyString
=
(
WebSession
.
Response
.
ResponseBodyString
=
WebSession
.
Response
.
Encoding
.
GetString
(
WebSession
.
Response
.
ResponseBody
));
WebSession
.
Response
.
Encoding
.
GetString
(
WebSession
.
Response
.
ResponseBody
));
}
}
/// <summary>
/// <summary>
...
...
Titanium.Web.Proxy/Exceptions/BodyNotFoundException.cs
View file @
c706c9fa
...
@@ -9,8 +9,7 @@
...
@@ -9,8 +9,7 @@
/// Constructor.
/// Constructor.
/// </summary>
/// </summary>
/// <param name="message"></param>
/// <param name="message"></param>
public
BodyNotFoundException
(
string
message
)
public
BodyNotFoundException
(
string
message
)
:
base
(
message
)
:
base
(
message
)
{
{
}
}
}
}
...
...
Titanium.Web.Proxy/Extensions/StreamExtensions.cs
View file @
c706c9fa
...
@@ -119,7 +119,8 @@ namespace Titanium.Web.Proxy.Extensions
...
@@ -119,7 +119,8 @@ namespace Titanium.Web.Proxy.Extensions
/// <param name="isChunked"></param>
/// <param name="isChunked"></param>
/// <param name="contentLength"></param>
/// <param name="contentLength"></param>
/// <returns></returns>
/// <returns></returns>
internal
static
async
Task
WriteResponseBody
(
this
CustomBinaryReader
inStreamReader
,
int
bufferSize
,
Stream
outStream
,
bool
isChunked
,
long
contentLength
)
internal
static
async
Task
WriteResponseBody
(
this
CustomBinaryReader
inStreamReader
,
int
bufferSize
,
Stream
outStream
,
bool
isChunked
,
long
contentLength
)
{
{
if
(!
isChunked
)
if
(!
isChunked
)
{
{
...
...
Titanium.Web.Proxy/Helpers/Firefox.cs
View file @
c706c9fa
...
@@ -16,8 +16,8 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -16,8 +16,8 @@ namespace Titanium.Web.Proxy.Helpers
try
try
{
{
var
myProfileDirectory
=
var
myProfileDirectory
=
new
DirectoryInfo
(
Environment
.
GetFolderPath
(
Environment
.
SpecialFolder
.
ApplicationData
)
+
new
DirectoryInfo
(
Environment
.
GetFolderPath
(
Environment
.
SpecialFolder
.
ApplicationData
)
+
"\\Mozilla\\Firefox\\Profiles\\"
)
"\\Mozilla\\Firefox\\Profiles\\"
)
.
GetDirectories
(
"*.default"
);
.
GetDirectories
(
"*.default"
);
var
myFfPrefFile
=
myProfileDirectory
[
0
].
FullName
+
"\\prefs.js"
;
var
myFfPrefFile
=
myProfileDirectory
[
0
].
FullName
+
"\\prefs.js"
;
if
(!
File
.
Exists
(
myFfPrefFile
))
if
(!
File
.
Exists
(
myFfPrefFile
))
{
{
...
@@ -36,8 +36,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -36,8 +36,7 @@ namespace Titanium.Web.Proxy.Helpers
if
(
myPrefContents
.
Contains
(
searchStr
))
if
(
myPrefContents
.
Contains
(
searchStr
))
{
{
// Add the proxy enable line and write it back to the file
// Add the proxy enable line and write it back to the file
myPrefContents
=
myPrefContents
.
Replace
(
searchStr
,
myPrefContents
=
myPrefContents
.
Replace
(
searchStr
,
"user_pref(\"network.proxy.type\", 5);"
);
"user_pref(\"network.proxy.type\", 5);"
);
}
}
}
}
...
...
Titanium.Web.Proxy/Helpers/ProxyInfo.cs
View file @
c706c9fa
...
@@ -70,7 +70,8 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -70,7 +70,8 @@ namespace Titanium.Web.Proxy.Helpers
private
static
string
BypassStringEscape
(
string
rawString
)
private
static
string
BypassStringEscape
(
string
rawString
)
{
{
Match
match
=
new
Regex
(
"^(?<scheme>.*://)?(?<host>[^:]*)(?<port>:[0-9]{1,5})?$"
,
RegexOptions
.
IgnoreCase
|
RegexOptions
.
CultureInvariant
).
Match
(
rawString
);
Match
match
=
new
Regex
(
"^(?<scheme>.*://)?(?<host>[^:]*)(?<port>:[0-9]{1,5})?$"
,
RegexOptions
.
IgnoreCase
|
RegexOptions
.
CultureInvariant
).
Match
(
rawString
);
string
empty1
;
string
empty1
;
string
rawString1
;
string
rawString1
;
string
empty2
;
string
empty2
;
...
...
Titanium.Web.Proxy/Helpers/RunTime.cs
View file @
c706c9fa
...
@@ -11,8 +11,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -11,8 +11,7 @@ namespace Titanium.Web.Proxy.Helpers
/// cache for mono runtime check
/// cache for mono runtime check
/// </summary>
/// </summary>
/// <returns></returns>
/// <returns></returns>
private
static
readonly
Lazy
<
bool
>
isRunningOnMono
private
static
readonly
Lazy
<
bool
>
isRunningOnMono
=
new
Lazy
<
bool
>(()
=>
Type
.
GetType
(
"Mono.Runtime"
)
!=
null
);
=
new
Lazy
<
bool
>(()
=>
Type
.
GetType
(
"Mono.Runtime"
)
!=
null
);
/// <summary>
/// <summary>
/// Is running on Mono?
/// Is running on Mono?
...
...
Titanium.Web.Proxy/Helpers/SystemProxy.cs
View file @
c706c9fa
...
@@ -33,8 +33,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -33,8 +33,7 @@ namespace Titanium.Web.Proxy.Helpers
internal
partial
class
NativeMethods
internal
partial
class
NativeMethods
{
{
[
DllImport
(
"wininet.dll"
)]
[
DllImport
(
"wininet.dll"
)]
internal
static
extern
bool
InternetSetOption
(
IntPtr
hInternet
,
int
dwOption
,
IntPtr
lpBuffer
,
internal
static
extern
bool
InternetSetOption
(
IntPtr
hInternet
,
int
dwOption
,
IntPtr
lpBuffer
,
int
dwBufferLength
);
int
dwBufferLength
);
[
DllImport
(
"kernel32.dll"
)]
[
DllImport
(
"kernel32.dll"
)]
internal
static
extern
IntPtr
GetConsoleWindow
();
internal
static
extern
IntPtr
GetConsoleWindow
();
...
@@ -304,11 +303,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -304,11 +303,7 @@ namespace Titanium.Web.Proxy.Helpers
private
ProxyInfo
GetProxyInfoFromRegistry
(
RegistryKey
reg
)
private
ProxyInfo
GetProxyInfoFromRegistry
(
RegistryKey
reg
)
{
{
var
pi
=
new
ProxyInfo
(
var
pi
=
new
ProxyInfo
(
null
,
reg
.
GetValue
(
regAutoConfigUrl
)
as
string
,
reg
.
GetValue
(
regProxyEnable
)
as
int
?,
reg
.
GetValue
(
regProxyServer
)
as
string
,
null
,
reg
.
GetValue
(
regAutoConfigUrl
)
as
string
,
reg
.
GetValue
(
regProxyEnable
)
as
int
?,
reg
.
GetValue
(
regProxyServer
)
as
string
,
reg
.
GetValue
(
regProxyOverride
)
as
string
);
reg
.
GetValue
(
regProxyOverride
)
as
string
);
return
pi
;
return
pi
;
...
...
Titanium.Web.Proxy/Helpers/Tcp.cs
View file @
c706c9fa
...
@@ -181,11 +181,8 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -181,11 +181,8 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="tcpConnectionFactory"></param>
/// <param name="tcpConnectionFactory"></param>
/// <param name="connection"></param>
/// <param name="connection"></param>
/// <returns></returns>
/// <returns></returns>
internal
static
async
Task
SendRaw
(
ProxyServer
server
,
internal
static
async
Task
SendRaw
(
ProxyServer
server
,
string
remoteHostName
,
int
remotePort
,
string
httpCmd
,
Version
httpVersion
,
string
remoteHostName
,
int
remotePort
,
Dictionary
<
string
,
HttpHeader
>
requestHeaders
,
bool
isHttps
,
Stream
clientStream
,
TcpConnectionFactory
tcpConnectionFactory
,
string
httpCmd
,
Version
httpVersion
,
Dictionary
<
string
,
HttpHeader
>
requestHeaders
,
bool
isHttps
,
Stream
clientStream
,
TcpConnectionFactory
tcpConnectionFactory
,
TcpConnection
connection
=
null
)
TcpConnection
connection
=
null
)
{
{
//prepare the prefix content
//prepare the prefix content
...
@@ -218,10 +215,7 @@ namespace Titanium.Web.Proxy.Helpers
...
@@ -218,10 +215,7 @@ namespace Titanium.Web.Proxy.Helpers
//create new connection if connection is null
//create new connection if connection is null
if
(
connection
==
null
)
if
(
connection
==
null
)
{
{
tcpConnection
=
await
tcpConnectionFactory
.
CreateClient
(
server
,
tcpConnection
=
await
tcpConnectionFactory
.
CreateClient
(
server
,
remoteHostName
,
remotePort
,
httpVersion
,
isHttps
,
null
,
null
);
remoteHostName
,
remotePort
,
httpVersion
,
isHttps
,
null
,
null
);
connectionCreated
=
true
;
connectionCreated
=
true
;
}
}
...
...
Titanium.Web.Proxy/Helpers/WinHttp/NativeMethods.WinHttp.cs
View file @
c706c9fa
...
@@ -18,7 +18,8 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
...
@@ -18,7 +18,8 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
internal
static
extern
bool
WinHttpSetTimeouts
(
WinHttpHandle
session
,
int
resolveTimeout
,
int
connectTimeout
,
int
sendTimeout
,
int
receiveTimeout
);
internal
static
extern
bool
WinHttpSetTimeouts
(
WinHttpHandle
session
,
int
resolveTimeout
,
int
connectTimeout
,
int
sendTimeout
,
int
receiveTimeout
);
[
DllImport
(
"winhttp.dll"
,
CharSet
=
CharSet
.
Unicode
,
SetLastError
=
true
)]
[
DllImport
(
"winhttp.dll"
,
CharSet
=
CharSet
.
Unicode
,
SetLastError
=
true
)]
internal
static
extern
bool
WinHttpGetProxyForUrl
(
WinHttpHandle
session
,
string
url
,
[
In
]
ref
WINHTTP_AUTOPROXY_OPTIONS
autoProxyOptions
,
out
WINHTTP_PROXY_INFO
proxyInfo
);
internal
static
extern
bool
WinHttpGetProxyForUrl
(
WinHttpHandle
session
,
string
url
,
[
In
]
ref
WINHTTP_AUTOPROXY_OPTIONS
autoProxyOptions
,
out
WINHTTP_PROXY_INFO
proxyInfo
);
[
DllImport
(
"winhttp.dll"
,
CharSet
=
CharSet
.
Unicode
,
SetLastError
=
true
)]
[
DllImport
(
"winhttp.dll"
,
CharSet
=
CharSet
.
Unicode
,
SetLastError
=
true
)]
internal
static
extern
bool
WinHttpCloseHandle
(
IntPtr
httpSession
);
internal
static
extern
bool
WinHttpCloseHandle
(
IntPtr
httpSession
);
...
...
Titanium.Web.Proxy/Http/HeaderParser.cs
View file @
c706c9fa
...
@@ -8,8 +8,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -8,8 +8,7 @@ namespace Titanium.Web.Proxy.Http
{
{
internal
static
class
HeaderParser
internal
static
class
HeaderParser
{
{
internal
static
async
Task
ReadHeaders
(
CustomBinaryReader
reader
,
internal
static
async
Task
ReadHeaders
(
CustomBinaryReader
reader
,
Dictionary
<
string
,
List
<
HttpHeader
>>
nonUniqueResponseHeaders
,
Dictionary
<
string
,
List
<
HttpHeader
>>
nonUniqueResponseHeaders
,
Dictionary
<
string
,
HttpHeader
>
headers
)
Dictionary
<
string
,
HttpHeader
>
headers
)
{
{
string
tmpLine
;
string
tmpLine
;
...
@@ -29,7 +28,11 @@ namespace Titanium.Web.Proxy.Http
...
@@ -29,7 +28,11 @@ namespace Titanium.Web.Proxy.Http
{
{
var
existing
=
headers
[
newHeader
.
Name
];
var
existing
=
headers
[
newHeader
.
Name
];
var
nonUniqueHeaders
=
new
List
<
HttpHeader
>
{
existing
,
newHeader
};
var
nonUniqueHeaders
=
new
List
<
HttpHeader
>
{
existing
,
newHeader
};
nonUniqueResponseHeaders
.
Add
(
newHeader
.
Name
,
nonUniqueHeaders
);
nonUniqueResponseHeaders
.
Add
(
newHeader
.
Name
,
nonUniqueHeaders
);
headers
.
Remove
(
newHeader
.
Name
);
headers
.
Remove
(
newHeader
.
Name
);
...
...
Titanium.Web.Proxy/Http/HttpWebClient.cs
View file @
c706c9fa
...
@@ -156,7 +156,8 @@ namespace Titanium.Web.Proxy.Http
...
@@ -156,7 +156,8 @@ namespace Titanium.Web.Proxy.Http
internal
async
Task
ReceiveResponse
()
internal
async
Task
ReceiveResponse
()
{
{
//return if this is already read
//return if this is already read
if
(
Response
.
ResponseStatusCode
!=
null
)
return
;
if
(
Response
.
ResponseStatusCode
!=
null
)
return
;
string
line
=
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
string
line
=
await
ServerConnection
.
StreamReader
.
ReadLineAsync
();
if
(
line
==
null
)
if
(
line
==
null
)
...
...
Titanium.Web.Proxy/Http/Request.cs
View file @
c706c9fa
...
@@ -218,7 +218,8 @@ namespace Titanium.Web.Proxy.Http
...
@@ -218,7 +218,8 @@ namespace Titanium.Web.Proxy.Http
{
{
var
hasHeader
=
RequestHeaders
.
ContainsKey
(
"expect"
);
var
hasHeader
=
RequestHeaders
.
ContainsKey
(
"expect"
);
if
(!
hasHeader
)
return
false
;
if
(!
hasHeader
)
return
false
;
var
header
=
RequestHeaders
[
"expect"
];
var
header
=
RequestHeaders
[
"expect"
];
return
header
.
Value
.
Equals
(
"100-continue"
);
return
header
.
Value
.
Equals
(
"100-continue"
);
...
@@ -317,8 +318,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -317,8 +318,7 @@ namespace Titanium.Web.Proxy.Http
/// <returns></returns>
/// <returns></returns>
public
bool
HeaderExists
(
string
name
)
public
bool
HeaderExists
(
string
name
)
{
{
if
(
RequestHeaders
.
ContainsKey
(
name
)
if
(
RequestHeaders
.
ContainsKey
(
name
)
||
NonUniqueRequestHeaders
.
ContainsKey
(
name
))
||
NonUniqueRequestHeaders
.
ContainsKey
(
name
))
{
{
return
true
;
return
true
;
}
}
...
@@ -336,7 +336,10 @@ namespace Titanium.Web.Proxy.Http
...
@@ -336,7 +336,10 @@ namespace Titanium.Web.Proxy.Http
{
{
if
(
RequestHeaders
.
ContainsKey
(
name
))
if
(
RequestHeaders
.
ContainsKey
(
name
))
{
{
return
new
List
<
HttpHeader
>
{
RequestHeaders
[
name
]
};
return
new
List
<
HttpHeader
>
{
RequestHeaders
[
name
]
};
}
}
if
(
NonUniqueRequestHeaders
.
ContainsKey
(
name
))
if
(
NonUniqueRequestHeaders
.
ContainsKey
(
name
))
{
{
...
@@ -387,8 +390,11 @@ namespace Titanium.Web.Proxy.Http
...
@@ -387,8 +390,11 @@ namespace Titanium.Web.Proxy.Http
var
existing
=
RequestHeaders
[
newHeader
.
Name
];
var
existing
=
RequestHeaders
[
newHeader
.
Name
];
RequestHeaders
.
Remove
(
newHeader
.
Name
);
RequestHeaders
.
Remove
(
newHeader
.
Name
);
NonUniqueRequestHeaders
.
Add
(
newHeader
.
Name
,
NonUniqueRequestHeaders
.
Add
(
newHeader
.
Name
,
new
List
<
HttpHeader
>
new
List
<
HttpHeader
>
{
existing
,
newHeader
});
{
existing
,
newHeader
});
}
}
else
else
{
{
...
@@ -434,8 +440,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -434,8 +440,7 @@ namespace Titanium.Web.Proxy.Http
}
}
else
if
(
NonUniqueRequestHeaders
.
ContainsKey
(
header
.
Name
))
else
if
(
NonUniqueRequestHeaders
.
ContainsKey
(
header
.
Name
))
{
{
if
(
NonUniqueRequestHeaders
[
header
.
Name
]
if
(
NonUniqueRequestHeaders
[
header
.
Name
].
RemoveAll
(
x
=>
x
.
Equals
(
header
))
>
0
)
.
RemoveAll
(
x
=>
x
.
Equals
(
header
))
>
0
)
{
{
return
true
;
return
true
;
}
}
...
...
Titanium.Web.Proxy/Http/Response.cs
View file @
c706c9fa
...
@@ -36,7 +36,8 @@ namespace Titanium.Web.Proxy.Http
...
@@ -36,7 +36,8 @@ namespace Titanium.Web.Proxy.Http
{
{
var
hasHeader
=
ResponseHeaders
.
ContainsKey
(
"content-encoding"
);
var
hasHeader
=
ResponseHeaders
.
ContainsKey
(
"content-encoding"
);
if
(!
hasHeader
)
return
null
;
if
(!
hasHeader
)
return
null
;
var
header
=
ResponseHeaders
[
"content-encoding"
];
var
header
=
ResponseHeaders
[
"content-encoding"
];
return
header
.
Value
.
Trim
();
return
header
.
Value
.
Trim
();
...
@@ -249,8 +250,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -249,8 +250,7 @@ namespace Titanium.Web.Proxy.Http
/// <returns></returns>
/// <returns></returns>
public
bool
HeaderExists
(
string
name
)
public
bool
HeaderExists
(
string
name
)
{
{
if
(
ResponseHeaders
.
ContainsKey
(
name
)
if
(
ResponseHeaders
.
ContainsKey
(
name
)
||
NonUniqueResponseHeaders
.
ContainsKey
(
name
))
||
NonUniqueResponseHeaders
.
ContainsKey
(
name
))
{
{
return
true
;
return
true
;
}
}
...
@@ -268,7 +268,10 @@ namespace Titanium.Web.Proxy.Http
...
@@ -268,7 +268,10 @@ namespace Titanium.Web.Proxy.Http
{
{
if
(
ResponseHeaders
.
ContainsKey
(
name
))
if
(
ResponseHeaders
.
ContainsKey
(
name
))
{
{
return
new
List
<
HttpHeader
>
{
ResponseHeaders
[
name
]
};
return
new
List
<
HttpHeader
>
{
ResponseHeaders
[
name
]
};
}
}
if
(
NonUniqueResponseHeaders
.
ContainsKey
(
name
))
if
(
NonUniqueResponseHeaders
.
ContainsKey
(
name
))
{
{
...
@@ -319,8 +322,11 @@ namespace Titanium.Web.Proxy.Http
...
@@ -319,8 +322,11 @@ namespace Titanium.Web.Proxy.Http
var
existing
=
ResponseHeaders
[
newHeader
.
Name
];
var
existing
=
ResponseHeaders
[
newHeader
.
Name
];
ResponseHeaders
.
Remove
(
newHeader
.
Name
);
ResponseHeaders
.
Remove
(
newHeader
.
Name
);
NonUniqueResponseHeaders
.
Add
(
newHeader
.
Name
,
NonUniqueResponseHeaders
.
Add
(
newHeader
.
Name
,
new
List
<
HttpHeader
>
new
List
<
HttpHeader
>
{
existing
,
newHeader
});
{
existing
,
newHeader
});
}
}
else
else
{
{
...
@@ -366,8 +372,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -366,8 +372,7 @@ namespace Titanium.Web.Proxy.Http
}
}
else
if
(
NonUniqueResponseHeaders
.
ContainsKey
(
header
.
Name
))
else
if
(
NonUniqueResponseHeaders
.
ContainsKey
(
header
.
Name
))
{
{
if
(
NonUniqueResponseHeaders
[
header
.
Name
]
if
(
NonUniqueResponseHeaders
[
header
.
Name
].
RemoveAll
(
x
=>
x
.
Equals
(
header
))
>
0
)
.
RemoveAll
(
x
=>
x
.
Equals
(
header
))
>
0
)
{
{
return
true
;
return
true
;
}
}
...
...
Titanium.Web.Proxy/Models/EndPoint.cs
View file @
c706c9fa
...
@@ -119,11 +119,14 @@ namespace Titanium.Web.Proxy.Models
...
@@ -119,11 +119,14 @@ namespace Titanium.Web.Proxy.Models
/// <param name="ipAddress"></param>
/// <param name="ipAddress"></param>
/// <param name="port"></param>
/// <param name="port"></param>
/// <param name="enableSsl"></param>
/// <param name="enableSsl"></param>
public
ExplicitProxyEndPoint
(
IPAddress
ipAddress
,
int
port
,
bool
enableSsl
)
public
ExplicitProxyEndPoint
(
IPAddress
ipAddress
,
int
port
,
bool
enableSsl
)
:
base
(
ipAddress
,
port
,
enableSsl
)
:
base
(
ipAddress
,
port
,
enableSsl
)
{
{
//init to well known HTTPS ports
//init to well known HTTPS ports
RemoteHttpsPorts
=
new
List
<
int
>
{
443
,
8443
};
RemoteHttpsPorts
=
new
List
<
int
>
{
443
,
8443
};
}
}
}
}
...
@@ -145,8 +148,7 @@ namespace Titanium.Web.Proxy.Models
...
@@ -145,8 +148,7 @@ namespace Titanium.Web.Proxy.Models
/// <param name="ipAddress"></param>
/// <param name="ipAddress"></param>
/// <param name="port"></param>
/// <param name="port"></param>
/// <param name="enableSsl"></param>
/// <param name="enableSsl"></param>
public
TransparentProxyEndPoint
(
IPAddress
ipAddress
,
int
port
,
bool
enableSsl
)
public
TransparentProxyEndPoint
(
IPAddress
ipAddress
,
int
port
,
bool
enableSsl
)
:
base
(
ipAddress
,
port
,
enableSsl
)
:
base
(
ipAddress
,
port
,
enableSsl
)
{
{
GenericCertificateName
=
"localhost"
;
GenericCertificateName
=
"localhost"
;
}
}
...
...
Titanium.Web.Proxy/Network/Certificate/BCCertificateMaker.cs
View file @
c706c9fa
...
@@ -81,14 +81,10 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -81,14 +81,10 @@ namespace Titanium.Web.Proxy.Network.Certificate
if
(
hostName
!=
null
)
if
(
hostName
!=
null
)
{
{
//add subject alternative names
//add subject alternative names
var
subjectAlternativeNames
=
new
Asn1Encodable
[]
var
subjectAlternativeNames
=
new
Asn1Encodable
[]
{
new
GeneralName
(
GeneralName
.
DnsName
,
hostName
),
};
{
new
GeneralName
(
GeneralName
.
DnsName
,
hostName
),
};
var
subjectAlternativeNamesExtension
=
new
DerSequence
(
subjectAlternativeNames
);
var
subjectAlternativeNamesExtension
=
new
DerSequence
(
subjectAlternativeNames
);
certificateGenerator
.
AddExtension
(
certificateGenerator
.
AddExtension
(
X509Extensions
.
SubjectAlternativeName
.
Id
,
false
,
subjectAlternativeNamesExtension
);
X509Extensions
.
SubjectAlternativeName
.
Id
,
false
,
subjectAlternativeNamesExtension
);
}
}
// Subject Public Key
// Subject Public Key
var
keyGenerationParameters
=
new
KeyGenerationParameters
(
secureRandom
,
keyStrength
);
var
keyGenerationParameters
=
new
KeyGenerationParameters
(
secureRandom
,
keyStrength
);
...
@@ -118,7 +114,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -118,7 +114,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
}
}
var
rsa
=
RsaPrivateKeyStructure
.
GetInstance
(
seq
);
var
rsa
=
RsaPrivateKeyStructure
.
GetInstance
(
seq
);
var
rsaparams
=
new
RsaPrivateCrtKeyParameters
(
rsa
.
Modulus
,
rsa
.
PublicExponent
,
rsa
.
PrivateExponent
,
rsa
.
Prime1
,
rsa
.
Prime2
,
rsa
.
Exponent1
,
rsa
.
Exponent2
,
rsa
.
Coefficient
);
var
rsaparams
=
new
RsaPrivateCrtKeyParameters
(
rsa
.
Modulus
,
rsa
.
PublicExponent
,
rsa
.
PrivateExponent
,
rsa
.
Prime1
,
rsa
.
Prime2
,
rsa
.
Exponent1
,
rsa
.
Exponent2
,
rsa
.
Coefficient
);
// Set private key onto certificate instance
// Set private key onto certificate instance
x509Certificate
.
PrivateKey
=
DotNetUtilities
.
ToRSA
(
rsaparams
);
x509Certificate
.
PrivateKey
=
DotNetUtilities
.
ToRSA
(
rsaparams
);
...
@@ -138,9 +135,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -138,9 +135,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// <param name="signingCertificate">The signing certificate.</param>
/// <param name="signingCertificate">The signing certificate.</param>
/// <returns>X509Certificate2 instance.</returns>
/// <returns>X509Certificate2 instance.</returns>
/// <exception cref="System.ArgumentException">You must specify a Signing Certificate if and only if you are not creating a root.</exception>
/// <exception cref="System.ArgumentException">You must specify a Signing Certificate if and only if you are not creating a root.</exception>
private
X509Certificate2
MakeCertificateInternal
(
bool
isRoot
,
private
X509Certificate2
MakeCertificateInternal
(
bool
isRoot
,
string
hostName
,
string
subjectName
,
DateTime
validFrom
,
DateTime
validTo
,
string
hostName
,
string
subjectName
,
X509Certificate2
signingCertificate
)
DateTime
validFrom
,
DateTime
validTo
,
X509Certificate2
signingCertificate
)
{
{
if
(
isRoot
!=
(
null
==
signingCertificate
))
if
(
isRoot
!=
(
null
==
signingCertificate
))
{
{
...
@@ -149,7 +145,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -149,7 +145,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
return
isRoot
return
isRoot
?
GenerateCertificate
(
null
,
subjectName
,
subjectName
,
validFrom
,
validTo
)
?
GenerateCertificate
(
null
,
subjectName
,
subjectName
,
validFrom
,
validTo
)
:
GenerateCertificate
(
hostName
,
subjectName
,
signingCertificate
.
Subject
,
validFrom
,
validTo
,
issuerPrivateKey
:
DotNetUtilities
.
GetKeyPair
(
signingCertificate
.
PrivateKey
).
Private
);
:
GenerateCertificate
(
hostName
,
subjectName
,
signingCertificate
.
Subject
,
validFrom
,
validTo
,
issuerPrivateKey
:
DotNetUtilities
.
GetKeyPair
(
signingCertificate
.
PrivateKey
).
Private
);
}
}
/// <summary>
/// <summary>
...
@@ -187,7 +184,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
...
@@ -187,7 +184,8 @@ namespace Titanium.Web.Proxy.Network.Certificate
return
certificate
;
return
certificate
;
}
}
return
MakeCertificateInternal
(
isRoot
,
subject
,
$"CN=
{
subject
}
"
,
DateTime
.
UtcNow
.
AddDays
(-
certificateGraceDays
),
DateTime
.
UtcNow
.
AddDays
(
certificateValidDays
),
isRoot
?
null
:
signingCert
);
return
MakeCertificateInternal
(
isRoot
,
subject
,
$"CN=
{
subject
}
"
,
DateTime
.
UtcNow
.
AddDays
(-
certificateGraceDays
),
DateTime
.
UtcNow
.
AddDays
(
certificateValidDays
),
isRoot
?
null
:
signingCert
);
}
}
}
}
}
}
Titanium.Web.Proxy/Network/CertificateManager.cs
View file @
c706c9fa
...
@@ -52,9 +52,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -52,9 +52,7 @@ namespace Titanium.Web.Proxy.Network
if
(
certEngine
==
null
)
if
(
certEngine
==
null
)
{
{
certEngine
=
engine
==
CertificateEngine
.
BouncyCastle
certEngine
=
engine
==
CertificateEngine
.
BouncyCastle
?
(
ICertificateMaker
)
new
BCCertificateMaker
()
:
new
WinCertificateMaker
();
?
(
ICertificateMaker
)
new
BCCertificateMaker
()
:
new
WinCertificateMaker
();
}
}
}
}
}
}
...
@@ -143,7 +141,8 @@ namespace Titanium.Web.Proxy.Network
...
@@ -143,7 +141,8 @@ namespace Titanium.Web.Proxy.Network
}
}
var
path
=
Path
.
GetDirectoryName
(
assemblyLocation
);
var
path
=
Path
.
GetDirectoryName
(
assemblyLocation
);
if
(
null
==
path
)
throw
new
NullReferenceException
();
if
(
null
==
path
)
throw
new
NullReferenceException
();
var
fileName
=
Path
.
Combine
(
path
,
"rootCert.pfx"
);
var
fileName
=
Path
.
Combine
(
path
,
"rootCert.pfx"
);
return
fileName
;
return
fileName
;
}
}
...
@@ -151,7 +150,8 @@ namespace Titanium.Web.Proxy.Network
...
@@ -151,7 +150,8 @@ namespace Titanium.Web.Proxy.Network
private
X509Certificate2
LoadRootCertificate
()
private
X509Certificate2
LoadRootCertificate
()
{
{
var
fileName
=
GetRootCertificatePath
();
var
fileName
=
GetRootCertificatePath
();
if
(!
File
.
Exists
(
fileName
))
return
null
;
if
(!
File
.
Exists
(
fileName
))
return
null
;
try
try
{
{
return
new
X509Certificate2
(
fileName
,
string
.
Empty
,
X509KeyStorageFlags
.
Exportable
);
return
new
X509Certificate2
(
fileName
,
string
.
Empty
,
X509KeyStorageFlags
.
Exportable
);
...
@@ -387,7 +387,10 @@ namespace Titanium.Web.Proxy.Network
...
@@ -387,7 +387,10 @@ namespace Titanium.Web.Proxy.Network
}
}
if
(
certificate
!=
null
&&
!
certificateCache
.
ContainsKey
(
certificateName
))
if
(
certificate
!=
null
&&
!
certificateCache
.
ContainsKey
(
certificateName
))
{
{
certificateCache
.
Add
(
certificateName
,
new
CachedCertificate
{
Certificate
=
certificate
});
certificateCache
.
Add
(
certificateName
,
new
CachedCertificate
{
Certificate
=
certificate
});
}
}
}
}
else
else
...
@@ -422,9 +425,7 @@ namespace Titanium.Web.Proxy.Network
...
@@ -422,9 +425,7 @@ namespace Titanium.Web.Proxy.Network
{
{
var
cutOff
=
DateTime
.
Now
.
AddMinutes
(-
1
*
certificateCacheTimeOutMinutes
);
var
cutOff
=
DateTime
.
Now
.
AddMinutes
(-
1
*
certificateCacheTimeOutMinutes
);
var
outdated
=
certificateCache
var
outdated
=
certificateCache
.
Where
(
x
=>
x
.
Value
.
LastAccess
<
cutOff
).
ToList
();
.
Where
(
x
=>
x
.
Value
.
LastAccess
<
cutOff
)
.
ToList
();
foreach
(
var
cache
in
outdated
)
foreach
(
var
cache
in
outdated
)
certificateCache
.
Remove
(
cache
.
Key
);
certificateCache
.
Remove
(
cache
.
Key
);
...
...
Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
View file @
c706c9fa
...
@@ -29,22 +29,17 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -29,22 +29,17 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <param name="externalHttpProxy"></param>
/// <param name="externalHttpProxy"></param>
/// <param name="externalHttpsProxy"></param>
/// <param name="externalHttpsProxy"></param>
/// <returns></returns>
/// <returns></returns>
internal
async
Task
<
TcpConnection
>
CreateClient
(
ProxyServer
server
,
internal
async
Task
<
TcpConnection
>
CreateClient
(
ProxyServer
server
,
string
remoteHostName
,
int
remotePort
,
Version
httpVersion
,
bool
isHttps
,
string
remoteHostName
,
int
remotePort
,
Version
httpVersion
,
bool
isHttps
,
ExternalProxy
externalHttpProxy
,
ExternalProxy
externalHttpsProxy
)
ExternalProxy
externalHttpProxy
,
ExternalProxy
externalHttpsProxy
)
{
{
bool
useHttpProxy
=
false
;
bool
useHttpProxy
=
false
;
//check if external proxy is set for HTTP
//check if external proxy is set for HTTP
if
(!
isHttps
&&
externalHttpProxy
!=
null
if
(!
isHttps
&&
externalHttpProxy
!=
null
&&
!(
externalHttpProxy
.
HostName
==
remoteHostName
&&
externalHttpProxy
.
Port
==
remotePort
))
&&
!(
externalHttpProxy
.
HostName
==
remoteHostName
&&
externalHttpProxy
.
Port
==
remotePort
))
{
{
useHttpProxy
=
true
;
useHttpProxy
=
true
;
//check if we need to ByPass
//check if we need to ByPass
if
(
externalHttpProxy
.
BypassLocalhost
if
(
externalHttpProxy
.
BypassLocalhost
&&
NetworkHelper
.
IsLocalIpAddress
(
remoteHostName
))
&&
NetworkHelper
.
IsLocalIpAddress
(
remoteHostName
))
{
{
useHttpProxy
=
false
;
useHttpProxy
=
false
;
}
}
...
@@ -52,15 +47,12 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -52,15 +47,12 @@ namespace Titanium.Web.Proxy.Network.Tcp
bool
useHttpsProxy
=
false
;
bool
useHttpsProxy
=
false
;
//check if external proxy is set for HTTPS
//check if external proxy is set for HTTPS
if
(
isHttps
&&
externalHttpsProxy
!=
null
if
(
isHttps
&&
externalHttpsProxy
!=
null
&&
!(
externalHttpsProxy
.
HostName
==
remoteHostName
&&
externalHttpsProxy
.
Port
==
remotePort
))
&&
!(
externalHttpsProxy
.
HostName
==
remoteHostName
&&
externalHttpsProxy
.
Port
==
remotePort
))
{
{
useHttpsProxy
=
true
;
useHttpsProxy
=
true
;
//check if we need to ByPass
//check if we need to ByPass
if
(
externalHttpsProxy
.
BypassLocalhost
if
(
externalHttpsProxy
.
BypassLocalhost
&&
NetworkHelper
.
IsLocalIpAddress
(
remoteHostName
))
&&
NetworkHelper
.
IsLocalIpAddress
(
remoteHostName
))
{
{
useHttpsProxy
=
false
;
useHttpsProxy
=
false
;
}
}
...
@@ -80,7 +72,10 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -80,7 +72,10 @@ namespace Titanium.Web.Proxy.Network.Tcp
await
client
.
ConnectAsync
(
externalHttpsProxy
.
HostName
,
externalHttpsProxy
.
Port
);
await
client
.
ConnectAsync
(
externalHttpsProxy
.
HostName
,
externalHttpsProxy
.
Port
);
stream
=
new
CustomBufferedStream
(
client
.
GetStream
(),
server
.
BufferSize
);
stream
=
new
CustomBufferedStream
(
client
.
GetStream
(),
server
.
BufferSize
);
using
(
var
writer
=
new
StreamWriter
(
stream
,
Encoding
.
ASCII
,
server
.
BufferSize
,
true
)
{
NewLine
=
ProxyConstants
.
NewLine
})
using
(
var
writer
=
new
StreamWriter
(
stream
,
Encoding
.
ASCII
,
server
.
BufferSize
,
true
)
{
NewLine
=
ProxyConstants
.
NewLine
})
{
{
await
writer
.
WriteLineAsync
(
$"CONNECT
{
remoteHostName
}
:
{
remotePort
}
HTTP/
{
httpVersion
}
"
);
await
writer
.
WriteLineAsync
(
$"CONNECT
{
remoteHostName
}
:
{
remotePort
}
HTTP/
{
httpVersion
}
"
);
await
writer
.
WriteLineAsync
(
$"Host:
{
remoteHostName
}
:
{
remotePort
}
"
);
await
writer
.
WriteLineAsync
(
$"Host:
{
remoteHostName
}
:
{
remotePort
}
"
);
...
@@ -89,7 +84,9 @@ namespace Titanium.Web.Proxy.Network.Tcp
...
@@ -89,7 +84,9 @@ namespace Titanium.Web.Proxy.Network.Tcp
if
(!
string
.
IsNullOrEmpty
(
externalHttpsProxy
.
UserName
)
&&
externalHttpsProxy
.
Password
!=
null
)
if
(!
string
.
IsNullOrEmpty
(
externalHttpsProxy
.
UserName
)
&&
externalHttpsProxy
.
Password
!=
null
)
{
{
await
writer
.
WriteLineAsync
(
"Proxy-Connection: keep-alive"
);
await
writer
.
WriteLineAsync
(
"Proxy-Connection: keep-alive"
);
await
writer
.
WriteLineAsync
(
"Proxy-Authorization"
+
": Basic "
+
Convert
.
ToBase64String
(
Encoding
.
UTF8
.
GetBytes
(
externalHttpsProxy
.
UserName
+
":"
+
externalHttpsProxy
.
Password
)));
await
writer
.
WriteLineAsync
(
"Proxy-Authorization"
+
": Basic "
+
Convert
.
ToBase64String
(
Encoding
.
UTF8
.
GetBytes
(
externalHttpsProxy
.
UserName
+
":"
+
externalHttpsProxy
.
Password
)));
}
}
await
writer
.
WriteLineAsync
();
await
writer
.
WriteLineAsync
();
await
writer
.
FlushAsync
();
await
writer
.
FlushAsync
();
...
...
Titanium.Web.Proxy/Network/WinAuth/Security/LittleEndian.cs
View file @
c706c9fa
...
@@ -61,18 +61,10 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
...
@@ -61,18 +61,10 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
{
{
if
(
BitConverter
.
IsLittleEndian
)
if
(
BitConverter
.
IsLittleEndian
)
{
{
return
new
[]
return
new
[]
{
bytes
[
0
],
bytes
[
1
],
bytes
[
2
],
bytes
[
3
],
bytes
[
4
],
bytes
[
5
],
bytes
[
6
],
bytes
[
7
]
};
{
bytes
[
0
],
bytes
[
1
],
bytes
[
2
],
bytes
[
3
],
bytes
[
4
],
bytes
[
5
],
bytes
[
6
],
bytes
[
7
]
};
}
}
return
new
[]
return
new
[]
{
bytes
[
7
],
bytes
[
6
],
bytes
[
5
],
bytes
[
4
],
bytes
[
3
],
bytes
[
2
],
bytes
[
1
],
bytes
[
0
]
};
{
bytes
[
7
],
bytes
[
6
],
bytes
[
5
],
bytes
[
4
],
bytes
[
3
],
bytes
[
2
],
bytes
[
1
],
bytes
[
0
]
};
}
}
internal
static
byte
[]
GetBytes
(
bool
value
)
internal
static
byte
[]
GetBytes
(
bool
value
)
...
...
Titanium.Web.Proxy/Network/WinAuth/Security/WinAuthEndPoint.cs
View file @
c706c9fa
...
@@ -16,8 +16,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
...
@@ -16,8 +16,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
/// <summary>
/// <summary>
/// Keep track of auth states for reuse in final challenge response
/// Keep track of auth states for reuse in final challenge response
/// </summary>
/// </summary>
private
static
readonly
IDictionary
<
Guid
,
State
>
authStates
private
static
readonly
IDictionary
<
Guid
,
State
>
authStates
=
new
ConcurrentDictionary
<
Guid
,
State
>();
=
new
ConcurrentDictionary
<
Guid
,
State
>();
/// <summary>
/// <summary>
...
@@ -27,17 +26,14 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
...
@@ -27,17 +26,14 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
/// <param name="authScheme"></param>
/// <param name="authScheme"></param>
/// <param name="requestId"></param>
/// <param name="requestId"></param>
/// <returns></returns>
/// <returns></returns>
internal
static
byte
[]
AcquireInitialSecurityToken
(
string
hostname
,
internal
static
byte
[]
AcquireInitialSecurityToken
(
string
hostname
,
string
authScheme
,
Guid
requestId
)
string
authScheme
,
Guid
requestId
)
{
{
byte
[]
token
;
byte
[]
token
;
//null for initial call
//null for initial call
SecurityBufferDesciption
serverToken
SecurityBufferDesciption
serverToken
=
new
SecurityBufferDesciption
();
=
new
SecurityBufferDesciption
();
SecurityBufferDesciption
clientToken
SecurityBufferDesciption
clientToken
=
new
SecurityBufferDesciption
(
MaximumTokenSize
);
=
new
SecurityBufferDesciption
(
MaximumTokenSize
);
try
try
{
{
...
@@ -101,17 +97,14 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
...
@@ -101,17 +97,14 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
/// <param name="serverChallenge"></param>
/// <param name="serverChallenge"></param>
/// <param name="requestId"></param>
/// <param name="requestId"></param>
/// <returns></returns>
/// <returns></returns>
internal
static
byte
[]
AcquireFinalSecurityToken
(
string
hostname
,
internal
static
byte
[]
AcquireFinalSecurityToken
(
string
hostname
,
byte
[]
serverChallenge
,
Guid
requestId
)
byte
[]
serverChallenge
,
Guid
requestId
)
{
{
byte
[]
token
;
byte
[]
token
;
//user server challenge
//user server challenge
SecurityBufferDesciption
serverToken
SecurityBufferDesciption
serverToken
=
new
SecurityBufferDesciption
(
serverChallenge
);
=
new
SecurityBufferDesciption
(
serverChallenge
);
SecurityBufferDesciption
clientToken
SecurityBufferDesciption
clientToken
=
new
SecurityBufferDesciption
(
MaximumTokenSize
);
=
new
SecurityBufferDesciption
(
MaximumTokenSize
);
try
try
{
{
...
@@ -161,9 +154,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
...
@@ -161,9 +154,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
{
{
var
cutOff
=
DateTime
.
Now
.
AddMinutes
(-
1
*
stateCacheTimeOutMinutes
);
var
cutOff
=
DateTime
.
Now
.
AddMinutes
(-
1
*
stateCacheTimeOutMinutes
);
var
outdated
=
authStates
var
outdated
=
authStates
.
Where
(
x
=>
x
.
Value
.
LastSeen
<
cutOff
).
ToList
();
.
Where
(
x
=>
x
.
Value
.
LastSeen
<
cutOff
)
.
ToList
();
foreach
(
var
cache
in
outdated
)
foreach
(
var
cache
in
outdated
)
{
{
...
...
Titanium.Web.Proxy/Network/WinAuth/WinAuthHandler.cs
View file @
c706c9fa
...
@@ -18,8 +18,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth
...
@@ -18,8 +18,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth
/// <param name="authScheme"></param>
/// <param name="authScheme"></param>
/// <param name="requestId"></param>
/// <param name="requestId"></param>
/// <returns></returns>
/// <returns></returns>
public
static
string
GetInitialAuthToken
(
string
serverHostname
,
public
static
string
GetInitialAuthToken
(
string
serverHostname
,
string
authScheme
,
Guid
requestId
)
string
authScheme
,
Guid
requestId
)
{
{
var
tokenBytes
=
WinAuthEndPoint
.
AcquireInitialSecurityToken
(
serverHostname
,
authScheme
,
requestId
);
var
tokenBytes
=
WinAuthEndPoint
.
AcquireInitialSecurityToken
(
serverHostname
,
authScheme
,
requestId
);
return
string
.
Concat
(
" "
,
Convert
.
ToBase64String
(
tokenBytes
));
return
string
.
Concat
(
" "
,
Convert
.
ToBase64String
(
tokenBytes
));
...
@@ -33,11 +32,9 @@ namespace Titanium.Web.Proxy.Network.WinAuth
...
@@ -33,11 +32,9 @@ namespace Titanium.Web.Proxy.Network.WinAuth
/// <param name="serverToken"></param>
/// <param name="serverToken"></param>
/// <param name="requestId"></param>
/// <param name="requestId"></param>
/// <returns></returns>
/// <returns></returns>
public
static
string
GetFinalAuthToken
(
string
serverHostname
,
public
static
string
GetFinalAuthToken
(
string
serverHostname
,
string
serverToken
,
Guid
requestId
)
string
serverToken
,
Guid
requestId
)
{
{
var
tokenBytes
=
WinAuthEndPoint
.
AcquireFinalSecurityToken
(
serverHostname
,
var
tokenBytes
=
WinAuthEndPoint
.
AcquireFinalSecurityToken
(
serverHostname
,
Convert
.
FromBase64String
(
serverToken
),
requestId
);
Convert
.
FromBase64String
(
serverToken
),
requestId
);
return
string
.
Concat
(
" "
,
Convert
.
ToBase64String
(
tokenBytes
));
return
string
.
Concat
(
" "
,
Convert
.
ToBase64String
(
tokenBytes
));
}
}
...
...
Titanium.Web.Proxy/ProxyAuthorizationHandler.cs
View file @
c706c9fa
...
@@ -30,7 +30,8 @@ namespace Titanium.Web.Proxy
...
@@ -30,7 +30,8 @@ namespace Titanium.Web.Proxy
}
}
var
header
=
httpHeaders
.
FirstOrDefault
(
t
=>
t
.
Name
==
"Proxy-Authorization"
);
var
header
=
httpHeaders
.
FirstOrDefault
(
t
=>
t
.
Name
==
"Proxy-Authorization"
);
if
(
header
==
null
)
throw
new
NullReferenceException
();
if
(
header
==
null
)
throw
new
NullReferenceException
();
var
headerValue
=
header
.
Value
.
Trim
();
var
headerValue
=
header
.
Value
.
Trim
();
if
(!
headerValue
.
StartsWith
(
"basic"
,
StringComparison
.
CurrentCultureIgnoreCase
))
if
(!
headerValue
.
StartsWith
(
"basic"
,
StringComparison
.
CurrentCultureIgnoreCase
))
{
{
...
...
Titanium.Web.Proxy/ProxyServer.cs
View file @
c706c9fa
...
@@ -253,8 +253,7 @@ namespace Titanium.Web.Proxy
...
@@ -253,8 +253,7 @@ namespace Titanium.Web.Proxy
/// <summary>
/// <summary>
/// List of supported Ssl versions
/// List of supported Ssl versions
/// </summary>
/// </summary>
public
SslProtocols
SupportedSslProtocols
{
get
;
set
;
}
=
SslProtocols
.
Tls
public
SslProtocols
SupportedSslProtocols
{
get
;
set
;
}
=
SslProtocols
.
Tls
|
SslProtocols
.
Tls11
|
SslProtocols
.
Tls12
|
SslProtocols
.
Ssl3
;
|
SslProtocols
.
Tls11
|
SslProtocols
.
Tls12
|
SslProtocols
.
Ssl3
;
/// <summary>
/// <summary>
/// Total number of active client connections
/// Total number of active client connections
...
@@ -309,8 +308,7 @@ namespace Titanium.Web.Proxy
...
@@ -309,8 +308,7 @@ namespace Titanium.Web.Proxy
/// <param name="endPoint"></param>
/// <param name="endPoint"></param>
public
void
AddEndPoint
(
ProxyEndPoint
endPoint
)
public
void
AddEndPoint
(
ProxyEndPoint
endPoint
)
{
{
if
(
ProxyEndPoints
.
Any
(
x
=>
x
.
IpAddress
.
Equals
(
endPoint
.
IpAddress
)
if
(
ProxyEndPoints
.
Any
(
x
=>
x
.
IpAddress
.
Equals
(
endPoint
.
IpAddress
)
&&
endPoint
.
Port
!=
0
&&
x
.
Port
==
endPoint
.
Port
))
&&
endPoint
.
Port
!=
0
&&
x
.
Port
==
endPoint
.
Port
))
{
{
throw
new
Exception
(
"Cannot add another endpoint to same port & ip address"
);
throw
new
Exception
(
"Cannot add another endpoint to same port & ip address"
);
}
}
...
@@ -617,7 +615,8 @@ namespace Titanium.Web.Proxy
...
@@ -617,7 +615,8 @@ namespace Titanium.Web.Proxy
/// <param name="endPoint"></param>
/// <param name="endPoint"></param>
private
void
ValidateEndPointAsSystemProxy
(
ExplicitProxyEndPoint
endPoint
)
private
void
ValidateEndPointAsSystemProxy
(
ExplicitProxyEndPoint
endPoint
)
{
{
if
(
endPoint
==
null
)
throw
new
ArgumentNullException
(
nameof
(
endPoint
));
if
(
endPoint
==
null
)
throw
new
ArgumentNullException
(
nameof
(
endPoint
));
if
(
ProxyEndPoints
.
Contains
(
endPoint
)
==
false
)
if
(
ProxyEndPoints
.
Contains
(
endPoint
)
==
false
)
{
{
throw
new
Exception
(
"Cannot set endPoints not added to proxy as system proxy"
);
throw
new
Exception
(
"Cannot set endPoints not added to proxy as system proxy"
);
...
...
Titanium.Web.Proxy/RequestHandler.cs
View file @
c706c9fa
This diff is collapsed.
Click to expand it.
Titanium.Web.Proxy/ResponseHandler.cs
View file @
c706c9fa
...
@@ -67,14 +67,12 @@ namespace Titanium.Web.Proxy
...
@@ -67,14 +67,12 @@ namespace Titanium.Web.Proxy
//Write back to client 100-conitinue response if that's what server returned
//Write back to client 100-conitinue response if that's what server returned
if
(
args
.
WebSession
.
Response
.
Is100Continue
)
if
(
args
.
WebSession
.
Response
.
Is100Continue
)
{
{
await
WriteResponseStatus
(
args
.
WebSession
.
Response
.
HttpVersion
,
"100"
,
await
WriteResponseStatus
(
args
.
WebSession
.
Response
.
HttpVersion
,
"100"
,
"Continue"
,
args
.
ProxyClient
.
ClientStreamWriter
);
"Continue"
,
args
.
ProxyClient
.
ClientStreamWriter
);
await
args
.
ProxyClient
.
ClientStreamWriter
.
WriteLineAsync
();
await
args
.
ProxyClient
.
ClientStreamWriter
.
WriteLineAsync
();
}
}
else
if
(
args
.
WebSession
.
Response
.
ExpectationFailed
)
else
if
(
args
.
WebSession
.
Response
.
ExpectationFailed
)
{
{
await
WriteResponseStatus
(
args
.
WebSession
.
Response
.
HttpVersion
,
"417"
,
await
WriteResponseStatus
(
args
.
WebSession
.
Response
.
HttpVersion
,
"417"
,
"Expectation Failed"
,
args
.
ProxyClient
.
ClientStreamWriter
);
"Expectation Failed"
,
args
.
ProxyClient
.
ClientStreamWriter
);
await
args
.
ProxyClient
.
ClientStreamWriter
.
WriteLineAsync
();
await
args
.
ProxyClient
.
ClientStreamWriter
.
WriteLineAsync
();
}
}
...
@@ -110,20 +108,17 @@ namespace Titanium.Web.Proxy
...
@@ -110,20 +108,17 @@ namespace Titanium.Web.Proxy
//Write body only if response is chunked or content length >0
//Write body only if response is chunked or content length >0
//Is none are true then check if connection:close header exist, if so write response until server or client terminates the connection
//Is none are true then check if connection:close header exist, if so write response until server or client terminates the connection
if
(
args
.
WebSession
.
Response
.
IsChunked
||
args
.
WebSession
.
Response
.
ContentLength
>
0
if
(
args
.
WebSession
.
Response
.
IsChunked
||
args
.
WebSession
.
Response
.
ContentLength
>
0
||
!
args
.
WebSession
.
Response
.
ResponseKeepAlive
)
||
!
args
.
WebSession
.
Response
.
ResponseKeepAlive
)
{
{
await
args
.
WebSession
.
ServerConnection
.
StreamReader
await
args
.
WebSession
.
ServerConnection
.
StreamReader
.
WriteResponseBody
(
BufferSize
,
args
.
ProxyClient
.
ClientStream
,
.
WriteResponseBody
(
BufferSize
,
args
.
ProxyClient
.
ClientStream
,
args
.
WebSession
.
Response
.
IsChunked
,
args
.
WebSession
.
Response
.
IsChunked
,
args
.
WebSession
.
Response
.
ContentLength
);
args
.
WebSession
.
Response
.
ContentLength
);
}
}
//write response if connection:keep-alive header exist and when version is http/1.0
//write response if connection:keep-alive header exist and when version is http/1.0
//Because in Http 1.0 server can return a response without content-length (expectation being client would read until end of stream)
//Because in Http 1.0 server can return a response without content-length (expectation being client would read until end of stream)
else
if
(
args
.
WebSession
.
Response
.
ResponseKeepAlive
&&
args
.
WebSession
.
Response
.
HttpVersion
.
Minor
==
0
)
else
if
(
args
.
WebSession
.
Response
.
ResponseKeepAlive
&&
args
.
WebSession
.
Response
.
HttpVersion
.
Minor
==
0
)
{
{
await
args
.
WebSession
.
ServerConnection
.
StreamReader
await
args
.
WebSession
.
ServerConnection
.
StreamReader
.
WriteResponseBody
(
BufferSize
,
args
.
ProxyClient
.
ClientStream
,
.
WriteResponseBody
(
BufferSize
,
args
.
ProxyClient
.
ClientStream
,
args
.
WebSession
.
Response
.
IsChunked
,
args
.
WebSession
.
Response
.
IsChunked
,
args
.
WebSession
.
Response
.
ContentLength
);
args
.
WebSession
.
Response
.
ContentLength
);
}
}
}
}
...
@@ -132,8 +127,8 @@ namespace Titanium.Web.Proxy
...
@@ -132,8 +127,8 @@ namespace Titanium.Web.Proxy
catch
(
Exception
e
)
catch
(
Exception
e
)
{
{
ExceptionFunc
(
new
ProxyHttpException
(
"Error occured whilst handling session response"
,
e
,
args
));
ExceptionFunc
(
new
ProxyHttpException
(
"Error occured whilst handling session response"
,
e
,
args
));
Dispose
(
args
.
ProxyClient
.
ClientStream
,
args
.
ProxyClient
.
ClientStreamReader
,
Dispose
(
args
.
ProxyClient
.
ClientStream
,
args
.
ProxyClient
.
ClientStreamReader
,
args
.
ProxyClient
.
ClientStreamWriter
,
args
.
ProxyClient
.
ClientStreamWriter
,
args
.
WebSession
.
ServerConnection
);
args
.
WebSession
.
ServerConnection
);
return
true
;
return
true
;
}
}
...
@@ -162,8 +157,7 @@ namespace Titanium.Web.Proxy
...
@@ -162,8 +157,7 @@ namespace Titanium.Web.Proxy
/// <param name="description"></param>
/// <param name="description"></param>
/// <param name="responseWriter"></param>
/// <param name="responseWriter"></param>
/// <returns></returns>
/// <returns></returns>
private
async
Task
WriteResponseStatus
(
Version
version
,
string
code
,
string
description
,
private
async
Task
WriteResponseStatus
(
Version
version
,
string
code
,
string
description
,
StreamWriter
responseWriter
)
StreamWriter
responseWriter
)
{
{
await
responseWriter
.
WriteLineAsync
(
$"HTTP/
{
version
.
Major
}
.
{
version
.
Minor
}
{
code
}
{
description
}
"
);
await
responseWriter
.
WriteLineAsync
(
$"HTTP/
{
version
.
Major
}
.
{
version
.
Minor
}
{
code
}
{
description
}
"
);
}
}
...
@@ -231,10 +225,7 @@ namespace Titanium.Web.Proxy
...
@@ -231,10 +225,7 @@ namespace Titanium.Web.Proxy
/// <param name="clientStreamReader"></param>
/// <param name="clientStreamReader"></param>
/// <param name="clientStreamWriter"></param>
/// <param name="clientStreamWriter"></param>
/// <param name="serverConnection"></param>
/// <param name="serverConnection"></param>
private
void
Dispose
(
Stream
clientStream
,
private
void
Dispose
(
Stream
clientStream
,
CustomBinaryReader
clientStreamReader
,
StreamWriter
clientStreamWriter
,
TcpConnection
serverConnection
)
CustomBinaryReader
clientStreamReader
,
StreamWriter
clientStreamWriter
,
TcpConnection
serverConnection
)
{
{
clientStream
?.
Close
();
clientStream
?.
Close
();
clientStream
?.
Dispose
();
clientStream
?.
Dispose
();
...
...
Titanium.Web.Proxy/Shared/ProxyConstants.cs
View file @
c706c9fa
...
@@ -16,8 +16,7 @@ namespace Titanium.Web.Proxy.Shared
...
@@ -16,8 +16,7 @@ namespace Titanium.Web.Proxy.Shared
internal
static
readonly
byte
[]
NewLineBytes
=
Encoding
.
ASCII
.
GetBytes
(
NewLine
);
internal
static
readonly
byte
[]
NewLineBytes
=
Encoding
.
ASCII
.
GetBytes
(
NewLine
);
internal
static
readonly
byte
[]
ChunkEnd
=
internal
static
readonly
byte
[]
ChunkEnd
=
Encoding
.
ASCII
.
GetBytes
(
0.
ToString
(
"x2"
)
+
NewLine
+
NewLine
);
Encoding
.
ASCII
.
GetBytes
(
0.
ToString
(
"x2"
)
+
NewLine
+
NewLine
);
internal
const
string
NewLine
=
"\r\n"
;
internal
const
string
NewLine
=
"\r\n"
;
}
}
...
...
Titanium.Web.Proxy/WinAuthHandler.cs
View file @
c706c9fa
...
@@ -43,10 +43,9 @@ namespace Titanium.Web.Proxy
...
@@ -43,10 +43,9 @@ namespace Titanium.Web.Proxy
HttpHeader
authHeader
=
null
;
HttpHeader
authHeader
=
null
;
//check in non-unique headers first
//check in non-unique headers first
var
header
=
args
.
WebSession
.
Response
var
header
=
.
NonUniqueResponseHeaders
args
.
WebSession
.
Response
.
NonUniqueResponseHeaders
.
FirstOrDefault
(
.
FirstOrDefault
(
x
=>
x
=>
authHeaderNames
.
Any
(
y
=>
x
.
Key
.
Equals
(
y
,
StringComparison
.
OrdinalIgnoreCase
)));
authHeaderNames
.
Any
(
y
=>
x
.
Key
.
Equals
(
y
,
StringComparison
.
OrdinalIgnoreCase
)));
if
(!
header
.
Equals
(
new
KeyValuePair
<
string
,
List
<
HttpHeader
>>()))
if
(!
header
.
Equals
(
new
KeyValuePair
<
string
,
List
<
HttpHeader
>>()))
{
{
...
@@ -55,8 +54,7 @@ namespace Titanium.Web.Proxy
...
@@ -55,8 +54,7 @@ namespace Titanium.Web.Proxy
if
(
headerName
!=
null
)
if
(
headerName
!=
null
)
{
{
authHeader
=
args
.
WebSession
.
Response
authHeader
=
args
.
WebSession
.
Response
.
NonUniqueResponseHeaders
[
headerName
]
.
NonUniqueResponseHeaders
[
headerName
]
.
FirstOrDefault
(
x
=>
authSchemes
.
Any
(
y
=>
x
.
Value
.
StartsWith
(
y
,
StringComparison
.
OrdinalIgnoreCase
)));
.
FirstOrDefault
(
x
=>
authSchemes
.
Any
(
y
=>
x
.
Value
.
StartsWith
(
y
,
StringComparison
.
OrdinalIgnoreCase
)));
}
}
...
@@ -64,10 +62,8 @@ namespace Titanium.Web.Proxy
...
@@ -64,10 +62,8 @@ namespace Titanium.Web.Proxy
if
(
authHeader
==
null
)
if
(
authHeader
==
null
)
{
{
//check in non-unique headers first
//check in non-unique headers first
var
uHeader
=
args
.
WebSession
.
Response
var
uHeader
=
.
ResponseHeaders
args
.
WebSession
.
Response
.
ResponseHeaders
.
FirstOrDefault
(
x
=>
authHeaderNames
.
Any
(
y
=>
x
.
Key
.
Equals
(
y
,
StringComparison
.
OrdinalIgnoreCase
)));
.
FirstOrDefault
(
x
=>
authHeaderNames
.
Any
(
y
=>
x
.
Key
.
Equals
(
y
,
StringComparison
.
OrdinalIgnoreCase
)));
if
(!
uHeader
.
Equals
(
new
KeyValuePair
<
string
,
HttpHeader
>()))
if
(!
uHeader
.
Equals
(
new
KeyValuePair
<
string
,
HttpHeader
>()))
{
{
...
@@ -76,8 +72,8 @@ namespace Titanium.Web.Proxy
...
@@ -76,8 +72,8 @@ namespace Titanium.Web.Proxy
if
(
headerName
!=
null
)
if
(
headerName
!=
null
)
{
{
authHeader
=
authSchemes
.
Any
(
x
=>
args
.
WebSession
.
Response
authHeader
=
authSchemes
.
Any
(
x
=>
args
.
WebSession
.
Response
.
ResponseHeaders
[
headerName
].
Value
.
ResponseHeaders
[
headerName
].
Value
.
StartsWith
(
x
,
StringComparison
.
OrdinalIgnoreCase
))
.
StartsWith
(
x
,
StringComparison
.
OrdinalIgnoreCase
))
?
args
.
WebSession
.
Response
.
ResponseHeaders
[
headerName
]
?
args
.
WebSession
.
Response
.
ResponseHeaders
[
headerName
]
:
null
;
:
null
;
}
}
...
@@ -119,21 +115,19 @@ namespace Titanium.Web.Proxy
...
@@ -119,21 +115,19 @@ namespace Titanium.Web.Proxy
//challenge value will start with any of the scheme selected
//challenge value will start with any of the scheme selected
else
else
{
{
scheme
=
authSchemes
.
FirstOrDefault
(
x
=>
authHeader
.
Value
.
StartsWith
(
x
,
StringComparison
.
OrdinalIgnoreCase
)
scheme
=
authSchemes
.
FirstOrDefault
(
x
=>
authHeader
.
Value
.
StartsWith
(
x
,
StringComparison
.
OrdinalIgnoreCase
)
&&
&&
authHeader
.
Value
.
Length
>
x
.
Length
+
1
);
authHeader
.
Value
.
Length
>
x
.
Length
+
1
);
var
serverToken
=
authHeader
.
Value
.
Substring
(
scheme
.
Length
+
1
);
var
serverToken
=
authHeader
.
Value
.
Substring
(
scheme
.
Length
+
1
);
var
clientToken
=
WinAuthHandler
.
GetFinalAuthToken
(
args
.
WebSession
.
Request
.
Host
,
serverToken
,
args
.
Id
);
var
clientToken
=
WinAuthHandler
.
GetFinalAuthToken
(
args
.
WebSession
.
Request
.
Host
,
serverToken
,
args
.
Id
);
//there will be an existing header from initial client request
//there will be an existing header from initial client request
args
.
WebSession
.
Request
.
RequestHeaders
[
"Authorization"
]
args
.
WebSession
.
Request
.
RequestHeaders
[
"Authorization"
]
=
new
HttpHeader
(
"Authorization"
,
string
.
Concat
(
scheme
,
clientToken
));
=
new
HttpHeader
(
"Authorization"
,
string
.
Concat
(
scheme
,
clientToken
));
//send body for final auth request
//send body for final auth request
if
(
args
.
WebSession
.
Request
.
HasBody
)
if
(
args
.
WebSession
.
Request
.
HasBody
)
{
{
args
.
WebSession
.
Request
.
ContentLength
args
.
WebSession
.
Request
.
ContentLength
=
args
.
WebSession
.
Request
.
RequestBody
.
Length
;
=
args
.
WebSession
.
Request
.
RequestBody
.
Length
;
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment