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

Commit 987dafc

Browse files
committed
socks 5 username/password authentication
1 parent 0614f4f commit 987dafc

File tree

4 files changed

+73
-4
lines changed

4 files changed

+73
-4
lines changed

src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ public bool EnableWinAuth
140140
/// </summary>
141141
public bool IsTransparent => ProxyEndPoint is TransparentProxyEndPoint;
142142

143+
/// <summary>
144+
/// Is this a SOCKS endpoint?
145+
/// </summary>
146+
public bool IsSocks => ProxyEndPoint is SocksProxyEndPoint;
147+
143148
/// <summary>
144149
/// The last exception that happened.
145150
/// </summary>

src/Titanium.Web.Proxy/RequestHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ await HeaderParser.ReadHeaders(clientStream, args.HttpClient.Request.Headers,
9090
request.Method = requestLine.Method;
9191
request.HttpVersion = requestLine.Version;
9292

93-
if (!args.IsTransparent)
93+
if (!args.IsTransparent && !args.IsSocks)
9494
{
9595
// proxy authorization check
9696
if (connectRequest == null && await checkAuthorization(args) == false)

src/Titanium.Web.Proxy/ResponseHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ await handleHttpSessionRequest(args, null, args.ClientConnection.NegotiatedAppli
9999

100100
response.Locked = true;
101101

102-
if (!args.IsTransparent)
102+
if (!args.IsTransparent && !args.IsSocks)
103103
{
104104
response.Headers.FixProxyHeaders();
105105
}

src/Titanium.Web.Proxy/SocksClientHandler.cs

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Text;
23
using System.Threading;
34
using System.Threading.Tasks;
45
using Titanium.Web.Proxy.Extensions;
@@ -48,13 +49,76 @@ private async Task handleClient(SocksProxyEndPoint endPoint, TcpClientConnection
4849
}
4950
else if (buffer[0] == 5)
5051
{
51-
if (buffer[1] == 0 || buffer[2] != 0)
52+
int authenticationMethodCount = buffer[1];
53+
if (read < authenticationMethodCount + 2)
5254
{
5355
return;
5456
}
5557

56-
buffer[1] = 0;
58+
int acceptedMethod = 255;
59+
for (int i = 0; i < authenticationMethodCount; i++)
60+
{
61+
int method = buffer[i + 2];
62+
if (method == 0 && ProxyBasicAuthenticateFunc == null)
63+
{
64+
acceptedMethod = 0;
65+
break;
66+
}
67+
68+
if (method == 2)
69+
{
70+
acceptedMethod = 2;
71+
break;
72+
}
73+
}
74+
75+
buffer[1] = (byte)acceptedMethod;
5776
await stream.WriteAsync(buffer, 0, 2, cancellationToken);
77+
78+
if (acceptedMethod == 255)
79+
{
80+
// no acceptable method
81+
return;
82+
}
83+
84+
if (acceptedMethod == 2)
85+
{
86+
read = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
87+
if (read < 3 || buffer[0] != 1)
88+
{
89+
// authentication version should be 1
90+
return;
91+
}
92+
93+
int userNameLength = buffer[1];
94+
if (read < 3 + userNameLength)
95+
{
96+
return;
97+
}
98+
99+
string userName = Encoding.ASCII.GetString(buffer, 2, userNameLength);
100+
101+
int passwordLength = buffer[2 + userNameLength];
102+
if (read < 3 + userNameLength + passwordLength)
103+
{
104+
return;
105+
}
106+
107+
string password = Encoding.ASCII.GetString(buffer, 3 + userNameLength, passwordLength);
108+
bool success = true;
109+
if (ProxySchemeAuthenticateFunc != null)
110+
{
111+
success = await ProxyBasicAuthenticateFunc.Invoke(null, userName, password);
112+
}
113+
114+
buffer[1] = success ? (byte)0 : (byte)1;
115+
await stream.WriteAsync(buffer, 0, 2, cancellationToken);
116+
if (!success)
117+
{
118+
return;
119+
}
120+
}
121+
58122
read = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
59123
if (read < 10 || buffer[1] != 1)
60124
{

0 commit comments

Comments
 (0)