Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Make HttpClient on Unix treat SslProtocols.None as meaning system defaults #13527

Merged
merged 1 commit into from
Nov 10, 2016

Conversation

stephentoub
Copy link
Member

Per discussion at #13075 (comment). Prior to this change, specifying SslProtocols.None for HttpClientHandler.SslProtocols meant that the default hardcoded into System.Net.Http should be used. This changes it to mean the underlying system's default, i.e. that of libcurl and OpenSSL on Unix.

cc: @bartonjs, @CIPop, @davidsh

…aults

This way, as libcurl and OpenSSL are updated to support newer protocols and disable older ones, we inherit the latest settings.
Copy link
Member

@CIPop CIPop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few questions.
LGTM

Thanks @stephentoub !

@@ -95,7 +95,12 @@ internal static void SetSslOptions(EasyRequest easy, ClientCertificateOption cli
private static void SetSslVersion(EasyRequest easy, IntPtr sslCtx = default(IntPtr))
{
// Get the requested protocols.
System.Security.Authentication.SslProtocols protocols = easy._handler.ActualSslProtocols;
SslProtocols protocols = easy._handler.SslProtocols;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this looks odd - why is the code accessing private members?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the question. Are you asking how it's accessing easy._handler? _handler is internal, not private.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks odd as it has the _ which, I thought, means private. If it's internal shouldn't it be capitalized and, even better, converted into a property to preserve encapsulation and the open-close principle? (easy.Handler instead of easy._handler)

Copy link
Member Author

@stephentoub stephentoub Nov 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's internal shouldn't it be capitalized

Our guidelines are that all non-public instance fields are prefixed with an underscore, regardless of private or internal.

and, even better, converted into a property to preserve encapsulation and the open-close principle? (easy.Handler instead of easy._handler)

My care level on that, for an internal implementation detail where this is essentially just a bag of state shared between different pieces of the same type, is basically zero. If you'd like to submit a PR to make the change, I'd be fine with it. Regardless, that naming exists well earlier than this change.

if (protocols == SslProtocols.None)
{
// Let libcurl use its defaults if None is set.
return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we know that Curl will use TLS1.2 by default? (Is there a test?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Note that newer versions of libcurl support the draft 1.3 as well.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thanks!

@stephentoub
Copy link
Member Author

@dotnet-bot test Outerloop Ubuntu14.04 Debug please
@dotnet-bot test Outerloop OSX Debug please

@stephentoub
Copy link
Member Author

@dotnet-bot test Outerloop OSX Debug please (package restore failure)

@stephentoub stephentoub merged commit 28e8fdf into dotnet:master Nov 10, 2016
@stephentoub stephentoub deleted the curl_defaults branch November 10, 2016 01:23
@stephentoub
Copy link
Member Author

@CIPop, @bartonjs, this change broke a few of our outerloop tests on CentOS and RedHat. The purpose of this change was to use whatever the underlying platform defaults to, but libcurl prior to 7.39.0 included SSLv3 as an allowed protocol, and the version of libcurl used in CI on RedHat and CentOS is older than that. I see three options:

  1. Leave it as-is, in which case SSLv3 will be allowed prior to 7.39.0.
  2. Explicitly map SslProtocols.None to CURL_SSLVERSION_TLSv1, which says it can use any TLS 1.x version.
  3. In the shim, detect the version, and if it's less than 7.39.0, initialize the allowed protocols for each easy handle to TLS 1.x (basically do (2) but only for older versions).

I'm leaning towards (3). Thoughts?

@bartonjs
Copy link
Member

If (3) is easy, I'd vote (3). If it's not, I'd vote (1). (If we had already had SystemDefault we probably wouldn't be looking at this at all, which is my basis for (1). Like, I don't expect us to necessarily revisit this when we start ensuring no one is hard-coding 1.0 as allowed...)

@CIPop
Copy link
Member

CIPop commented Nov 15, 2016

In NetFX we leave the decision to the OS. Windows includes SSL3 within the defaults for versions < Win10 1607: https://support.microsoft.com/en-us/kb/3154518 (see the table under More Information).

Windows APIs don't have the ability to remove protocols (we're discussing options with Schannel). If CURL has this option already, we should always remove unwanted protocols (SSL2, 3) regardless of the version while ensuring that new protocols are allowed (TLS1.3, future non-TLS protocols, etc).

@stephentoub
Copy link
Member Author

If CURL has this option already, we should always remove unwanted protocols (SSL2, 3) regardless of the version while ensuring that new protocols are allowed (TLS1.3, future non-TLS protocols, etc).

OpenSSL has that ability, and if you're using libcurl with an OpenSSL backend, we already do so (as part of this change). The issue is with libcurl with some other backend (which is the case in our CI environment with RedHat and CentOS). We don't have the ability to tell libcurl itself to remove protocols, so the best we could do is say to use TLS 1.x; that would remove SSLv3, but it would also prevent future non-TLS protocols.

Thanks both for the feedback. Sounds like I should just leave the implementation as-is and fix the tests accordingly.

@karelz karelz modified the milestone: 1.2.0 Dec 3, 2016
@karelz karelz added os-linux Linux OS (any supported distro) and removed X-Plat labels Mar 8, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Net os-linux Linux OS (any supported distro)
Projects
None yet
6 participants