bundler 1.2.4 → 1.2.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 1.2.5 (Feb 24, 2013)
2
+
3
+ Bugfixes:
4
+
5
+ - install Gemfiles with HTTP sources even without OpenSSL present
6
+ - display CerficateFailureError message in full
7
+
1
8
  ## 1.2.4 (Feb 12, 2013)
2
9
 
3
10
  Features:
@@ -4,10 +4,24 @@ require 'bundler/vendored_persistent'
4
4
  module Bundler
5
5
  # Handles all the fetching with the rubygems server
6
6
  class Fetcher
7
+ # How many redirects to allew in one request
7
8
  REDIRECT_LIMIT = 5
8
9
  # how long to wait for each gemcutter API call
9
- API_TIMEOUT = 10
10
- class FallbackError < Bundler::HTTPError; end
10
+ API_TIMEOUT = 10
11
+
12
+ # This error is raised if the API returns a 413 (only printed in verbose)
13
+ class FallbackError < HTTPError; end
14
+ # This is the error raised if OpenSSL fails the cert verification
15
+ class CertificateFailureError < HTTPError
16
+ def initialize(remote_uri)
17
+ super "Could not verify the SSL certificate for #{remote_uri}.\nThere" \
18
+ " is a chance you are experiencing a man-in-the-middle attack, but" \
19
+ " most likely your system doesn't have the CA certificates needed" \
20
+ " for verification. For information about OpenSSL certificates, see" \
21
+ " bit.ly/ssl-certs. To connect without using SSL, edit your Gemfile" \
22
+ " sources and change 'https' to 'http'."
23
+ end
24
+ end
11
25
 
12
26
  attr_reader :has_api
13
27
 
@@ -46,8 +60,19 @@ module Bundler
46
60
  def initialize(remote_uri)
47
61
  @remote_uri = remote_uri
48
62
  @has_api = true # will be set to false if the rubygems index is ever fetched
49
- @@connection ||= Net::HTTP::Persistent.new nil, :ENV
50
- @@connection.read_timeout = API_TIMEOUT
63
+
64
+ if USE_PERSISTENT
65
+ @connection ||= Net::HTTP::Persistent.new 'bundler', :ENV
66
+ else
67
+ if @remote_uri.scheme == "https"
68
+ raise Bundler::HTTPError, "Could not load OpenSSL.\n" \
69
+ "You must recompile Ruby with OpenSSL support or change the sources in your " \
70
+ "Gemfile from 'https' to 'http'. Instructions for compiling with OpenSSL " \
71
+ "using RVM are available at rvm.io/packages/openssl."
72
+ end
73
+ @connection ||= Net::HTTP.new(@remote_uri.host, @remote_uri.port)
74
+ end
75
+ @connection.read_timeout = API_TIMEOUT
51
76
 
52
77
  Socket.do_not_reverse_lookup = true
53
78
  end
@@ -66,8 +91,9 @@ module Bundler
66
91
  # return the specs in the bundler format as an index
67
92
  def specs(gem_names, source)
68
93
  index = Index.new
94
+ use_full_source_index = !gem_names || @remote_uri.scheme == "file" || Bundler::Fetcher.disable_endpoint
69
95
 
70
- if !gem_names || @remote_uri.scheme == "file" || Bundler::Fetcher.disable_endpoint
96
+ if use_full_source_index
71
97
  Bundler.ui.info "Fetching source index from #{strip_user_pass_from_uri(@remote_uri)}"
72
98
  specs = fetch_all_remote_specs
73
99
  else
@@ -110,6 +136,9 @@ module Bundler
110
136
  end
111
137
 
112
138
  index
139
+ rescue OpenSSL::SSL::SSLError
140
+ Bundler.ui.info "" if !use_full_source_index # newline after dots
141
+ raise CertificateFailureError.new(strip_user_pass_from_uri(@remote_uri))
113
142
  end
114
143
 
115
144
  # fetch index
@@ -133,16 +162,25 @@ module Bundler
133
162
 
134
163
  private
135
164
 
165
+ HTTP_ERRORS = [
166
+ Timeout::Error, EOFError, SocketError,
167
+ Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EAGAIN,
168
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError
169
+ ]
170
+ HTTP_ERRORS << Net::HTTP::Persistent::Error if defined?(Net::HTTP::Persistent)
171
+
136
172
  def fetch(uri, counter = 0)
137
173
  raise HTTPError, "Too many redirects" if counter >= REDIRECT_LIMIT
138
174
 
139
175
  begin
140
176
  Bundler.ui.debug "Fetching from: #{uri}"
141
- response = nil
142
- response = @@connection.request(uri)
143
- rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
144
- SocketError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
145
- Net::HTTP::Persistent::Error, Net::ProtocolError => e
177
+ if USE_PERSISTENT
178
+ response = @connection.request(uri)
179
+ else
180
+ req = Net::HTTP::Get.new uri.request_uri
181
+ response = @connection.request(req)
182
+ end
183
+ rescue *HTTP_ERRORS
146
184
  raise HTTPError, "Network error while fetching #{uri}"
