-
Notifications
You must be signed in to change notification settings - Fork 1.3k
CSHARP-734: SOCKS5 Proxy Support #1731
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
tests/MongoDB.Driver.Tests/Core/Configuration/ConnectionStringTests.cs
Outdated
Show resolved
Hide resolved
src/MongoDB.Driver/Core/Connections/Socks5AuthenticationSettings.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MongoUrlBuilder.ToString
is being used to build the Url from provided parameters, so having passwords there is probably the expected behavior (I suppose we ought to have another method for that, something like BuildUrl
). However this class is user-facing settings class, there is a bigger chances it could be converted to string and logged or even worse outputted as a part of exception. I've checked MongoClientSettings
- it does not look like it can leak passwords in the similar way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have Ensure.IsNullOrBetween if this is what you are looking for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great overall!
src/MongoDB.Driver/Core/Connections/Socks5ProxySettingsBuilder.cs
Outdated
Show resolved
Hide resolved
tests/MongoDB.Driver.Tests/Specifications/socks5-support/Socks5SupportProseTests.cs
Outdated
Show resolved
Hide resolved
3b3701b
to
395a74d
Compare
tests/MongoDB.Driver.Tests/Specifications/socks5-support/Socks5SupportProseTests.cs
Show resolved
Hide resolved
src/MongoDB.Driver/Core/Configuration/Socks5ProxyStreamSettings.cs
Outdated
Show resolved
Hide resolved
src/MongoDB.Driver/Core/Configuration/Socks5ProxyStreamSettings.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few minor comment + unaddressed comment
tests/MongoDB.Driver.Tests/Core/Connections/Socks5ProxySettingsTest.cs
Outdated
Show resolved
Hide resolved
0d0d06f
to
fc7c610
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As i understand, If the server cannot find any acceptable authentication methods offered by the client, it replies with 0xFF
("no acceptable methods"). The only way the server can select username/password (0x02)
is if the client offered it. A case where the server replies with 0x02
but the client did not offer it should not occur in a compliant implementation - that would indicate a protocol violation by the server.
To handle this defensively, what do you think about throwing an error such as:
"Unexpected server response: server replied with but expected one of "?
This would highlight the unexpected behavior to users and, in edge cases where a proxy forces 0x02
, might help discourage clients from inadvertently sending credentials.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this should not happen unless the server is behaving badly, I'm trying to be defensive here.
Regarding the message, I agree, it's a little vague, I'll try to rephrase it so it highlights the issue better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The method signature looks generic, but internally it casts from Socks5AuthenticationSettings
to UsernamePasswordAuthenticationSettings
, so it effectively only works with the 0x02
method. Would it make sense to make the signature explicit (e.g. only accept UsernamePasswordAuthenticationSettings
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can keep the method generic, but throw an exception if the authentication is not for the correct type (that should not happen), so we keep the method open to extension in the future if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the RFC-1929, authentication only fails when buffer[1] != Socks5Success
. If buffer[0] != SubnegotiationVersion
(despite the client specifying 1), that suggests a protocol-noncompliant response from the server/proxy.
The RFC states:
"The VER field contains the current version of the subnegotiation, which is X'01'."
I'd propose making the failure reason explicit here. When buffer[0] != SubnegotiationVersion
, we should indicate that this is an unexpected server response rather than a credentials error. For example: "SOCKS5 auth subnegotiation: unexpected VER from server"
. This would also make troubleshooting easier. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Casting username or password length to byte works correctly if the int
values are ≤ 0xFF
. Otherwise, we end up reporting incorrect lengths and writing more bytes than the proxy expects, which could silently corrupt data and result in unexpected responses from the server.
I’d propose enforcing a maximum length (in UTF-8 bytes, not chars/code points) for username and password in UsernamePasswordAuthenticationSettings
. That way, it is validate at the API edge and fail fast with a clear error message.
The same applies to var hostLength = EncodeString(targetHost, buffer, 5, nameof(targetHost));
. Per RFC 1035 §2.3.4, the maximum domain name length is 255 bytes (0xFF), which i'd propose enforcing in Socks5ProxySettings
.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what the checked
statement is doing, it will throw an OverflowException
in case the value cannot be safely converted to byte
.
I agree that probably we can be a little more user friendly here, instead of throwing a generic exception. I'll try to add some more validation to our settings class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we provide a more user-friendly message here indicating what type of error the server returned?
The RFC defines the following failure reply types:
0x01 General SOCKS server failure
0x02 Connection not allowed by ruleset
0x03 Network unreachable
0x04 Host unreachable
0x05 Connection refused
0x06 TTL expired
0x07 Command not supported
0x08 Address type not supported
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense! Added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few minor comments
tests/MongoDB.Driver.Tests/Core/Connections/Socks5AuthenticationSettingsTests.cs
Outdated
Show resolved
Hide resolved
tests/MongoDB.Driver.Tests/Core/Connections/Socks5AuthenticationSettingsTests.cs
Show resolved
Hide resolved
tests/MongoDB.Driver.Tests/Core/Connections/Socks5AuthenticationSettingsTests.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM + few minor comments
src/MongoDB.Driver/Core/Connections/Socks5ProxyStreamFactory.cs
Outdated
Show resolved
Hide resolved
src/MongoDB.Driver/Core/Connections/Socks5ProxyStreamFactory.cs
Outdated
Show resolved
Hide resolved
tests/MongoDB.Driver.Tests/Core/Connections/Socks5AuthenticationSettingsTests.cs
Outdated
Show resolved
Hide resolved
tests/MongoDB.Driver.Tests/Core/Connections/Socks5AuthenticationSettingsTests.cs
Outdated
Show resolved
Hide resolved
tests/MongoDB.Driver.Tests/Core/Connections/Socks5AuthenticationSettingsTests.cs
Outdated
Show resolved
Hide resolved
tests/MongoDB.Driver.Tests/Core/Connections/Socks5AuthenticationSettingsTests.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
tests/MongoDB.Driver.Tests/Core/Connections/Socks5AuthenticationSettingsTests.cs
Outdated
Show resolved
Hide resolved
tests/MongoDB.Driver.Tests/Core/Connections/Socks5AuthenticationSettingsTests.cs
Outdated
Show resolved
Hide resolved
tests/MongoDB.Driver.Tests/Core/Connections/Socks5AuthenticationSettingsTests.cs
Outdated
Show resolved
Hide resolved
654c59d
to
b4d184a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Uh oh!
There was an error while loading. Please reload this page.
No description provided.