diff options
author | The Bundler Bot <bot@bundler.io> | 2017-08-28 19:16:06 +0000 |
---|---|---|
committer | The Bundler Bot <bot@bundler.io> | 2017-08-28 19:16:06 +0000 |
commit | 6ce61e7c6060d1d7a45a131031be472aa25e1d7e (patch) | |
tree | e9b0bdff68a460c4c45c3c7d075c121f68897b68 | |
parent | 766f412f338edb1502c62fb4cc2a6ae6678f55d4 (diff) | |
parent | dbac58918e75f8e7df9875f7363985cd3a1fae01 (diff) | |
download | bundler-6ce61e7c6060d1d7a45a131031be472aa25e1d7e.tar.gz |
Auto merge of #5638 - bundler:seg-warn-old-tls, r=indirect
Warn when making an outdated TLS connection to rubygems.org
Right now, output looks like
```
Your Ruby version does not support TLSv1.1 or newer, which will be required to connect to https://index.rubygems.org by June 2018.
Fetching gem metadata from https://rubygems.org/...........
Fetching version metadata from https://rubygems.org/..
Resolving dependencies...
Using rake 11.3.0
Using automatiek 0.1.2 from source at `.`
Using rspec-support 3.5.0
Using diff-lcs 1.3
Using bundler 1.15.0.pre.3
Using rspec-core 3.5.4
Using rspec-expectations 3.5.0
Using rspec-mocks 3.5.0
Using rspec 3.5.0
Bundle updated!
```
Obviously this requires tests, and also backing out forcing the TLS version (which I did to make testing easier). The message could also use improvement, but I figured I'd ask for input from @indirect and @dwradcliffe
-rw-r--r-- | lib/bundler/fetcher.rb | 4 | ||||
-rw-r--r-- | lib/bundler/vendored_persistent.rb | 33 | ||||
-rw-r--r-- | spec/bundler/vendored_persistent_spec.rb | 72 |
3 files changed, 107 insertions, 2 deletions
diff --git a/lib/bundler/fetcher.rb b/lib/bundler/fetcher.rb index 5a9617c60a..03ff528826 100644 --- a/lib/bundler/fetcher.rb +++ b/lib/bundler/fetcher.rb @@ -238,7 +238,7 @@ module Bundler Bundler.settings[:ssl_client_cert] raise SSLError if needs_ssl && !defined?(OpenSSL::SSL) - con = Bundler::Persistent::Net::HTTP::Persistent.new "bundler", :ENV + con = PersistentHTTP.new "bundler", :ENV if gem_proxy = Bundler.rubygems.configuration[:http_proxy] con.proxy = URI.parse(gem_proxy) if gem_proxy != :no_proxy end @@ -277,7 +277,7 @@ module Bundler Timeout::Error, EOFError, SocketError, Errno::ENETDOWN, Errno::ENETUNREACH, Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EAGAIN, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError, - Bundler::Persistent::Net::HTTP::Persistent::Error, Zlib::BufError, Errno::EHOSTUNREACH + PersistentHTTP::Error, Zlib::BufError, Errno::EHOSTUNREACH ].freeze def bundler_cert_store diff --git a/lib/bundler/vendored_persistent.rb b/lib/bundler/vendored_persistent.rb index ecbf21e30a..190fed58e5 100644 --- a/lib/bundler/vendored_persistent.rb +++ b/lib/bundler/vendored_persistent.rb @@ -16,3 +16,36 @@ module Bundler end end require "bundler/vendor/net-http-persistent/lib/net/http/persistent" + +module Bundler + class PersistentHTTP < Persistent::Net::HTTP::Persistent + def connection_for(uri) + connection = super + warn_old_tls_version_rubygems_connection(uri, connection) + connection + end + + def warn_old_tls_version_rubygems_connection(uri, connection) + return unless connection.use_ssl? + return unless (uri.host || "").end_with?("rubygems.org") + + socket = connection.instance_variable_get(:@socket) + socket_io = socket.io + return unless socket_io.respond_to?(:ssl_version) + ssl_version = socket_io.ssl_version + + case ssl_version + when /TLSv([\d\.]+)/ + version = Gem::Version.new($1) + if version < Gem::Version.new("1.2") + Bundler.ui.warn \ + "Warning: Your Ruby version is compiled against a copy of OpenSSL that is very old. " \ + "Starting in January 2018, RubyGems.org will refuse connection requests from these " \ + "very old versions of OpenSSL. If you will need to continue installing gems after " \ + "January 2018, please follow this guide to upgrade: http://ruby.to/tls-outdated.", + :wrap => true + end + end + end + end +end diff --git a/spec/bundler/vendored_persistent_spec.rb b/spec/bundler/vendored_persistent_spec.rb new file mode 100644 index 0000000000..b1b091f2c5 --- /dev/null +++ b/spec/bundler/vendored_persistent_spec.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require "spec_helper" +require "bundler/vendored_persistent" + +RSpec.describe Bundler::PersistentHTTP do + describe "#warn_old_tls_version_rubygems_connection" do + let(:uri) { "https://index.rubygems.org" } + let(:connection) { instance_double(subject.http_class) } + let(:tls_version) { "TLSv1.2" } + let(:socket) { double("Socket") } + let(:socket_io) { double("SocketIO") } + + before do + allow(connection).to receive(:use_ssl?).and_return(!tls_version.nil?) + allow(socket).to receive(:io).and_return(socket_io) + connection.instance_variable_set(:@socket, socket) + + if tls_version + allow(socket_io).to receive(:ssl_version).and_return(tls_version) + end + end + + shared_examples_for "does not warn" do + it "does not warn" do + allow(Bundler.ui).to receive(:warn).never + subject.warn_old_tls_version_rubygems_connection(URI(uri), connection) + end + end + + shared_examples_for "does warn" do |*expected| + it "warns" do + expect(Bundler.ui).to receive(:warn).with(*expected) + subject.warn_old_tls_version_rubygems_connection(URI(uri), connection) + end + end + + context "an HTTPS uri with TLSv1.2" do + include_examples "does not warn" + end + + context "without SSL" do + let(:tls_version) { nil } + + include_examples "does not warn" + end + + context "with a different TLD" do + let(:uri) { "https://foo.bar" } + include_examples "does not warn" + + context "and an outdated TLS version" do + let(:tls_version) { "TLSv1" } + include_examples "does not warn" + end + end + + context "with a nonsense TLS version" do + let(:tls_version) { "BlahBlah2.0Blah" } + include_examples "does not warn" + end + + context "with an outdated TLS version" do + let(:tls_version) { "TLSv1" } + include_examples "does warn", + "Warning: Your Ruby version is compiled against a copy of OpenSSL that is very old. " \ + "Starting in January 2018, RubyGems.org will refuse connection requests from these very old versions of OpenSSL. " \ + "If you will need to continue installing gems after January 2018, please follow this guide to upgrade: http://ruby.to/tls-outdated.", + :wrap => true + end + end +end |