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
37714ced
Commit
37714ced
authored
Feb 05, 2016
by
titanium007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #36
Add endpoints
parent
75d6ba76
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
161 additions
and
61 deletions
+161
-61
ProxyTestController.cs
Titanium.Web.Proxy.Test/ProxyTestController.cs
+9
-7
EndPoint.cs
Titanium.Web.Proxy/Models/EndPoint.cs
+30
-0
ProxyServer.cs
Titanium.Web.Proxy/ProxyServer.cs
+76
-42
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+45
-12
Titanium.Web.Proxy.csproj
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
+1
-0
No files found.
Titanium.Web.Proxy.Test/ProxyTestController.cs
View file @
37714ced
using
System
;
using
System.Net
;
using
System.Text.RegularExpressions
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Models
;
namespace
Titanium.Web.Proxy.Test
{
...
...
@@ -15,20 +17,20 @@ namespace Titanium.Web.Proxy.Test
ProxyServer
.
BeforeRequest
+=
OnRequest
;
ProxyServer
.
BeforeResponse
+=
OnResponse
;
ProxyServer
.
EnableSsl
=
EnableSsl
;
ProxyServer
.
SetAsSystemProxy
=
SetAsSystemProxy
;
//Exclude Https addresses you don't want to proxy
//Usefull for clients that use certificate pinning
//for example dropbox.com
ProxyServer
.
ExcludedHttpsHostNameRegex
.
Add
(
".dropbox.com"
);
// ProxyServer.ExcludedHttpsHostNameRegex.Add(".dropbox.com");
var
explicitEndPoint
=
new
ExplicitProxyEndPoint
{
EnableSsl
=
true
,
IpAddress
=
IPAddress
.
Any
,
Port
=
8000
};
var
transparentEndPoint
=
new
TransparentProxyEndPoint
{
EnableSsl
=
true
,
IpAddress
=
IPAddress
.
Loopback
,
Port
=
443
};
ProxyServer
.
AddEndPoint
(
explicitEndPoint
);
ProxyServer
.
AddEndPoint
(
transparentEndPoint
);
ProxyServer
.
Start
();
ProxyServer
.
SetAsSystemProxy
(
explicitEndPoint
);
ProxyServer
.
ListeningPort
=
ProxyServer
.
ListeningPort
;
Console
.
WriteLine
(
"Proxy listening on local machine port: {0} "
,
ProxyServer
.
ListeningPort
);
//
Console.WriteLine("Proxy listening on local machine port: {0} ", ProxyServer.ListeningPort);
}
public
void
Stop
()
...
...
Titanium.Web.Proxy/Models/EndPoint.cs
0 → 100644
View file @
37714ced
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Net
;
using
System.Net.Sockets
;
using
System.Text
;
namespace
Titanium.Web.Proxy.Models
{
public
abstract
class
ProxyEndPoint
{
public
IPAddress
IpAddress
{
get
;
set
;
}
public
int
Port
{
get
;
set
;
}
public
bool
EnableSsl
{
get
;
set
;
}
internal
TcpListener
listener
{
get
;
set
;
}
}
public
class
ExplicitProxyEndPoint
:
ProxyEndPoint
{
internal
bool
IsSystemProxy
{
get
;
set
;
}
public
List
<
string
>
ExcludedHostNameRegex
{
get
;
set
;
}
}
public
class
TransparentProxyEndPoint
:
ProxyEndPoint
{
}
}
Titanium.Web.Proxy/ProxyServer.cs
View file @
37714ced
...
...
@@ -9,7 +9,9 @@ using System.Text.RegularExpressions;
using
System.Threading.Tasks
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Helpers
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Network
;
using
System.Linq
;
namespace
Titanium.Web.Proxy
{
...
...
@@ -31,89 +33,115 @@ namespace Titanium.Web.Proxy
private
static
readonly
byte
[]
ChunkEnd
=
Encoding
.
ASCII
.
GetBytes
(
0.
ToString
(
"x2"
)
+
Environment
.
NewLine
+
Environment
.
NewLine
);
private
static
TcpListener
_listener
;
private
static
List
<
ProxyEndPoint
>
_proxyEndPoints
{
get
;
set
;
}
public
static
List
<
string
>
ExcludedHttpsHostNameRegex
=
new
List
<
string
>();
static
ProxyServer
()
{
CertManager
=
new
CertificateManager
(
"Titanium"
,
"Titanium Root Certificate Authority"
);
ListeningIpAddress
=
IPAddress
.
Any
;
ListeningPort
=
0
;
_proxyEndPoints
=
new
List
<
ProxyEndPoint
>();
Initialize
();
}
private
static
CertificateManager
CertManager
{
get
;
set
;
}
private
static
bool
EnableSsl
{
get
;
set
;
}
private
static
bool
certTrusted
{
get
;
set
;
}
private
static
bool
proxyStarted
{
get
;
set
;
}
public
static
string
RootCertificateName
{
get
;
set
;
}
public
static
bool
EnableSsl
{
get
;
set
;
}
public
static
bool
SetAsSystemProxy
{
get
;
set
;
}
public
static
int
ListeningPort
{
get
;
set
;
}
public
static
IPAddress
ListeningIpAddress
{
get
;
set
;
}
public
static
event
EventHandler
<
SessionEventArgs
>
BeforeRequest
;
public
static
event
EventHandler
<
SessionEventArgs
>
BeforeResponse
;
public
static
void
Initialize
()
{
Task
.
Factory
.
StartNew
(()
=>
TcpConnectionManager
.
ClearIdleConnections
());
{
Task
.
Factory
.
StartNew
(()
=>
TcpConnectionManager
.
ClearIdleConnections
());
}
public
static
void
AddEndPoint
(
ProxyEndPoint
endPoint
)
{
if
(
proxyStarted
)
throw
new
Exception
(
"Cannot add end points after proxy started."
);
_proxyEndPoints
.
Add
(
endPoint
);
}
public
static
bool
Start
(
)
public
static
void
SetAsSystemProxy
(
ExplicitProxyEndPoint
endPoint
)
{
_listener
=
new
TcpListener
(
ListeningIpAddress
,
ListeningPort
);
_listener
.
Start
(
);
if
(
_proxyEndPoints
.
Contains
(
endPoint
)
==
false
)
throw
new
Exception
(
"Cannot set endPoints not added to proxy as system proxy"
);
ListeningPort
=
((
IPEndPoint
)
_listener
.
LocalEndpoint
).
Port
;
// accept clients asynchronously
_listener
.
BeginAcceptTcpClient
(
OnAcceptConnection
,
_listener
);
if
(!
proxyStarted
)
throw
new
Exception
(
"Cannot set system proxy settings before proxy has been started."
);
var
certTrusted
=
false
;
//clear any settings previously added
_proxyEndPoints
.
OfType
<
ExplicitProxyEndPoint
>().
ToList
().
ForEach
(
x
=>
x
.
IsSystemProxy
=
false
);
if
(
EnableSsl
)
certTrusted
=
CertManager
.
CreateTrustedRootCertificate
();
endPoint
.
IsSystemProxy
=
true
;
if
(
SetAsSystemProxy
)
{
SystemProxyHelper
.
EnableProxyHttp
(
Equals
(
ListeningIpAddress
,
IPAddress
.
Any
)
?
"127.0.0.1"
:
ListeningIpAddress
.
ToString
(),
ListeningPort
);
SystemProxyHelper
.
EnableProxyHttp
(
Equals
(
endPoint
.
IpAddress
,
IPAddress
.
Any
)
?
"127.0.0.1"
:
endPoint
.
IpAddress
.
ToString
(),
endPoint
.
Port
);
#if !DEBUG
FireFoxHelper
.
AddFirefox
();
FireFoxHelper
.
AddFirefox
();
#endif
if
(
endPoint
.
EnableSsl
)
{
RootCertificateName
=
RootCertificateName
??
"Titanium_Proxy_Test_Root"
;
if
(
EnableSsl
)
//If certificate was trusted by the machine
if
(
certTrusted
)
{
RootCertificateName
=
RootCertificateName
??
"Titanium_Proxy_Test_Root"
;
//If certificate was trusted by the machine
if
(
certTrusted
)
{
SystemProxyHelper
.
EnableProxyHttps
(
Equals
(
ListeningIpAddress
,
IPAddress
.
Any
)
?
"127.0.0.1"
:
ListeningIpAddress
.
ToString
(),
ListeningPort
);
}
SystemProxyHelper
.
EnableProxyHttps
(
Equals
(
endPoint
.
IpAddress
,
IPAddress
.
Any
)
?
"127.0.0.1"
:
endPoint
.
IpAddress
.
ToString
(),
endPoint
.
Port
);
}
}
return
true
;
}
public
static
void
Start
()
{
EnableSsl
=
_proxyEndPoints
.
Any
(
x
=>
x
.
EnableSsl
);
if
(
EnableSsl
)
certTrusted
=
CertManager
.
CreateTrustedRootCertificate
();
foreach
(
var
endPoint
in
_proxyEndPoints
)
{
endPoint
.
listener
=
new
TcpListener
(
endPoint
.
IpAddress
,
endPoint
.
Port
);
endPoint
.
listener
.
Start
();
endPoint
.
Port
=
((
IPEndPoint
)
endPoint
.
listener
.
LocalEndpoint
).
Port
;
// accept clients asynchronously
endPoint
.
listener
.
BeginAcceptTcpClient
(
OnAcceptConnection
,
endPoint
);
}
proxyStarted
=
true
;
}
private
static
void
OnAcceptConnection
(
IAsyncResult
asyn
)
{
var
endPoint
=
(
ProxyEndPoint
)
asyn
.
AsyncState
;
// Get the listener that handles the client request.
endPoint
.
listener
.
BeginAcceptTcpClient
(
OnAcceptConnection
,
endPoint
);
var
client
=
endPoint
.
listener
.
EndAcceptTcpClient
(
asyn
);
try
{
// Get the listener that handles the client request.
_listener
.
BeginAcceptTcpClient
(
OnAcceptConnection
,
_listener
);
var
client
=
_listener
.
EndAcceptTcpClient
(
asyn
);
Task
.
Factory
.
StartNew
(()
=>
HandleClient
(
client
));
if
(
endPoint
.
GetType
()
==
typeof
(
TransparentProxyEndPoint
))
Task
.
Factory
.
StartNew
(()
=>
HandleClient
(
endPoint
as
TransparentProxyEndPoint
,
client
));
else
Task
.
Factory
.
StartNew
(()
=>
HandleClient
(
endPoint
as
ExplicitProxyEndPoint
,
client
));
}
catch
{
...
...
@@ -124,6 +152,8 @@ namespace Titanium.Web.Proxy
public
static
void
Stop
()
{
var
SetAsSystemProxy
=
_proxyEndPoints
.
OfType
<
ExplicitProxyEndPoint
>().
Any
(
x
=>
x
.
IsSystemProxy
);
if
(
SetAsSystemProxy
)
{
SystemProxyHelper
.
DisableAllProxy
();
...
...
@@ -132,7 +162,11 @@ namespace Titanium.Web.Proxy
#endif
}
_listener
.
Stop
();
foreach
(
var
endPoint
in
_proxyEndPoints
)
{
endPoint
.
listener
.
Stop
();
}
CertManager
.
Dispose
();
}
}
...
...
Titanium.Web.Proxy/RequestHandler.cs
View file @
37714ced
...
...
@@ -20,7 +20,7 @@ namespace Titanium.Web.Proxy
{
partial
class
ProxyServer
{
private
static
void
HandleClient
(
TcpClient
client
)
private
static
void
HandleClient
(
ExplicitProxyEndPoint
endPoint
,
TcpClient
client
)
{
Stream
clientStream
=
client
.
GetStream
();
var
clientStreamReader
=
new
CustomBinaryReader
(
clientStream
,
Encoding
.
ASCII
);
...
...
@@ -51,7 +51,8 @@ namespace Titanium.Web.Proxy
var
httpVersion
=
httpCmdSplit
[
2
];
var
excluded
=
ExcludedHttpsHostNameRegex
.
Any
(
x
=>
Regex
.
IsMatch
(
httpRemoteUri
.
Host
,
x
));
var
excluded
=
endPoint
.
ExcludedHostNameRegex
!=
null
?
endPoint
.
ExcludedHostNameRegex
.
Any
(
x
=>
Regex
.
IsMatch
(
httpRemoteUri
.
Host
,
x
))
:
false
;
//Client wants to create a secure tcp tunnel (its a HTTPS request)
if
(
httpVerb
.
ToUpper
()
==
"CONNECT"
&&
!
excluded
&&
httpRemoteUri
.
Port
==
443
)
...
...
@@ -103,7 +104,7 @@ namespace Titanium.Web.Proxy
//Now create the request
HandleHttpSessionRequest
(
client
,
httpCmd
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
httpRemoteUri
.
Scheme
==
Uri
.
UriSchemeHttps
?
httpRemoteUri
.
OriginalString
:
null
);
httpRemoteUri
.
Scheme
==
Uri
.
UriSchemeHttps
?
true
:
false
);
}
catch
{
...
...
@@ -111,9 +112,43 @@ namespace Titanium.Web.Proxy
}
}
private
static
void
HandleClient
(
TransparentProxyEndPoint
endPoint
,
TcpClient
client
)
{
var
sslStream
=
new
SslStream
(
client
.
GetStream
(),
true
);
CustomBinaryReader
clientStreamReader
=
null
;
StreamWriter
clientStreamWriter
=
null
;
var
certificate
=
CertManager
.
CreateCertificate
(
"127.0.0.1"
);
try
{
//Successfully managed to authenticate the client using the fake certificate
sslStream
.
AuthenticateAsServer
(
certificate
,
false
,
SslProtocols
.
Tls
,
false
);
clientStreamReader
=
new
CustomBinaryReader
(
sslStream
,
Encoding
.
ASCII
);
clientStreamWriter
=
new
StreamWriter
(
sslStream
);
//HTTPS server created - we can now decrypt the client's traffic
}
catch
(
Exception
e
)
{
if
(
sslStream
!=
null
)
sslStream
.
Dispose
();
Dispose
(
client
,
sslStream
,
clientStreamReader
,
clientStreamWriter
,
null
);
return
;
}
var
httpCmd
=
clientStreamReader
.
ReadLine
();
//Now create the request
HandleHttpSessionRequest
(
client
,
httpCmd
,
sslStream
,
clientStreamReader
,
clientStreamWriter
,
true
);
}
private
static
void
HandleHttpSessionRequest
(
TcpClient
client
,
string
httpCmd
,
Stream
clientStream
,
CustomBinaryReader
clientStreamReader
,
StreamWriter
clientStreamWriter
,
string
secureTunnelHostName
)
CustomBinaryReader
clientStreamReader
,
StreamWriter
clientStreamWriter
,
bool
IsHttps
)
{
TcpConnection
connection
=
null
;
string
lastRequestHostName
=
null
;
...
...
@@ -135,8 +170,8 @@ namespace Titanium.Web.Proxy
var
httpCmdSplit
=
httpCmd
.
Split
(
SpaceSplit
,
3
);
var
httpMethod
=
httpCmdSplit
[
0
];
var
httpRemoteUri
=
new
Uri
(
secureTunnelHostName
==
null
?
httpCmdSplit
[
1
]
:
(
secureTunnelHostName
+
httpCmdSplit
[
1
]));
var
httpVersion
=
httpCmdSplit
[
2
];
Version
version
;
...
...
@@ -149,11 +184,6 @@ namespace Titanium.Web.Proxy
version
=
new
Version
(
1
,
0
);
}
if
(
httpRemoteUri
.
Scheme
==
Uri
.
UriSchemeHttps
)
{
args
.
IsHttps
=
true
;
}
args
.
ProxySession
.
Request
.
RequestHeaders
=
new
List
<
HttpHeader
>();
...
...
@@ -166,6 +196,9 @@ namespace Titanium.Web.Proxy
SetRequestHeaders
(
args
.
ProxySession
.
Request
.
RequestHeaders
,
args
.
ProxySession
);
var
httpRemoteUri
=
new
Uri
(!
IsHttps
?
httpCmdSplit
[
1
]
:
(
string
.
Concat
(
"https://"
,
args
.
ProxySession
.
Request
.
Hostname
,
httpCmdSplit
[
1
])));
args
.
IsHttps
=
IsHttps
;
if
(
args
.
ProxySession
.
Request
.
UpgradeToWebSocket
)
{
TcpHelper
.
SendRaw
(
clientStreamReader
.
BaseStream
,
httpCmd
,
args
.
ProxySession
.
Request
.
RequestHeaders
,
...
...
@@ -249,7 +282,7 @@ namespace Titanium.Web.Proxy
Dispose
(
client
,
clientStream
,
clientStreamReader
,
clientStreamWriter
,
args
);
break
;
}
}
if
(
connection
!=
null
)
...
...
Titanium.Web.Proxy/Titanium.Web.Proxy.csproj
View file @
37714ced
...
...
@@ -85,6 +85,7 @@
<Compile
Include=
"Helpers\CertificateManager.cs"
/>
<Compile
Include=
"Helpers\Firefox.cs"
/>
<Compile
Include=
"Helpers\SystemProxy.cs"
/>
<Compile
Include=
"Models\EndPoint.cs"
/>
<Compile
Include=
"Network\TcpExtensions.cs"
/>
<Compile
Include=
"Network\TcpConnectionManager.cs"
/>
<Compile
Include=
"Models\HttpHeader.cs"
/>
...
...
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