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`
|
||