diff options
Diffstat (limited to 'lib/bundler/ssl_certs/certificate_manager.rb')
-rw-r--r-- | lib/bundler/ssl_certs/certificate_manager.rb | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/lib/bundler/ssl_certs/certificate_manager.rb b/lib/bundler/ssl_certs/certificate_manager.rb new file mode 100644 index 0000000000..a5e5d84b64 --- /dev/null +++ b/lib/bundler/ssl_certs/certificate_manager.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true +require "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 |