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
8063d024
Commit
8063d024
authored
Jun 02, 2017
by
Jehonathan
Committed by
GitHub
Jun 02, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #253 from justcoding121/develop
Beta
parents
f02a8bfd
813700fe
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
343 additions
and
20 deletions
+343
-20
ProxyTestController.cs
.../Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
+2
-0
Request.cs
Titanium.Web.Proxy/Http/Request.cs
+140
-0
Response.cs
Titanium.Web.Proxy/Http/Response.cs
+136
-0
ProxyServer.cs
Titanium.Web.Proxy/ProxyServer.cs
+1
-1
RequestHandler.cs
Titanium.Web.Proxy/RequestHandler.cs
+20
-16
WinAuthHandler.cs
Titanium.Web.Proxy/WinAuthHandler.cs
+44
-3
No files found.
Examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
View file @
8063d024
...
@@ -45,6 +45,8 @@ namespace Titanium.Web.Proxy.Examples.Basic
...
@@ -45,6 +45,8 @@ namespace Titanium.Web.Proxy.Examples.Basic
proxyServer
.
ServerCertificateValidationCallback
+=
OnCertificateValidation
;
proxyServer
.
ServerCertificateValidationCallback
+=
OnCertificateValidation
;
proxyServer
.
ClientCertificateSelectionCallback
+=
OnCertificateSelection
;
proxyServer
.
ClientCertificateSelectionCallback
+=
OnCertificateSelection
;
//proxyServer.EnableWinAuth = true;
var
explicitEndPoint
=
new
ExplicitProxyEndPoint
(
IPAddress
.
Any
,
8000
,
true
)
var
explicitEndPoint
=
new
ExplicitProxyEndPoint
(
IPAddress
.
Any
,
8000
,
true
)
{
{
//Exclude Https addresses you don't want to proxy
//Exclude Https addresses you don't want to proxy
...
...
Titanium.Web.Proxy/Http/Request.cs
View file @
8063d024
using
System
;
using
System
;
using
System.Linq
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Text
;
using
System.Text
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Extensions
;
...
@@ -306,6 +307,143 @@ namespace Titanium.Web.Proxy.Http
...
@@ -306,6 +307,143 @@ namespace Titanium.Web.Proxy.Http
NonUniqueRequestHeaders
=
new
Dictionary
<
string
,
List
<
HttpHeader
>>(
StringComparer
.
OrdinalIgnoreCase
);
NonUniqueRequestHeaders
=
new
Dictionary
<
string
,
List
<
HttpHeader
>>(
StringComparer
.
OrdinalIgnoreCase
);
}
}
/// <summary>
/// True if header exists
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public
bool
HeaderExists
(
string
name
)
{
if
(
RequestHeaders
.
ContainsKey
(
name
)
||
NonUniqueRequestHeaders
.
ContainsKey
(
name
))
{
return
true
;
}
return
false
;
}
/// <summary>
/// Returns all headers with given name if exists
/// Returns null if does'nt exist
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public
List
<
HttpHeader
>
GetHeaders
(
string
name
)
{
if
(
RequestHeaders
.
ContainsKey
(
name
))
{
return
new
List
<
HttpHeader
>()
{
RequestHeaders
[
name
]
};
}
else
if
(
NonUniqueRequestHeaders
.
ContainsKey
(
name
))
{
return
new
List
<
HttpHeader
>(
NonUniqueRequestHeaders
[
name
]);
}
return
null
;
}
/// <summary>
/// Returns all headers
/// </summary>
/// <returns></returns>
public
List
<
HttpHeader
>
GetAllHeaders
()
{
var
result
=
new
List
<
HttpHeader
>();
result
.
AddRange
(
RequestHeaders
.
Select
(
x
=>
x
.
Value
));
result
.
AddRange
(
NonUniqueRequestHeaders
.
SelectMany
(
x
=>
x
.
Value
));
return
result
;
}
/// <summary>
/// Add a new header with given name and value
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
public
void
AddHeader
(
string
name
,
string
value
)
{
AddHeader
(
new
HttpHeader
(
name
,
value
));
}
/// <summary>
/// Adds the given header object to Request
/// </summary>
/// <param name="newHeader"></param>
public
void
AddHeader
(
HttpHeader
newHeader
)
{
if
(
NonUniqueRequestHeaders
.
ContainsKey
(
newHeader
.
Name
))
{
NonUniqueRequestHeaders
[
newHeader
.
Name
].
Add
(
newHeader
);
return
;
}
if
(
RequestHeaders
.
ContainsKey
(
newHeader
.
Name
))
{
var
existing
=
RequestHeaders
[
newHeader
.
Name
];
RequestHeaders
.
Remove
(
newHeader
.
Name
);
NonUniqueRequestHeaders
.
Add
(
newHeader
.
Name
,
new
List
<
HttpHeader
>()
{
existing
,
newHeader
});
}
else
{
RequestHeaders
.
Add
(
newHeader
.
Name
,
newHeader
);
}
}
/// <summary>
/// removes all headers with given name
/// </summary>
/// <param name="headerName"></param>
/// <returns>True if header was removed
/// False if no header exists with given name</returns>
public
bool
RemoveHeader
(
string
headerName
)
{
if
(
RequestHeaders
.
ContainsKey
(
headerName
))
{
RequestHeaders
.
Remove
(
headerName
);
return
true
;
}
else
if
(
NonUniqueRequestHeaders
.
ContainsKey
(
headerName
))
{
NonUniqueRequestHeaders
.
Remove
(
headerName
);
return
true
;
}
return
false
;
}
/// <summary>
/// Removes given header object if it exist
/// </summary>
/// <param name="header">Returns true if header exists and was removed </param>
public
bool
RemoveHeader
(
HttpHeader
header
)
{
if
(
RequestHeaders
.
ContainsKey
(
header
.
Name
))
{
if
(
RequestHeaders
[
header
.
Name
].
Equals
(
header
))
{
RequestHeaders
.
Remove
(
header
.
Name
);
return
true
;
}
}
else
if
(
NonUniqueRequestHeaders
.
ContainsKey
(
header
.
Name
))
{
if
(
NonUniqueRequestHeaders
[
header
.
Name
]
.
RemoveAll
(
x
=>
x
.
Equals
(
header
))
>
0
)
{
return
true
;
}
}
return
false
;
}
/// <summary>
/// <summary>
/// Dispose off
/// Dispose off
/// </summary>
/// </summary>
...
@@ -320,5 +458,7 @@ namespace Titanium.Web.Proxy.Http
...
@@ -320,5 +458,7 @@ namespace Titanium.Web.Proxy.Http
RequestBody
=
null
;
RequestBody
=
null
;
RequestBody
=
null
;
RequestBody
=
null
;
}
}
}
}
}
}
Titanium.Web.Proxy/Http/Response.cs
View file @
8063d024
using
System
;
using
System
;
using
System.Linq
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.IO
;
using
System.Text
;
using
System.Text
;
...
@@ -242,6 +243,141 @@ namespace Titanium.Web.Proxy.Http
...
@@ -242,6 +243,141 @@ namespace Titanium.Web.Proxy.Http
NonUniqueResponseHeaders
=
new
Dictionary
<
string
,
List
<
HttpHeader
>>(
StringComparer
.
OrdinalIgnoreCase
);
NonUniqueResponseHeaders
=
new
Dictionary
<
string
,
List
<
HttpHeader
>>(
StringComparer
.
OrdinalIgnoreCase
);
}
}
/// <summary>
/// True if header exists
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public
bool
HeaderExists
(
string
name
)
{
if
(
ResponseHeaders
.
ContainsKey
(
name
)
||
NonUniqueResponseHeaders
.
ContainsKey
(
name
))
{
return
true
;
}
return
false
;
}
/// <summary>
/// Returns all headers with given name if exists
/// Returns null if does'nt exist
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public
List
<
HttpHeader
>
GetHeaders
(
string
name
)
{
if
(
ResponseHeaders
.
ContainsKey
(
name
))
{
return
new
List
<
HttpHeader
>()
{
ResponseHeaders
[
name
]
};
}
else
if
(
NonUniqueResponseHeaders
.
ContainsKey
(
name
))
{
return
new
List
<
HttpHeader
>(
NonUniqueResponseHeaders
[
name
]);
}
return
null
;
}
/// <summary>
/// Returns all headers
/// </summary>
/// <returns></returns>
public
List
<
HttpHeader
>
GetAllHeaders
()
{
var
result
=
new
List
<
HttpHeader
>();
result
.
AddRange
(
ResponseHeaders
.
Select
(
x
=>
x
.
Value
));
result
.
AddRange
(
NonUniqueResponseHeaders
.
SelectMany
(
x
=>
x
.
Value
));
return
result
;
}
/// <summary>
/// Add a new header with given name and value
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
public
void
AddHeader
(
string
name
,
string
value
)
{
AddHeader
(
new
HttpHeader
(
name
,
value
));
}
/// <summary>
/// Adds the given header object to Response
/// </summary>
/// <param name="newHeader"></param>
public
void
AddHeader
(
HttpHeader
newHeader
)
{
if
(
NonUniqueResponseHeaders
.
ContainsKey
(
newHeader
.
Name
))
{
NonUniqueResponseHeaders
[
newHeader
.
Name
].
Add
(
newHeader
);
return
;
}
if
(
ResponseHeaders
.
ContainsKey
(
newHeader
.
Name
))
{
var
existing
=
ResponseHeaders
[
newHeader
.
Name
];
ResponseHeaders
.
Remove
(
newHeader
.
Name
);
NonUniqueResponseHeaders
.
Add
(
newHeader
.
Name
,
new
List
<
HttpHeader
>()
{
existing
,
newHeader
});
}
else
{
ResponseHeaders
.
Add
(
newHeader
.
Name
,
newHeader
);
}
}
/// <summary>
/// removes all headers with given name
/// </summary>
/// <param name="headerName"></param>
/// <returns>True if header was removed
/// False if no header exists with given name</returns>
public
bool
RemoveHeader
(
string
headerName
)
{
if
(
ResponseHeaders
.
ContainsKey
(
headerName
))
{
ResponseHeaders
.
Remove
(
headerName
);
return
true
;
}
else
if
(
NonUniqueResponseHeaders
.
ContainsKey
(
headerName
))
{
NonUniqueResponseHeaders
.
Remove
(
headerName
);
return
true
;
}
return
false
;
}
/// <summary>
/// Removes given header object if it exist
/// </summary>
/// <param name="header">Returns true if header exists and was removed </param>
public
bool
RemoveHeader
(
HttpHeader
header
)
{
if
(
ResponseHeaders
.
ContainsKey
(
header
.
Name
))
{
if
(
ResponseHeaders
[
header
.
Name
].
Equals
(
header
))
{
ResponseHeaders
.
Remove
(
header
.
Name
);
return
true
;
}
}
else
if
(
NonUniqueResponseHeaders
.
ContainsKey
(
header
.
Name
))
{
if
(
NonUniqueResponseHeaders
[
header
.
Name
]
.
RemoveAll
(
x
=>
x
.
Equals
(
header
))
>
0
)
{
return
true
;
}
}
return
false
;
}
/// <summary>
/// <summary>
/// Dispose off
/// Dispose off
/// </summary>
/// </summary>
...
...
Titanium.Web.Proxy/ProxyServer.cs
View file @
8063d024
...
@@ -205,7 +205,7 @@ namespace Titanium.Web.Proxy
...
@@ -205,7 +205,7 @@ namespace Titanium.Web.Proxy
/// in middle attack is not currently supported
/// in middle attack is not currently supported
/// (which would require windows delegation enabled for this server process)
/// (which would require windows delegation enabled for this server process)
/// </summary>
/// </summary>
public
bool
EnableWinAuth
{
get
;
set
;
}
=
true
;
public
bool
EnableWinAuth
{
get
;
set
;
}
/// <summary>
/// <summary>
/// Verifies the remote Secure Sockets Layer (SSL) certificate used for authentication
/// Verifies the remote Secure Sockets Layer (SSL) certificate used for authentication
...
...
Titanium.Web.Proxy/RequestHandler.cs
View file @
8063d024
...
@@ -453,6 +453,9 @@ namespace Titanium.Web.Proxy
...
@@ -453,6 +453,9 @@ namespace Titanium.Web.Proxy
await
args
.
WebSession
.
SendRequest
(
Enable100ContinueBehaviour
);
await
args
.
WebSession
.
SendRequest
(
Enable100ContinueBehaviour
);
}
}
//check if content-length is > 0
if
(
args
.
WebSession
.
Request
.
ContentLength
>
0
)
{
//If request was modified by user
//If request was modified by user
if
(
args
.
WebSession
.
Request
.
RequestBodyRead
)
if
(
args
.
WebSession
.
Request
.
RequestBodyRead
)
{
{
...
@@ -477,6 +480,7 @@ namespace Titanium.Web.Proxy
...
@@ -477,6 +480,7 @@ namespace Titanium.Web.Proxy
}
}
}
}
}
}
}
//If not expectation failed response was returned by server then parse response
//If not expectation failed response was returned by server then parse response
if
(!
args
.
WebSession
.
Request
.
ExpectationFailed
)
if
(!
args
.
WebSession
.
Request
.
ExpectationFailed
)
...
...
Titanium.Web.Proxy/WinAuthHandler.cs
View file @
8063d024
...
@@ -5,6 +5,8 @@ using System.Threading.Tasks;
...
@@ -5,6 +5,8 @@ using System.Threading.Tasks;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.EventArguments
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Models
;
using
Titanium.Web.Proxy.Network.WinAuth
;
using
Titanium.Web.Proxy.Network.WinAuth
;
using
Titanium.Web.Proxy.Extensions
;
using
Titanium.Web.Proxy.Helpers
;
namespace
Titanium.Web.Proxy
namespace
Titanium.Web.Proxy
{
{
...
@@ -87,11 +89,35 @@ namespace Titanium.Web.Proxy
...
@@ -87,11 +89,35 @@ namespace Titanium.Web.Proxy
{
{
var
scheme
=
authSchemes
.
FirstOrDefault
(
x
=>
authHeader
.
Value
.
Equals
(
x
,
StringComparison
.
OrdinalIgnoreCase
));
var
scheme
=
authSchemes
.
FirstOrDefault
(
x
=>
authHeader
.
Value
.
Equals
(
x
,
StringComparison
.
OrdinalIgnoreCase
));
//clear any existing headers to avoid confusing bad servers
if
(
args
.
WebSession
.
Request
.
NonUniqueRequestHeaders
.
ContainsKey
(
"Authorization"
))
{
args
.
WebSession
.
Request
.
NonUniqueRequestHeaders
.
Remove
(
"Authorization"
);
}
//initial value will match exactly any of the schemes
//initial value will match exactly any of the schemes
if
(
scheme
!=
null
)
if
(
scheme
!=
null
)
{
{
var
clientToken
=
WinAuthHandler
.
GetInitialAuthToken
(
args
.
WebSession
.
Request
.
Host
,
scheme
,
args
.
Id
);
var
clientToken
=
WinAuthHandler
.
GetInitialAuthToken
(
args
.
WebSession
.
Request
.
Host
,
scheme
,
args
.
Id
);
args
.
WebSession
.
Request
.
RequestHeaders
.
Add
(
"Authorization"
,
new
HttpHeader
(
"Authorization"
,
string
.
Concat
(
scheme
,
clientToken
)));
var
auth
=
new
HttpHeader
(
"Authorization"
,
string
.
Concat
(
scheme
,
clientToken
));
//replace existing authorization header if any
if
(
args
.
WebSession
.
Request
.
RequestHeaders
.
ContainsKey
(
"Authorization"
))
{
args
.
WebSession
.
Request
.
RequestHeaders
[
"Authorization"
]
=
auth
;
}
else
{
args
.
WebSession
.
Request
.
RequestHeaders
.
Add
(
"Authorization"
,
auth
);
}
//don't need to send body for Authorization request
if
(
args
.
WebSession
.
Request
.
HasBody
)
{
args
.
WebSession
.
Request
.
ContentLength
=
0
;
}
}
}
//challenge value will start with any of the scheme selected
//challenge value will start with any of the scheme selected
else
else
...
@@ -102,13 +128,28 @@ namespace Titanium.Web.Proxy
...
@@ -102,13 +128,28 @@ namespace Titanium.Web.Proxy
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
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
if
(
args
.
WebSession
.
Request
.
HasBody
)
{
args
.
WebSession
.
Request
.
ContentLength
=
args
.
WebSession
.
Request
.
RequestBody
.
Length
;
}
}
}
//clear current response
//Need to revisit this.
//Should we cache all Set-Cokiee headers from server during auth process
//and send it to client after auth?
//clear current server response
await
args
.
ClearResponse
();
await
args
.
ClearResponse
();
//request again with updated authorization header
//and server cookies
var
disposed
=
await
HandleHttpSessionRequestInternal
(
args
.
WebSession
.
ServerConnection
,
args
,
false
);
var
disposed
=
await
HandleHttpSessionRequestInternal
(
args
.
WebSession
.
ServerConnection
,
args
,
false
);
return
disposed
;
return
disposed
;
}
}
...
...
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