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
e928c25a
Commit
e928c25a
authored
May 12, 2017
by
Jehonathan Thomas
Committed by
GitHub
May 12, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #215 from justcoding121/develop
Beta merge
parents
b62f9f14
e7b254f1
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
491 additions
and
375 deletions
+491
-375
Program.cs
Examples/Titanium.Web.Proxy.Examples.Basic/Program.cs
+4
-4
ProxyTestController.cs
.../Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
+6
-4
README.md
README.md
+1
-1
CertificateManagerTests.cs
...s/Titanium.Web.Proxy.UnitTests/CertificateManagerTests.cs
+1
-1
CertificateHandler.cs
Titanium.Web.Proxy/CertificateHandler.cs
+2
-2
ByteArrayExtensions.cs
Titanium.Web.Proxy/Extensions/ByteArrayExtensions.cs
+2
-2
Firefox.cs
Titanium.Web.Proxy/Helpers/Firefox.cs
+3
-3
Network.cs
Titanium.Web.Proxy/Helpers/Network.cs
+80
-42
EndPoint.cs
Titanium.Web.Proxy/Models/EndPoint.cs
+6
-6
ExternalProxy.cs
Titanium.Web.Proxy/Models/ExternalProxy.cs
+10
-5
BCCertificateMaker.cs
Titanium.Web.Proxy/Network/Certificate/BCCertificateMaker.cs
+4
-4
WinCertificateMaker.cs
...nium.Web.Proxy/Network/Certificate/WinCertificateMaker.cs
+40
-40
CertificateManager.cs
Titanium.Web.Proxy/Network/CertificateManager.cs
+35
-11
ProxyClient.cs
Titanium.Web.Proxy/Network/ProxyClient.cs
+1
-1
TcpConnection.cs
Titanium.Web.Proxy/Network/Tcp/TcpConnection.cs
+1
-1
TcpConnectionFactory.cs
Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
+153
-152
TcpRow.cs
Titanium.Web.Proxy/Network/Tcp/TcpRow.cs
+7
-7
TcpTable.cs
Titanium.Web.Proxy/Network/Tcp/TcpTable.cs
+2
-2
ProxyServer.cs
Titanium.Web.Proxy/ProxyServer.cs
+122
-76
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+8
-8
ResponseHandler.cs
Titanium.Web.Proxy/ResponseHandler.cs
+3
-3
No files found.
Examples/Titanium.Web.Proxy.Examples.Basic/Program.cs
View file @
e928c25a
...
...
@@ -5,7 +5,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
{
public
class
Program
{
private
static
readonly
ProxyTestController
C
ontroller
=
new
ProxyTestController
();
private
static
readonly
ProxyTestController
c
ontroller
=
new
ProxyTestController
();
public
static
void
Main
(
string
[]
args
)
{
...
...
@@ -15,13 +15,13 @@ namespace Titanium.Web.Proxy.Examples.Basic
//Start proxy controller
C
ontroller
.
StartProxy
();
c
ontroller
.
StartProxy
();
Console
.
WriteLine
(
"Hit any key to exit.."
);
Console
.
WriteLine
();
Console
.
Read
();
C
ontroller
.
Stop
();
c
ontroller
.
Stop
();
}
...
...
@@ -30,7 +30,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
if
(
eventType
!=
2
)
return
false
;
try
{
C
ontroller
.
Stop
();
c
ontroller
.
Stop
();
}
catch
{
...
...
Examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
View file @
e928c25a
using
System
;
using
System.Collections.Generic
;
using
System.Net
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Models
;
...
...
@@ -9,10 +10,10 @@ namespace Titanium.Web.Proxy.Examples.Basic
{
public
class
ProxyTestController
{
private
ProxyServer
proxyServer
;
private
readonly
ProxyServer
proxyServer
;
//share requestBody outside handlers
private
Dictionary
<
Guid
,
string
>
requestBodyHistory
;
private
readonly
Dictionary
<
Guid
,
string
>
requestBodyHistory
=
new
Dictionary
<
Guid
,
string
>()
;
public
ProxyTestController
()
{
...
...
@@ -23,7 +24,8 @@ namespace Titanium.Web.Proxy.Examples.Basic
//Under Mono only BouncyCastle will be supported
//proxyServer.CertificateEngine = Network.CertificateEngine.BouncyCastle;
requestBodyHistory
=
new
Dictionary
<
Guid
,
string
>();
//optionally set the Root Certificate
//proxyServer.RootCertificate = new X509Certificate2("myCert.pfx", string.Empty, X509KeyStorageFlags.Exportable);
}
public
void
StartProxy
()
...
...
README.md
View file @
e928c25a
...
...
@@ -112,7 +112,7 @@ Sample request and response event handlers
```
csharp
//To access requestBody from OnResponse handler
private
Dictionary
<
Guid
,
string
>
requestBodyHistory
;
private
Dictionary
<
Guid
,
string
>
requestBodyHistory
=
new
Dictionary
<
Guid
,
string
>()
;
public
async
Task
OnRequest
(
object
sender
,
SessionEventArgs
e
)
{
...
...
Tests/Titanium.Web.Proxy.UnitTests/CertificateManagerTests.cs
View file @
e928c25a
...
...
@@ -9,7 +9,7 @@ namespace Titanium.Web.Proxy.UnitTests
[
TestClass
]
public
class
CertificateManagerTests
{
private
readonly
static
string
[]
hostNames
private
static
readonly
string
[]
hostNames
=
new
string
[]
{
"facebook.com"
,
"youtube.com"
,
"google.com"
,
"bing.com"
,
"yahoo.com"
};
...
...
Titanium.Web.Proxy/CertificateHandler.cs
View file @
e928c25a
...
...
@@ -16,7 +16,7 @@ namespace Titanium.Web.Proxy
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns></returns>
internal
bool
ValidateServerCertificate
(
private
bool
ValidateServerCertificate
(
object
sender
,
X509Certificate
certificate
,
X509Chain
chain
,
...
...
@@ -66,7 +66,7 @@ namespace Titanium.Web.Proxy
/// <param name="remoteCertificate"></param>
/// <param name="acceptableIssuers"></param>
/// <returns></returns>
internal
X509Certificate
SelectClientCertificate
(
private
X509Certificate
SelectClientCertificate
(
object
sender
,
string
targetHost
,
X509CertificateCollection
localCertificates
,
...
...
Titanium.Web.Proxy/Extensions/ByteArrayExtensions.cs
View file @
e928c25a
...
...
@@ -5,7 +5,7 @@ namespace Titanium.Web.Proxy.Extensions
/// <summary>
/// Extension methods for Byte Arrays.
/// </summary>
public
static
class
ByteArrayExtensions
internal
static
class
ByteArrayExtensions
{
/// <summary>
/// Get the sub array from byte of data
...
...
@@ -15,7 +15,7 @@ namespace Titanium.Web.Proxy.Extensions
/// <param name="index"></param>
/// <param name="length"></param>
/// <returns></returns>
public
static
T
[]
SubArray
<
T
>(
this
T
[]
data
,
int
index
,
int
length
)
internal
static
T
[]
SubArray
<
T
>(
this
T
[]
data
,
int
index
,
int
length
)
{
var
result
=
new
T
[
length
];
Array
.
Copy
(
data
,
index
,
result
,
0
,
length
);
...
...
Titanium.Web.Proxy/Helpers/Firefox.cs
View file @
e928c25a
...
...
@@ -6,12 +6,12 @@ namespace Titanium.Web.Proxy.Helpers
/// <summary>
/// A helper class to set proxy settings for firefox
/// </summary>
public
class
FireFoxProxySettingsManager
internal
class
FireFoxProxySettingsManager
{
/// <summary>
/// Add Firefox settings.
/// </summary>
public
void
AddFirefox
()
internal
void
AddFirefox
()
{
try
{
...
...
@@ -40,7 +40,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <summary>
/// Remove firefox settings.
/// </summary>
public
void
RemoveFirefox
()
internal
void
RemoveFirefox
()
{
try
{
...
...
Titanium.Web.Proxy/Helpers/Network.cs
View file @
e928c25a
using
System.Linq
;
using
System.Net
;
using
System.Net.Sockets
;
namespace
Titanium.Web.Proxy.Helpers
{
...
...
@@ -38,5 +39,42 @@ namespace Titanium.Web.Proxy.Helpers
// test if any host IP equals to any local IP or to localhost
return
IPAddress
.
IsLoopback
(
address
)
||
localIPs
.
Contains
(
address
);
}
internal
static
bool
IsLocalIpAddress
(
string
hostName
)
{
bool
isLocalhost
=
false
;
IPHostEntry
localhost
=
Dns
.
GetHostEntry
(
"127.0.0.1"
);
if
(
hostName
==
localhost
.
HostName
)
{
IPHostEntry
hostEntry
=
Dns
.
GetHostEntry
(
hostName
);
isLocalhost
=
hostEntry
.
AddressList
.
Any
(
IPAddress
.
IsLoopback
);
}
if
(!
isLocalhost
)
{
localhost
=
Dns
.
GetHostEntry
(
Dns
.
GetHostName
());
IPAddress
ipAddress
=
null
;
if
(
IPAddress
.
TryParse
(
hostName
,
out
ipAddress
))
isLocalhost
=
localhost
.
AddressList
.
Any
(
x
=>
x
.
Equals
(
ipAddress
));
if
(!
isLocalhost
)
{
try
{
var
hostEntry
=
Dns
.
GetHostEntry
(
hostName
);
isLocalhost
=
localhost
.
AddressList
.
Any
(
x
=>
hostEntry
.
AddressList
.
Any
(
x
.
Equals
));
}
catch
(
SocketException
)
{
}
}
}
return
isLocalhost
;
}
}
}
Titanium.Web.Proxy/Models/EndPoint.cs
View file @
e928c25a
...
...
@@ -53,8 +53,8 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
public
class
ExplicitProxyEndPoint
:
ProxyEndPoint
{
private
List
<
string
>
_
excludedHttpsHostNameRegex
;
private
List
<
string
>
_
includedHttpsHostNameRegex
;
private
List
<
string
>
excludedHttpsHostNameRegex
;
private
List
<
string
>
includedHttpsHostNameRegex
;
internal
bool
IsSystemHttpProxy
{
get
;
set
;
}
...
...
@@ -65,7 +65,7 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
public
List
<
string
>
ExcludedHttpsHostNameRegex
{
get
{
return
_
excludedHttpsHostNameRegex
;
}
get
{
return
excludedHttpsHostNameRegex
;
}
set
{
if
(
IncludedHttpsHostNameRegex
!=
null
)
...
...
@@ -73,7 +73,7 @@ namespace Titanium.Web.Proxy.Models
throw
new
ArgumentException
(
"Cannot set excluded when included is set"
);
}
_
excludedHttpsHostNameRegex
=
value
;
excludedHttpsHostNameRegex
=
value
;
}
}
...
...
@@ -82,7 +82,7 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
public
List
<
string
>
IncludedHttpsHostNameRegex
{
get
{
return
_
includedHttpsHostNameRegex
;
}
get
{
return
includedHttpsHostNameRegex
;
}
set
{
if
(
ExcludedHttpsHostNameRegex
!=
null
)
...
...
@@ -90,7 +90,7 @@ namespace Titanium.Web.Proxy.Models
throw
new
ArgumentException
(
"Cannot set included when excluded is set"
);
}
_
includedHttpsHostNameRegex
=
value
;
includedHttpsHostNameRegex
=
value
;
}
}
...
...
Titanium.Web.Proxy/Models/ExternalProxy.cs
View file @
e928c25a
...
...
@@ -8,7 +8,7 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
public
class
ExternalProxy
{
private
static
readonly
Lazy
<
NetworkCredential
>
D
efaultCredentials
=
new
Lazy
<
NetworkCredential
>(()
=>
CredentialCache
.
DefaultNetworkCredentials
);
private
static
readonly
Lazy
<
NetworkCredential
>
d
efaultCredentials
=
new
Lazy
<
NetworkCredential
>(()
=>
CredentialCache
.
DefaultNetworkCredentials
);
private
string
userName
;
private
string
password
;
...
...
@@ -18,16 +18,21 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
public
bool
UseDefaultCredentials
{
get
;
set
;
}
/// <summary>
/// Bypass this proxy for connections to localhost?
/// </summary>
public
bool
BypassForLocalhost
{
get
;
set
;
}
/// <summary>
/// Username.
/// </summary>
public
string
UserName
{
get
{
return
UseDefaultCredentials
?
D
efaultCredentials
.
Value
.
UserName
:
userName
;
}
get
{
return
UseDefaultCredentials
?
d
efaultCredentials
.
Value
.
UserName
:
userName
;
}
set
{
userName
=
value
;
if
(
D
efaultCredentials
.
Value
.
UserName
!=
userName
)
if
(
d
efaultCredentials
.
Value
.
UserName
!=
userName
)
{
UseDefaultCredentials
=
false
;
}
...
...
@@ -39,12 +44,12 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
public
string
Password
{
get
{
return
UseDefaultCredentials
?
D
efaultCredentials
.
Value
.
Password
:
password
;
}
get
{
return
UseDefaultCredentials
?
d
efaultCredentials
.
Value
.
Password
:
password
;
}
set
{
password
=
value
;
if
(
D
efaultCredentials
.
Value
.
Password
!=
password
)
if
(
d
efaultCredentials
.
Value
.
Password
!=
password
)
{
UseDefaultCredentials
=
false
;
}
...
...
Titanium.Web.Proxy/Network/Certificate/BCCertificateMaker.cs
View file @
e928c25a
...
...
@@ -21,10 +21,10 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// <summary>
/// Implements certificate generation operations.
/// </summary>
public
class
BCCertificateMaker
:
ICertificateMaker
internal
class
BCCertificateMaker
:
ICertificateMaker
{
private
const
int
C
ertificateValidDays
=
1825
;
private
const
int
C
ertificateGraceDays
=
366
;
private
const
int
c
ertificateValidDays
=
1825
;
private
const
int
c
ertificateGraceDays
=
366
;
/// <summary>
/// Makes the certificate.
...
...
@@ -187,7 +187,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
return
certificate
;
}
return
MakeCertificateInternal
(
isRoot
,
subject
,
$"CN=
{
subject
}
"
,
DateTime
.
UtcNow
.
AddDays
(-
CertificateGraceDays
),
DateTime
.
UtcNow
.
AddDays
(
C
ertificateValidDays
),
isRoot
?
null
:
signingCert
);
return
MakeCertificateInternal
(
isRoot
,
subject
,
$"CN=
{
subject
}
"
,
DateTime
.
UtcNow
.
AddDays
(-
certificateGraceDays
),
DateTime
.
UtcNow
.
AddDays
(
c
ertificateValidDays
),
isRoot
?
null
:
signingCert
);
}
}
...
...
Titanium.Web.Proxy/Network/Certificate/WinCertificateMaker.cs
View file @
e928c25a
...
...
@@ -10,7 +10,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// Certificate Maker - uses MakeCert
/// Calls COM objects using reflection
/// </summary>
public
class
WinCertificateMaker
:
ICertificateMaker
internal
class
WinCertificateMaker
:
ICertificateMaker
{
private
readonly
Type
typeX500DN
;
...
...
@@ -42,12 +42,12 @@ namespace Titanium.Web.Proxy.Network.Certificate
private
readonly
string
sProviderName
=
"Microsoft Enhanced Cryptographic Provider v1.0"
;
private
object
_S
haredPrivateKey
;
private
object
s
haredPrivateKey
;
/// <summary>
/// Constructor.
/// </summary>
public
WinCertificateMaker
()
internal
WinCertificateMaker
()
{
typeX500DN
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX500DistinguishedName"
,
true
);
typeX509PrivateKey
=
Type
.
GetTypeFromProgID
(
"X509Enrollment.CX509PrivateKey"
,
true
);
...
...
@@ -105,7 +105,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
if
(!
isRoot
)
{
sharedPrivateKey
=
_S
haredPrivateKey
;
sharedPrivateKey
=
this
.
s
haredPrivateKey
;
}
if
(
sharedPrivateKey
==
null
)
...
...
@@ -130,52 +130,52 @@ namespace Titanium.Web.Proxy.Network.Certificate
if
(!
isRoot
)
{
_S
haredPrivateKey
=
sharedPrivateKey
;
this
.
s
haredPrivateKey
=
sharedPrivateKey
;
}
}
typeValue
=
new
object
[
1
];
var
OID
=
Activator
.
CreateInstance
(
typeOID
);
var
oid
=
Activator
.
CreateInstance
(
typeOID
);
typeValue
[
0
]
=
"1.3.6.1.5.5.7.3.1"
;
typeOID
.
InvokeMember
(
"InitializeFromValue"
,
BindingFlags
.
InvokeMethod
,
null
,
OID
,
typeValue
);
typeOID
.
InvokeMember
(
"InitializeFromValue"
,
BindingFlags
.
InvokeMethod
,
null
,
oid
,
typeValue
);
var
OIDS
=
Activator
.
CreateInstance
(
typeOIDS
);
typeValue
[
0
]
=
OID
;
typeOIDS
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
OIDS
,
typeValue
);
var
oids
=
Activator
.
CreateInstance
(
typeOIDS
);
typeValue
[
0
]
=
oid
;
typeOIDS
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
oids
,
typeValue
);
var
EKU
Ext
=
Activator
.
CreateInstance
(
typeEKUExt
);
typeValue
[
0
]
=
OIDS
;
typeEKUExt
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
EKU
Ext
,
typeValue
);
var
eku
Ext
=
Activator
.
CreateInstance
(
typeEKUExt
);
typeValue
[
0
]
=
oids
;
typeEKUExt
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
eku
Ext
,
typeValue
);
var
R
equestCert
=
Activator
.
CreateInstance
(
typeRequestCert
);
var
r
equestCert
=
Activator
.
CreateInstance
(
typeRequestCert
);
typeValue
=
new
[]
{
1
,
sharedPrivateKey
,
string
.
Empty
};
typeRequestCert
.
InvokeMember
(
"InitializeFromPrivateKey"
,
BindingFlags
.
InvokeMethod
,
null
,
R
equestCert
,
typeValue
);
typeRequestCert
.
InvokeMember
(
"InitializeFromPrivateKey"
,
BindingFlags
.
InvokeMethod
,
null
,
r
equestCert
,
typeValue
);
typeValue
=
new
[]
{
x500CertDN
};
typeRequestCert
.
InvokeMember
(
"Subject"
,
BindingFlags
.
PutDispProperty
,
null
,
R
equestCert
,
typeValue
);
typeRequestCert
.
InvokeMember
(
"Subject"
,
BindingFlags
.
PutDispProperty
,
null
,
r
equestCert
,
typeValue
);
typeValue
[
0
]
=
x500RootCertDN
;
typeRequestCert
.
InvokeMember
(
"Issuer"
,
BindingFlags
.
PutDispProperty
,
null
,
R
equestCert
,
typeValue
);
typeRequestCert
.
InvokeMember
(
"Issuer"
,
BindingFlags
.
PutDispProperty
,
null
,
r
equestCert
,
typeValue
);
typeValue
[
0
]
=
validFrom
;
typeRequestCert
.
InvokeMember
(
"NotBefore"
,
BindingFlags
.
PutDispProperty
,
null
,
R
equestCert
,
typeValue
);
typeRequestCert
.
InvokeMember
(
"NotBefore"
,
BindingFlags
.
PutDispProperty
,
null
,
r
equestCert
,
typeValue
);
typeValue
[
0
]
=
validTo
;
typeRequestCert
.
InvokeMember
(
"NotAfter"
,
BindingFlags
.
PutDispProperty
,
null
,
R
equestCert
,
typeValue
);
typeRequestCert
.
InvokeMember
(
"NotAfter"
,
BindingFlags
.
PutDispProperty
,
null
,
r
equestCert
,
typeValue
);
var
KU
Ext
=
Activator
.
CreateInstance
(
typeKUExt
);
var
ku
Ext
=
Activator
.
CreateInstance
(
typeKUExt
);
typeValue
[
0
]
=
176
;
typeKUExt
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
KU
Ext
,
typeValue
);
typeKUExt
.
InvokeMember
(
"InitializeEncode"
,
BindingFlags
.
InvokeMethod
,
null
,
ku
Ext
,
typeValue
);
var
certificate
=
typeRequestCert
.
InvokeMember
(
"X509Extensions"
,
BindingFlags
.
GetProperty
,
null
,
R
equestCert
,
null
);
var
certificate
=
typeRequestCert
.
InvokeMember
(
"X509Extensions"
,
BindingFlags
.
GetProperty
,
null
,
r
equestCert
,
null
);
typeValue
=
new
object
[
1
];
if
(!
isRoot
)
{
typeValue
[
0
]
=
KU
Ext
;
typeValue
[
0
]
=
ku
Ext
;
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
certificate
,
typeValue
);
}
typeValue
[
0
]
=
EKU
Ext
;
typeValue
[
0
]
=
eku
Ext
;
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
certificate
,
typeValue
);
if
(!
isRoot
)
...
...
@@ -203,12 +203,12 @@ namespace Titanium.Web.Proxy.Network.Certificate
if
(!
isRoot
)
{
var
S
ignerCertificate
=
Activator
.
CreateInstance
(
typeSignerCertificate
);
var
s
ignerCertificate
=
Activator
.
CreateInstance
(
typeSignerCertificate
);
typeValue
=
new
object
[]
{
0
,
0
,
12
,
signingCertificate
.
Thumbprint
};
typeSignerCertificate
.
InvokeMember
(
"Initialize"
,
BindingFlags
.
InvokeMethod
,
null
,
S
ignerCertificate
,
typeValue
);
typeValue
=
new
[]
{
S
ignerCertificate
};
typeRequestCert
.
InvokeMember
(
"SignerCertificate"
,
BindingFlags
.
PutDispProperty
,
null
,
R
equestCert
,
typeValue
);
typeSignerCertificate
.
InvokeMember
(
"Initialize"
,
BindingFlags
.
InvokeMethod
,
null
,
s
ignerCertificate
,
typeValue
);
typeValue
=
new
[]
{
s
ignerCertificate
};
typeRequestCert
.
InvokeMember
(
"SignerCertificate"
,
BindingFlags
.
PutDispProperty
,
null
,
r
equestCert
,
typeValue
);
}
else
{
...
...
@@ -220,24 +220,24 @@ namespace Titanium.Web.Proxy.Network.Certificate
typeX509Extensions
.
InvokeMember
(
"Add"
,
BindingFlags
.
InvokeMethod
,
null
,
certificate
,
typeValue
);
}
OID
=
Activator
.
CreateInstance
(
typeOID
);
oid
=
Activator
.
CreateInstance
(
typeOID
);
typeValue
=
new
object
[]
{
1
,
0
,
0
,
hashAlg
};
typeOID
.
InvokeMember
(
"InitializeFromAlgorithmName"
,
BindingFlags
.
InvokeMethod
,
null
,
OID
,
typeValue
);
typeOID
.
InvokeMember
(
"InitializeFromAlgorithmName"
,
BindingFlags
.
InvokeMethod
,
null
,
oid
,
typeValue
);
typeValue
=
new
[]
{
OID
};
typeRequestCert
.
InvokeMember
(
"HashAlgorithm"
,
BindingFlags
.
PutDispProperty
,
null
,
R
equestCert
,
typeValue
);
typeRequestCert
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
R
equestCert
,
null
);
typeValue
=
new
[]
{
oid
};
typeRequestCert
.
InvokeMember
(
"HashAlgorithm"
,
BindingFlags
.
PutDispProperty
,
null
,
r
equestCert
,
typeValue
);
typeRequestCert
.
InvokeMember
(
"Encode"
,
BindingFlags
.
InvokeMethod
,
null
,
r
equestCert
,
null
);
var
X
509Enrollment
=
Activator
.
CreateInstance
(
typeX509Enrollment
);
var
x
509Enrollment
=
Activator
.
CreateInstance
(
typeX509Enrollment
);
typeValue
[
0
]
=
R
equestCert
;
typeX509Enrollment
.
InvokeMember
(
"InitializeFromRequest"
,
BindingFlags
.
InvokeMethod
,
null
,
X
509Enrollment
,
typeValue
);
typeValue
[
0
]
=
r
equestCert
;
typeX509Enrollment
.
InvokeMember
(
"InitializeFromRequest"
,
BindingFlags
.
InvokeMethod
,
null
,
x
509Enrollment
,
typeValue
);
if
(
isRoot
)
{
typeValue
[
0
]
=
fullSubject
;
typeX509Enrollment
.
InvokeMember
(
"CertificateFriendlyName"
,
BindingFlags
.
PutDispProperty
,
null
,
X
509Enrollment
,
typeValue
);
typeX509Enrollment
.
InvokeMember
(
"CertificateFriendlyName"
,
BindingFlags
.
PutDispProperty
,
null
,
x
509Enrollment
,
typeValue
);
}
...
...
@@ -245,15 +245,15 @@ namespace Titanium.Web.Proxy.Network.Certificate
typeValue
[
0
]
=
0
;
var
createCertRequest
=
typeX509Enrollment
.
InvokeMember
(
"CreateRequest"
,
BindingFlags
.
InvokeMethod
,
null
,
X
509Enrollment
,
typeValue
);
var
createCertRequest
=
typeX509Enrollment
.
InvokeMember
(
"CreateRequest"
,
BindingFlags
.
InvokeMethod
,
null
,
x
509Enrollment
,
typeValue
);
typeValue
=
new
[]
{
2
,
createCertRequest
,
0
,
string
.
Empty
};
typeX509Enrollment
.
InvokeMember
(
"InstallResponse"
,
BindingFlags
.
InvokeMethod
,
null
,
X
509Enrollment
,
typeValue
);
typeX509Enrollment
.
InvokeMember
(
"InstallResponse"
,
BindingFlags
.
InvokeMethod
,
null
,
x
509Enrollment
,
typeValue
);
typeValue
=
new
object
[]
{
null
,
0
,
1
};
try
{
var
empty
=
(
string
)
typeX509Enrollment
.
InvokeMember
(
"CreatePFX"
,
BindingFlags
.
InvokeMethod
,
null
,
X
509Enrollment
,
typeValue
);
var
empty
=
(
string
)
typeX509Enrollment
.
InvokeMember
(
"CreatePFX"
,
BindingFlags
.
InvokeMethod
,
null
,
x
509Enrollment
,
typeValue
);
return
new
X509Certificate2
(
Convert
.
FromBase64String
(
empty
),
string
.
Empty
,
X509KeyStorageFlags
.
Exportable
);
}
catch
(
Exception
)
...
...
Titanium.Web.Proxy/Network/CertificateManager.cs
View file @
e928c25a
...
...
@@ -31,6 +31,10 @@ namespace Titanium.Web.Proxy.Network
/// </summary>
internal
class
CertificateManager
:
IDisposable
{
private
const
string
defaultRootCertificateIssuer
=
"Titanium"
;
private
const
string
defaultRootRootCertificateName
=
"Titanium Root Certificate Authority"
;
private
readonly
ICertificateMaker
certEngine
;
private
bool
clearCertificates
{
get
;
set
;
}
...
...
@@ -66,8 +70,8 @@ namespace Titanium.Web.Proxy.Network
certEngine
=
new
WinCertificateMaker
();
}
Issuer
=
issuer
;
RootCertificateName
=
rootCertificateName
;
Issuer
=
issuer
??
defaultRootCertificateIssuer
;
RootCertificateName
=
rootCertificateName
??
defaultRootRootCertificateName
;
certificateCache
=
new
ConcurrentDictionary
<
string
,
CachedCertificate
>();
}
...
...
@@ -88,7 +92,7 @@ namespace Titanium.Web.Proxy.Network
return
fileName
;
}
internal
X509Certificate2
Get
RootCertificate
()
internal
X509Certificate2
Load
RootCertificate
()
{
var
fileName
=
GetRootCertificatePath
();
if
(!
File
.
Exists
(
fileName
))
return
null
;
...
...
@@ -108,11 +112,16 @@ namespace Titanium.Web.Proxy.Network
/// <returns>true if succeeded, else false</returns>
internal
bool
CreateTrustedRootCertificate
()
{
RootCertificate
=
GetRootCertificate
();
if
(
RootCertificate
==
null
)
{
RootCertificate
=
LoadRootCertificate
();
}
if
(
RootCertificate
!=
null
)
{
return
true
;
}
try
{
RootCertificate
=
CreateCertificate
(
RootCertificateName
,
true
);
...
...
@@ -121,6 +130,7 @@ namespace Titanium.Web.Proxy.Network
{
exceptionFunc
(
e
);
}
if
(
RootCertificate
!=
null
)
{
try
...
...
@@ -133,9 +143,23 @@ namespace Titanium.Web.Proxy.Network
exceptionFunc
(
e
);
}
}
return
RootCertificate
!=
null
;
}
/// <summary>
/// Trusts the root certificate.
/// </summary>
/// <param name="exceptionFunc"></param>
internal
void
TrustRootCertificate
(
Action
<
Exception
>
exceptionFunc
)
{
//current user
TrustRootCertificate
(
StoreLocation
.
CurrentUser
,
exceptionFunc
);
//current system
TrustRootCertificate
(
StoreLocation
.
LocalMachine
,
exceptionFunc
);
}
/// <summary>
/// Create an SSL certificate
/// </summary>
...
...
@@ -144,7 +168,6 @@ namespace Titanium.Web.Proxy.Network
/// <returns></returns>
internal
virtual
X509Certificate2
CreateCertificate
(
string
certificateName
,
bool
isRootCertificate
)
{
if
(
certificateCache
.
ContainsKey
(
certificateName
))
{
var
cached
=
certificateCache
[
certificateName
];
...
...
@@ -152,7 +175,6 @@ namespace Titanium.Web.Proxy.Network
return
cached
.
Certificate
;
}
X509Certificate2
certificate
=
null
;
lock
(
string
.
Intern
(
certificateName
))
{
...
...
@@ -160,6 +182,11 @@ namespace Titanium.Web.Proxy.Network
{
try
{
if
(!
isRootCertificate
&&
RootCertificate
==
null
)
{
CreateTrustedRootCertificate
();
}
certificate
=
certEngine
.
MakeCertificate
(
certificateName
,
isRootCertificate
,
RootCertificate
);
}
catch
(
Exception
e
)
...
...
@@ -168,7 +195,7 @@ 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
...
...
@@ -182,10 +209,7 @@ namespace Titanium.Web.Proxy.Network
}
}
return
certificate
;
}
/// <summary>
...
...
Titanium.Web.Proxy/Network/ProxyClient.cs
View file @
e928c25a
...
...
@@ -7,7 +7,7 @@ namespace Titanium.Web.Proxy.Network
/// <summary>
/// This class wraps Tcp connection to client
/// </summary>
public
class
ProxyClient
internal
class
ProxyClient
{
/// <summary>
/// TcpClient used to communicate with client
...
...
Titanium.Web.Proxy/Network/Tcp/TcpConnection.cs
View file @
e928c25a
...
...
@@ -9,7 +9,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <summary>
/// An object that holds TcpConnection to a particular server and port
/// </summary>
public
class
TcpConnection
:
IDisposable
internal
class
TcpConnection
:
IDisposable
{
internal
ExternalProxy
UpStreamHttpProxy
{
get
;
set
;
}
...
...
Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
View file @
e928c25a
...
...
@@ -41,20 +41,24 @@ namespace Titanium.Web.Proxy.Network.Tcp
bool
isHttps
,
SslProtocols
supportedSslProtocols
,
RemoteCertificateValidationCallback
remoteCertificateValidationCallback
,
LocalCertificateSelectionCallback
localCertificateSelectionCallback
,
ExternalProxy
externalHttpProxy
,
ExternalProxy
externalHttpsProxy
,
Stream
clientStream
,
EndPoint
upStreamEndPoint
)
Stream
clientStream
,
IPEndPoint
upStreamEndPoint
)
{
TcpClient
client
;
Stream
stream
;
bool
isLocalhost
=
(
externalHttpsProxy
==
null
&&
externalHttpProxy
==
null
)
?
false
:
NetworkHelper
.
IsLocalIpAddress
(
remoteHostName
);
bool
useHttpsProxy
=
externalHttpsProxy
!=
null
&&
externalHttpsProxy
.
HostName
!=
remoteHostName
&&
(
externalHttpsProxy
.
BypassForLocalhost
&&
!
isLocalhost
);
bool
useHttpProxy
=
externalHttpProxy
!=
null
&&
externalHttpProxy
.
HostName
!=
remoteHostName
&&
(
externalHttpProxy
.
BypassForLocalhost
&&
!
isLocalhost
);
if
(
isHttps
)
{
SslStream
sslStream
=
null
;
//If this proxy uses another external proxy then create a tunnel request for HTTPS connections
if
(
externalHttpsProxy
!=
null
&&
externalHttpsProxy
.
HostName
!=
remoteHostName
)
if
(
useHttpsProxy
)
{
client
=
new
TcpClient
();
client
.
Client
.
Bind
(
upStreamEndPoint
);
client
=
new
TcpClient
(
upStreamEndPoint
);
await
client
.
ConnectAsync
(
externalHttpsProxy
.
HostName
,
externalHttpsProxy
.
Port
);
stream
=
client
.
GetStream
();
...
...
@@ -89,8 +93,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
}
else
{
client
=
new
TcpClient
();
client
.
Client
.
Bind
(
upStreamEndPoint
);
client
=
new
TcpClient
(
upStreamEndPoint
);
await
client
.
ConnectAsync
(
remoteHostName
,
remotePort
);
stream
=
client
.
GetStream
();
}
...
...
@@ -113,17 +116,15 @@ namespace Titanium.Web.Proxy.Network.Tcp
}
else
{
if
(
externalHttpProxy
!=
null
&&
externalHttpProxy
.
HostName
!=
remoteHostName
)
if
(
useHttpProxy
)
{
client
=
new
TcpClient
();
client
.
Client
.
Bind
(
upStreamEndPoint
);
client
=
new
TcpClient
(
upStreamEndPoint
);
await
client
.
ConnectAsync
(
externalHttpProxy
.
HostName
,
externalHttpProxy
.
Port
);
stream
=
client
.
GetStream
();
}
else
{
client
=
new
TcpClient
();
client
.
Client
.
Bind
(
upStreamEndPoint
);
client
=
new
TcpClient
(
upStreamEndPoint
);
await
client
.
ConnectAsync
(
remoteHostName
,
remotePort
);
stream
=
client
.
GetStream
();
}
...
...
Titanium.Web.Proxy/Network/Tcp/TcpRow.cs
View file @
e928c25a
...
...
@@ -13,7 +13,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// Initializes a new instance of the <see cref="TcpRow"/> class.
/// </summary>
/// <param name="tcpRow">TcpRow struct.</param>
public
TcpRow
(
NativeMethods
.
TcpRow
tcpRow
)
internal
TcpRow
(
NativeMethods
.
TcpRow
tcpRow
)
{
ProcessId
=
tcpRow
.
owningPid
;
...
...
@@ -29,16 +29,16 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <summary>
/// Gets the local end point.
/// </summary>
public
IPEndPoint
LocalEndPoint
{
get
;
}
internal
IPEndPoint
LocalEndPoint
{
get
;
}
/// <summary>
/// Gets the remote end point.
/// </summary>
public
IPEndPoint
RemoteEndPoint
{
get
;
}
internal
IPEndPoint
RemoteEndPoint
{
get
;
}
/// <summary>
/// Gets the process identifier.
/// </summary>
public
int
ProcessId
{
get
;
}
internal
int
ProcessId
{
get
;
}
}
}
\ No newline at end of file
Titanium.Web.Proxy/Network/Tcp/TcpTable.cs
View file @
e928c25a
...
...
@@ -17,7 +17,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// Initializes a new instance of the <see cref="TcpTable"/> class.
/// </summary>
/// <param name="tcpRows">TcpRow collection to initialize with.</param>
public
TcpTable
(
IEnumerable
<
TcpRow
>
tcpRows
)
internal
TcpTable
(
IEnumerable
<
TcpRow
>
tcpRows
)
{
this
.
tcpRows
=
tcpRows
;
}
...
...
@@ -25,7 +25,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <summary>
/// Gets the TCP rows.
/// </summary>
public
IEnumerable
<
TcpRow
>
TcpRows
=>
tcpRows
;
internal
IEnumerable
<
TcpRow
>
TcpRows
=>
tcpRows
;
/// <summary>
/// Returns an enumerator that iterates through the collection.
...
...
Titanium.Web.Proxy/ProxyServer.cs
View file @
e928c25a
This diff is collapsed.
Click to expand it.
Titanium.Web.Proxy/RequestHandler.cs
View file @
e928c25a
...
...
@@ -115,7 +115,7 @@ namespace Titanium.Web.Proxy
sslStream
=
new
SslStream
(
clientStream
,
true
);
var
certificate
=
endPoint
.
GenericCertificate
??
certificate
Cache
Manager
.
CreateCertificate
(
httpRemoteUri
.
Host
,
false
);
var
certificate
=
endPoint
.
GenericCertificate
??
certificateManager
.
CreateCertificate
(
httpRemoteUri
.
Host
,
false
);
//Successfully managed to authenticate the client using the fake certificate
await
sslStream
.
AuthenticateAsServerAsync
(
certificate
,
false
,
...
...
@@ -147,7 +147,7 @@ namespace Titanium.Web.Proxy
//write back successfull CONNECT response
await
WriteConnectResponse
(
clientStreamWriter
,
version
);
await
TcpHelper
.
SendRaw
(
B
UFFER_SIZE
,
ConnectionTimeOutSeconds
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
await
TcpHelper
.
SendRaw
(
B
ufferSize
,
ConnectionTimeOutSeconds
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
null
,
version
,
null
,
false
,
SupportedSslProtocols
,
ValidateServerCertificate
,
...
...
@@ -185,7 +185,7 @@ namespace Titanium.Web.Proxy
var
sslStream
=
new
SslStream
(
clientStream
,
true
);
//implement in future once SNI supported by SSL stream, for now use the same certificate
var
certificate
=
certificate
Cache
Manager
.
CreateCertificate
(
endPoint
.
GenericCertificateName
,
false
);
var
certificate
=
certificateManager
.
CreateCertificate
(
endPoint
.
GenericCertificateName
,
false
);
try
{
...
...
@@ -245,7 +245,7 @@ namespace Titanium.Web.Proxy
args
.
CustomUpStreamHttpProxyUsed
=
customUpStreamHttpProxy
;
args
.
CustomUpStreamHttpsProxyUsed
=
customUpStreamHttpsProxy
;
connection
=
await
tcpConnectionFactory
.
CreateClient
(
B
UFFER_SIZE
,
ConnectionTimeOutSeconds
,
connection
=
await
tcpConnectionFactory
.
CreateClient
(
B
ufferSize
,
ConnectionTimeOutSeconds
,
args
.
WebSession
.
Request
.
RequestUri
.
Host
,
args
.
WebSession
.
Request
.
RequestUri
.
Port
,
args
.
WebSession
.
Request
.
HttpVersion
,
args
.
IsHttps
,
SupportedSslProtocols
,
ValidateServerCertificate
,
...
...
@@ -378,7 +378,7 @@ namespace Titanium.Web.Proxy
}
var
args
=
new
SessionEventArgs
(
B
UFFER_SIZE
,
HandleHttpSessionResponse
)
new
SessionEventArgs
(
B
ufferSize
,
HandleHttpSessionResponse
)
{
ProxyClient
=
{
TcpClient
=
client
},
WebSession
=
{
ConnectHeaders
=
connectHeaders
}
...
...
@@ -487,7 +487,7 @@ namespace Titanium.Web.Proxy
//if upgrading to websocket then relay the requet without reading the contents
if
(
args
.
WebSession
.
Request
.
UpgradeToWebSocket
)
{
await
TcpHelper
.
SendRaw
(
B
UFFER_SIZE
,
ConnectionTimeOutSeconds
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
await
TcpHelper
.
SendRaw
(
B
ufferSize
,
ConnectionTimeOutSeconds
,
httpRemoteUri
.
Host
,
httpRemoteUri
.
Port
,
httpCmd
,
httpVersion
,
args
.
WebSession
.
Request
.
RequestHeaders
,
args
.
IsHttps
,
SupportedSslProtocols
,
ValidateServerCertificate
,
SelectClientCertificate
,
...
...
@@ -581,14 +581,14 @@ namespace Titanium.Web.Proxy
//send the request body bytes to server
if
(
args
.
WebSession
.
Request
.
ContentLength
>
0
)
{
await
args
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStream
(
B
UFFER_SIZE
,
postStream
,
args
.
WebSession
.
Request
.
ContentLength
);
await
args
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStream
(
B
ufferSize
,
postStream
,
args
.
WebSession
.
Request
.
ContentLength
);
}
//Need to revist, find any potential bugs
//send the request body bytes to server in chunks
else
if
(
args
.
WebSession
.
Request
.
IsChunked
)
{
await
args
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStreamChunked
(
B
UFFER_SIZE
,
postStream
);
await
args
.
ProxyClient
.
ClientStreamReader
.
CopyBytesToStreamChunked
(
B
ufferSize
,
postStream
);
}
}
}
...
...
Titanium.Web.Proxy/ResponseHandler.cs
View file @
e928c25a
...
...
@@ -22,7 +22,7 @@ namespace Titanium.Web.Proxy
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
p
ublic
async
Task
HandleHttpSessionResponse
(
SessionEventArgs
args
)
p
rivate
async
Task
HandleHttpSessionResponse
(
SessionEventArgs
args
)
{
//read response & headers from server
await
args
.
WebSession
.
ReceiveResponse
();
...
...
@@ -108,7 +108,7 @@ namespace Titanium.Web.Proxy
||
!
args
.
WebSession
.
Response
.
ResponseKeepAlive
)
{
await
args
.
WebSession
.
ServerConnection
.
StreamReader
.
WriteResponseBody
(
B
UFFER_SIZE
,
args
.
ProxyClient
.
ClientStream
,
args
.
WebSession
.
Response
.
IsChunked
,
.
WriteResponseBody
(
B
ufferSize
,
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
...
...
@@ -116,7 +116,7 @@ namespace Titanium.Web.Proxy
else
if
(
args
.
WebSession
.
Response
.
ResponseKeepAlive
&&
args
.
WebSession
.
Response
.
HttpVersion
.
Minor
==
0
)
{
await
args
.
WebSession
.
ServerConnection
.
StreamReader
.
WriteResponseBody
(
B
UFFER_SIZE
,
args
.
ProxyClient
.
ClientStream
,
args
.
WebSession
.
Response
.
IsChunked
,
.
WriteResponseBody
(
B
ufferSize
,
args
.
ProxyClient
.
ClientStream
,
args
.
WebSession
.
Response
.
IsChunked
,
args
.
WebSession
.
Response
.
ContentLength
);
}
}
...
...
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