147
185
  end
148
186
 
@@ -216,8 +254,12 @@ module Bundler
216
254
  rescue Gem::RemoteFetcher::FetchError
217
255
  Bundler.ui.debug "Could not fetch prerelease specs from #{strip_user_pass_from_uri(@remote_uri)}"
218
256
  end
219
- rescue Gem::RemoteFetcher::FetchError
220
- raise HTTPError, "Could not reach #{strip_user_pass_from_uri(@remote_uri)}"
257
+ rescue Gem::RemoteFetcher::FetchError => e
258
+ if e.message.match("certificate verify failed")
259
+ raise CertificateFailureError.new(strip_user_pass_from_uri(@remote_uri))
260
+ else
261
+ raise HTTPError, "Could not fetch specs from #{strip_user_pass_from_uri(@remote_uri)}"
262
+ end
221
263
  end
222
264
 
223
265
  return spec_list
@@ -1,3 +1,15 @@
1
- vendor = File.expand_path('../vendor', __FILE__)
2
- $:.unshift(vendor) unless $:.include?(vendor)
3
- require 'net/http/persistent'
1
+ begin
2
+ require 'openssl'
3
+ OpenSSL # ensure OpenSSL is loaded
4
+
5
+ vendor = File.expand_path('../vendor', __FILE__)
6
+ $:.unshift(vendor) unless $:.include?(vendor)
7
+ require 'net/http/persistent'
8
+
9
+ USE_PERSISTENT = true
10
+
11
+ rescue LoadError, NameError => e
12
+ require 'net/http'
13
+ USE_PERSISTENT = false
14
+
15
+ end
@@ -2,5 +2,5 @@ module Bundler
2
2
  # We're doing this because we might write tests that deal
3
3
  # with other versions of bundler and we are unsure how to
4
4
  # handle this better.
5
- VERSION = "1.2.4" unless defined?(::Bundler::VERSION)
5
+ VERSION = "1.2.5" unless defined?(::Bundler::VERSION)
6
6
  end
@@ -483,4 +483,47 @@ OUTPUT
483
483
  end
484
484
  end
485
485
 
486
+ context "when SSL certificate verification fails" do
487
+ it "explains what is going on" do
488
+ # Install a monkeypatch that reproduces the effects of openssl raising
489
+ # a certificate validation error at the appropriate moment.
490
+ gemfile <<-G
491
+ class Bundler::Fetcher
492
+ def fetch_all_remote_specs
493
+ raise OpenSSL::SSL::SSLError, "Certificate invalid"
494
+ end
495
+ end
496
+
497
+ source "#{source_uri.gsub(/http/, 'https')}"
498
+ gem "rack"
499
+ G
500
+
501
+ bundle :install
502
+ expect(out).to match(/could not verify the SSL certificate/i)
503
+ end
504
+ end
505
+
506
+ context ".gemrc with sources is present" do
507
+ before do
508
+ File.open(home('.gemrc'), 'w') do |file|
509
+ file.puts({:sources => ["https://rubygems.org"]}.to_yaml)
510
+ end
511
+ end
512
+
513
+ after do
514
+ home('.gemrc').rmtree
515
+ end
516
+
517
+ it "uses other sources declared in the Gemfile" do
518
+ gemfile <<-G
519
+ source "#{source_uri}"
520
+ gem 'rack'
521
+ G
522
+
523
+ bundle "install", :exitstatus => true, :artifice => "endpoint_marshal_fail"
524
+
525
+ expect(exitstatus).to eq(0)
526
+ end
527
+ end
528
+
486
529
  end
@@ -310,7 +310,7 @@ describe "bundle install with gem sources" do
310
310
  G
311
311
 
312
312
  bundle :install
313
- out.should include("Could not reach http://localhost:9384/")
313
+ out.should include("Could not fetch specs from http://localhost:9384/")
314
314
  out.should_not include("file://")
315
315
  end
316
316
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 1.2.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2013-02-14 00:00:00.000000000 Z
15
+ date: 2013-02-25 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: ronn
@@ -276,7 +276,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
276
276
  version: 1.3.6
277
277
  requirements: []
278
278
  rubyforge_project: bundler
279
- rubygems_version: 1.8.24
279
+ rubygems_version: 1.8.23
280
280
  signing_key:
281
281
  specification_version: 3
282
282
  summary: The best way to manage your application's dependencies
@@ -362,4 +362,3 @@ test_files:
362
362
  - spec/update/gems_spec.rb
363
363
  - spec/update/git_spec.rb
364
364
  - spec/update/source_spec.rb
365
- has_rdoc: