Bug #15384 ยป unify-certification-bundler.patch
lib/bundler/fetcher.rb | ||
---|---|---|
require "bundler/vendored_persistent"
|
||
require "cgi"
|
||
require "rbconfig"
|
||
require "securerandom"
|
||
require "zlib"
|
||
... | ... | |
end
|
||
else
|
||
store.set_default_paths
|
||
certs = File.expand_path("../ssl_certs/*/*.pem", __FILE__)
|
||
rubygems_certs_dir = File.expand_path("../../rubygems/ssl_certs", __FILE__)
|
||
unless File.exists?(rubygems_certs_dir)
|
||
rubygems_certs_dir = File.join(RbConfig::CONFIG["rubylibdir"], "rubygems", "ssl_certs")
|
||
end
|
||
certs = File.join(rubygems_certs_dir, "*", "*.pem")
|
||
Dir.glob(certs).each {|c| store.add_file c }
|
||
end
|
||
store
|
/dev/null | ||
---|---|---|
# Ignore all files in this directory
|
/dev/null | ||
---|---|---|
# frozen_string_literal: true
|
||
require "bundler/vendored_fileutils"
|
||
require "net/https"
|
||
require "openssl"
|
||
module Bundler
|
||
module SSLCerts
|
||
class CertificateManager
|
||
attr_reader :bundler_cert_path, :bundler_certs, :rubygems_certs
|
||
def self.update_from!(rubygems_path)
|
||
new(rubygems_path).update!
|
||
end
|
||
def initialize(rubygems_path = nil)
|
||
if rubygems_path
|
||
rubygems_cert_path = File.join(rubygems_path, "lib/rubygems/ssl_certs")
|
||
@rubygems_certs = certificates_in(rubygems_cert_path)
|
||
end
|
||
@bundler_cert_path = File.expand_path("..", __FILE__)
|
||
@bundler_certs = certificates_in(bundler_cert_path)
|
||
end
|
||
def up_to_date?
|
||
rubygems_certs.all? do |rc|
|
||
bundler_certs.find do |bc|
|
||
File.basename(bc) == File.basename(rc) && FileUtils.compare_file(bc, rc)
|
||
end
|
||
end
|
||
end
|
||
def update!
|
||
return if up_to_date?
|
||
FileUtils.rm bundler_certs
|
||
FileUtils.cp rubygems_certs, bundler_cert_path
|
||
end
|
||
def connect_to(host)
|
||
http = Net::HTTP.new(host, 443)
|
||
http.use_ssl = true
|
||
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
||
http.cert_store = store
|
||
http.head("/")
|
||
end
|
||
private
|
||
def certificates_in(path)
|
||
Dir[File.join(path, "**/*.pem")].sort
|
||
end
|
||
def store
|
||
@store ||= begin
|
||
store = OpenSSL::X509::Store.new
|
||
bundler_certs.each do |cert|
|
||
store.add_file cert
|
||
end
|
||
store
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
/dev/null | ||
---|---|---|
-----BEGIN CERTIFICATE-----
|
||
MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
|
||
A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
|
||
b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
|
||
MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
|
||
YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
|
||
aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
|
||
jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
|
||
xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
|
||
1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
|
||
snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
|
||
U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
|
||
9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
|
||
BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
|
||
AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
|
||
yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
|
||
38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
|
||
AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
|
||
DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
|
||
HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
|
||
-----END CERTIFICATE-----
|
/dev/null | ||
---|---|---|
-----BEGIN CERTIFICATE-----
|
||
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
|
||
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
||
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
|
||
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
|
||
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
|
||
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
|
||
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
|
||
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
|
||
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
|
||
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
|
||
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
|
||
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
|
||
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
|
||
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
|
||
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
|
||
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
|
||
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
|
||
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
|
||
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
|
||
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
|
||
+OkuE6N36B9K
|
||
-----END CERTIFICATE-----
|
/dev/null | ||
---|---|---|
-----BEGIN CERTIFICATE-----
|
||
MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
|
||
MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
|
||
IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
|
||
MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
|
||
FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
|
||
bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
|
||
dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
|
||
H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
|
||
uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
|
||
mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
|
||
a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
|
||
E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
|
||
WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
|
||
VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
|
||
Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
|
||
cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
|
||
IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
|
||
AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
|
||
YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
|
||
6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
|
||
Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
|
||
c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
|
||
mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
|
||
-----END CERTIFICATE-----
|
/dev/null | ||
---|---|---|
# frozen_string_literal: true
|
||
require "bundler/ssl_certs/certificate_manager"
|
||
RSpec.describe Bundler::SSLCerts::CertificateManager do
|
||
let(:rubygems_path) { root }
|
||
let(:stub_cert) { File.join(root.to_s, "lib", "rubygems", "ssl_certs", "rubygems.org", "ssl-cert.pem") }
|
||
let(:rubygems_certs_dir) { File.join(root.to_s, "lib", "rubygems", "ssl_certs", "rubygems.org") }
|
||
subject { described_class.new(rubygems_path) }
|
||
# Pretend bundler root is rubygems root
|
||
before do
|
||
# Backing up rubygems ceriticates
|
||
FileUtils.mv(rubygems_certs_dir, rubygems_certs_dir + ".back") if ruby_core?
|
||
FileUtils.mkdir_p(rubygems_certs_dir)
|
||
FileUtils.touch(stub_cert)
|
||
end
|
||
after do
|
||
FileUtils.rm_rf(rubygems_certs_dir)
|
||
# Restore rubygems certificates
|
||
FileUtils.mv(rubygems_certs_dir + ".back", rubygems_certs_dir) if ruby_core?
|
||
end
|
||
describe "#update_from" do
|
||
let(:cert_manager) { double(:cert_manager) }
|
||
before { allow(described_class).to receive(:new).with(rubygems_path).and_return(cert_manager) }
|
||
it "should update the certs through a new certificate manager" do
|
||
allow(cert_manager).to receive(:update!)
|
||
expect(described_class.update_from!(rubygems_path)).to be_nil
|
||
end
|
||
end
|
||
describe "#initialize" do
|
||
it "should set bundler_cert_path as path of the subdir with bundler ssl certs" do
|
||
expect(subject.bundler_cert_path).to eq(File.join(root, "lib/bundler/ssl_certs"))
|
||
end
|
||
it "should set bundler_certs as the paths of the bundler ssl certs" do
|
||
expect(subject.bundler_certs).to include(File.join(root, "lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem"))
|
||
expect(subject.bundler_certs).to include(File.join(root, "lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem"))
|
||
end
|
||
context "when rubygems_path is not nil" do
|
||
it "should set rubygems_certs" do
|
||
expect(subject.rubygems_certs).to include(File.join(root, "lib", "rubygems", "ssl_certs", "rubygems.org", "ssl-cert.pem"))
|
||
end
|
||
end
|
||
end
|
||
describe "#up_to_date?" do
|
||
context "when bundler certs and rubygems certs are the same" do
|
||
before do
|
||
bundler_certs = Dir[File.join(root.to_s, "lib", "bundler", "ssl_certs", "**", "*.pem")]
|
||
FileUtils.rm(stub_cert)
|
||
FileUtils.cp(bundler_certs, rubygems_certs_dir)
|
||
end
|
||
it "should return true" do
|
||
expect(subject).to be_up_to_date
|
||
end
|
||
end
|
||
context "when bundler certs and rubygems certs are not the same" do
|
||
it "should return false" do
|
||
expect(subject).to_not be_up_to_date
|
||
end
|
||
end
|
||
end
|
||
describe "#update!" do
|
||
context "when certificate manager is not up to date" do
|
||
before do
|
||
allow(subject).to receive(:up_to_date?).and_return(false)
|
||
allow(bundler_fileutils).to receive(:rm)
|
||
allow(bundler_fileutils).to receive(:cp)
|
||
end
|
||
it "should remove the current bundler certs" do
|
||
expect(bundler_fileutils).to receive(:rm).with(subject.bundler_certs)
|
||
subject.update!
|
||
end
|
||
it "should copy the rubygems certs into bundler certs" do
|
||
expect(bundler_fileutils).to receive(:cp).with(subject.rubygems_certs, subject.bundler_cert_path)
|
||
subject.update!
|
||
end
|
||
it "should return nil" do
|
||
expect(subject.update!).to be_nil
|
||
end
|
||
end
|
||
context "when certificate manager is up to date" do
|
||
before { allow(subject).to receive(:up_to_date?).and_return(true) }
|
||
it "should return nil" do
|
||
expect(subject.update!).to be_nil
|
||
end
|
||
end
|
||
end
|
||
describe "#connect_to" do
|
||
let(:host) { "http://www.host.com" }
|
||
let(:http) { Net::HTTP.new(host, 443) }
|
||
let(:cert_store) { OpenSSL::X509::Store.new }
|
||
let(:http_header_response) { double(:http_header_response) }
|
||
before do
|
||
allow(Net::HTTP).to receive(:new).with(host, 443).and_return(http)
|
||
allow(OpenSSL::X509::Store).to receive(:new).and_return(cert_store)
|
||
allow(http).to receive(:head).with("/").and_return(http_header_response)
|
||
end
|
||
it "should use ssl for the http request" do
|
||
expect(http).to receive(:use_ssl=).with(true)
|
||
subject.connect_to(host)
|
||
end
|
||
it "use verify peer mode" do
|
||
expect(http).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
|
||
subject.connect_to(host)
|
||
end
|
||
it "set its cert store as a OpenSSL::X509::Store populated with bundler certs" do
|
||
expect(cert_store).to receive(:add_file).at_least(:once)
|
||
expect(http).to receive(:cert_store=).with(cert_store)
|
||
subject.connect_to(host)
|
||
end
|
||
it "return the headers of the request response" do
|
||
expect(subject.connect_to(host)).to eq(http_header_response)
|
||
end
|
||
end
|
||
end
|
/dev/null | ||
---|---|---|
# frozen_string_literal: true
|
||
require "bundler/ssl_certs/certificate_manager"
|
||
RSpec.describe "SSL Certificates", :rubygems_master do
|
||
hosts = %w[
|
||
rubygems.org
|
||
index.rubygems.org
|
||
rubygems.global.ssl.fastly.net
|
||
staging.rubygems.org
|
||
]
|
||
hosts.each do |host|
|
||
it "can securely connect to #{host}", :realworld do
|
||
Bundler::SSLCerts::CertificateManager.new.connect_to(host)
|
||
end
|
||
end
|
||
end
|
spec/bundler/quality_spec.rb | ||
---|---|---|
end
|
||
it "has no malformed whitespace" do
|
||
exempt = /\.gitmodules|\.marshal|fixtures|vendor|ssl_certs|LICENSE|vcr_cassettes/
|
||
exempt = /\.gitmodules|\.marshal|fixtures|vendor|LICENSE|vcr_cassettes/
|
||
error_messages = []
|
||
Dir.chdir(root) do
|
||
lib_files = ruby_core? ? `git ls-files -z -- lib/bundler lib/bundler.rb spec/bundler` : `git ls-files -z -- lib`
|