Skip to content

Commit 896292d

Browse files
committed
Added comments and removed unused methods
1 parent 3cfe101 commit 896292d

File tree

1 file changed

+28
-57
lines changed

1 file changed

+28
-57
lines changed

src/MongoDB.Driver/Core/Connections/Socks5Helper.cs

Lines changed: 28 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,24 @@ internal static class Socks5Helper
7575
// | 1 | 1 | X'00' | 1 | Variable | 2 |
7676
// +----+-----+-------+------+----------+----------+
7777

78+
//General use constants
7879
private const byte ProtocolVersion5 = 0x05;
79-
private const byte SubnegotiationVersion = 0x01;
80+
private const byte Socks5Success = 0x00;
81+
private const byte Reserved = 0x00;
8082
private const byte CmdConnect = 0x01;
83+
84+
//Auth constants
8185
private const byte MethodNoAuth = 0x00;
8286
private const byte MethodUsernamePassword = 0x02;
87+
private const byte SubnegotiationVersion = 0x01;
88+
89+
//Address type constants
8390
private const byte AddressTypeIPv4 = 0x01;
84-
private const byte AddressTypeDomain = 0x03;
8591
private const byte AddressTypeIPv6 = 0x04;
86-
private const byte Socks5Success = 0x00;
92+
private const byte AddressTypeDomain = 0x03;
8793

88-
private const int BufferSize = 512;
94+
// Largest possible message size when using username and password auth.
95+
private const int BufferSize = 513;
8996

9097
public static void PerformSocks5Handshake(Stream stream, EndPoint endPoint, Socks5AuthenticationSettings authenticationSettings, CancellationToken cancellationToken)
9198
{
@@ -101,9 +108,10 @@ public static void PerformSocks5Handshake(Stream stream, EndPoint endPoint, Sock
101108
stream.ReadBytes(buffer, 0, 2, cancellationToken);
102109
var acceptsUsernamePasswordAuth = ProcessGreetingResponse(buffer, useAuth);
103110

111+
// If we have username and password, but the proxy doesn't need them, we skip.
104112
if (useAuth && acceptsUsernamePasswordAuth)
105113
{
106-
var authenticationRequestLength = CreateAuthenticationRequest(buffer, authenticationSettings, cancellationToken);
114+
var authenticationRequestLength = CreateAuthenticationRequest(buffer, authenticationSettings);
107115
stream.Write(buffer, 0, authenticationRequestLength);
108116

109117
stream.ReadBytes(buffer, 0, 2, cancellationToken);
@@ -137,9 +145,10 @@ public static async Task PerformSocks5HandshakeAsync(Stream stream, EndPoint end
137145
await stream.ReadBytesAsync(buffer, 0, 2, cancellationToken).ConfigureAwait(false);
138146
var acceptsUsernamePasswordAuth = ProcessGreetingResponse(buffer, useAuth);
139147

148+
// If we have username and password, but the proxy doesn't need them, we skip.
140149
if (useAuth && acceptsUsernamePasswordAuth)
141150
{
142-
var authenticationRequestLength = CreateAuthenticationRequest(buffer, authenticationSettings, cancellationToken);
151+
var authenticationRequestLength = CreateAuthenticationRequest(buffer, authenticationSettings);
143152
await stream.WriteAsync(buffer, 0, authenticationRequestLength, cancellationToken).ConfigureAwait(false);
144153

145154
await stream.ReadBytesAsync(buffer, 0, 2, cancellationToken).ConfigureAwait(false);
@@ -163,6 +172,7 @@ private static int CreateGreetingRequest(byte[] buffer, bool useAuth)
163172
{
164173
buffer[0] = ProtocolVersion5;
165174

175+
//buffer[1] is the number of methods supported by the client.
166176
if (!useAuth)
167177
{
168178
buffer[1] = 1;
@@ -179,8 +189,8 @@ private static int CreateGreetingRequest(byte[] buffer, bool useAuth)
179189
private static bool ProcessGreetingResponse(byte[] buffer, bool useAuth)
180190
{
181191
VerifyProtocolVersion(buffer[0]);
182-
var method = buffer[1];
183-
if (method == MethodUsernamePassword)
192+
var acceptedMethod = buffer[1];
193+
if (acceptedMethod == MethodUsernamePassword)
184194
{
185195
if (!useAuth)
186196
{
@@ -190,20 +200,21 @@ private static bool ProcessGreetingResponse(byte[] buffer, bool useAuth)
190200
return true;
191201
}
192202

193-
if (method != MethodNoAuth)
203+
if (acceptedMethod != MethodNoAuth)
194204
{
195205
throw new IOException("SOCKS5 proxy requires unsupported authentication method.");
196206
}
197207

198208
return false;
199209
}
200210

201-
private static int CreateAuthenticationRequest(byte[] buffer, Socks5AuthenticationSettings authenticationSettings, CancellationToken cancellationToken)
211+
private static int CreateAuthenticationRequest(byte[] buffer, Socks5AuthenticationSettings authenticationSettings)
202212
{
203213
var usernamePasswordAuthenticationSettings = (Socks5AuthenticationSettings.UsernamePasswordAuthenticationSettings)authenticationSettings;
204214
var proxyUsername = usernamePasswordAuthenticationSettings.Username;
205215
var proxyPassword = usernamePasswordAuthenticationSettings.Password;
206216

217+
// We need to add version, username.length, username, password.length, password (in this order)
207218
buffer[0] = SubnegotiationVersion;
208219
var usernameLength = EncodeString(proxyUsername, buffer, 2, nameof(proxyUsername));
209220
buffer[1] = usernameLength;
@@ -221,56 +232,12 @@ private static void ProcessAuthenticationResponse(byte[] buffer)
221232
}
222233
}
223234

224-
private static void PerformUsernamePasswordAuth(Stream stream, byte[] buffer, Socks5AuthenticationSettings authenticationSettings, CancellationToken cancellationToken)
225-
{
226-
var usernamePasswordAuthenticationSettings = (Socks5AuthenticationSettings.UsernamePasswordAuthenticationSettings)authenticationSettings;
227-
var proxyUsername = usernamePasswordAuthenticationSettings.Username;
228-
var proxyPassword = usernamePasswordAuthenticationSettings.Password;
229-
230-
buffer[0] = SubnegotiationVersion;
231-
var usernameLength = EncodeString(proxyUsername, buffer, 2, nameof(proxyUsername));
232-
buffer[1] = usernameLength;
233-
var passwordLength = EncodeString(proxyPassword, buffer, 3 + usernameLength, nameof(proxyPassword));
234-
buffer[2 + usernameLength] = (byte)passwordLength;
235-
236-
var authLength = 3 + usernameLength + passwordLength;
237-
stream.Write(buffer, 0, authLength);
238-
239-
stream.ReadBytes(buffer, 0, 2, cancellationToken);
240-
if (buffer[0] != SubnegotiationVersion || buffer[1] != Socks5Success)
241-
{
242-
throw new IOException("SOCKS5 authentication failed.");
243-
}
244-
}
245-
246-
private static async Task PerformUsernamePasswordAuthAsync(Stream stream, byte[] buffer, Socks5AuthenticationSettings authenticationSettings, CancellationToken cancellationToken)
247-
{
248-
var usernamePasswordAuthenticationSettings = (Socks5AuthenticationSettings.UsernamePasswordAuthenticationSettings)authenticationSettings;
249-
var proxyUsername = usernamePasswordAuthenticationSettings.Username;
250-
var proxyPassword = usernamePasswordAuthenticationSettings.Password;
251-
252-
buffer[0] = SubnegotiationVersion;
253-
var usernameLength = EncodeString(proxyUsername, buffer, 2, nameof(proxyUsername));
254-
buffer[1] = usernameLength;
255-
var passwordLength = EncodeString(proxyPassword, buffer, 3 + usernameLength, nameof(proxyPassword));
256-
buffer[2 + usernameLength] = passwordLength;
257-
258-
var authLength = 3 + usernameLength + passwordLength;
259-
await stream.WriteAsync(buffer, 0, authLength, cancellationToken).ConfigureAwait(false);
260-
261-
await stream.ReadBytesAsync(buffer, 0, 2, cancellationToken).ConfigureAwait(false);
262-
if (buffer[0] != SubnegotiationVersion || buffer[1] != Socks5Success)
263-
{
264-
throw new IOException("SOCKS5 authentication failed.");
265-
}
266-
}
267-
268235
private static int CreateConnectRequest(byte[] buffer, string targetHost, int targetPort)
269236
{
270237
buffer[0] = ProtocolVersion5;
271238
buffer[1] = CmdConnect;
272-
buffer[2] = 0x00;
273-
var addressLength = 0;
239+
buffer[2] = Reserved;
240+
int addressLength;
274241

275242
if (IPAddress.TryParse(targetHost, out var ip))
276243
{
@@ -310,9 +277,13 @@ private static int ProcessConnectResponse(byte[] buffer)
310277

311278
if (buffer[1] != Socks5Success)
312279
{
313-
throw new IOException($"SOCKS5 connect failed");
280+
throw new IOException($"SOCKS5 connect failed"); //TODO Need to add the reason here.
314281
}
315282

283+
// We skip the last bytes of the response as we do not need them.
284+
// We skip length(dst.address) + length(dst.port) - 1 --- length(dst.port) is always 2
285+
// -1 because we already ready the first byte of the address type
286+
// (used for the variable length domain-type addresses)
316287
return buffer[3] switch
317288
{
318289
AddressTypeIPv4 => 5,

0 commit comments

Comments
 (0)