Skip to content

Commit

Permalink
Merge pull request #8 from MSP-Greg/ruby-desc
Browse files Browse the repository at this point in the history
RUBY_DESCRIPTION, minor formatting, width
  • Loading branch information
duckinator authored Nov 20, 2024
2 parents 472640b + 1e84796 commit 1a9015d
Showing 1 changed file with 88 additions and 51 deletions.
139 changes: 88 additions & 51 deletions check.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
begin
require 'openssl'
rescue LoadError
abort "Oh no! Your Ruby doesn't have OpenSSL, so it can't connect to #{host}. " \
"You'll need to recompile or reinstall Ruby with OpenSSL support and try again."
puts "Oh no! Your Ruby doesn't have OpenSSL, so it can't connect to #{host}.",
"You'll need to recompile or reinstall Ruby with OpenSSL support and try again."
exit 1
end

begin
Expand All @@ -39,27 +40,48 @@
end

uri = URI("https://#{host}")
ssl_version = ARGV.shift
tls_version = ARGV.shift
verify_mode = ARGV.any? ? OpenSSL::SSL.const_get(ARGV.shift) : OpenSSL::SSL::VERIFY_PEER

ruby_version = RUBY_VERSION.dup
ruby_version << "p#{RUBY_PATCHLEVEL}" if defined?(RUBY_PATCHLEVEL)
ruby_version << " (#{RUBY_RELEASE_DATE} revision #{RUBY_REVISION})"
ruby_version << " [#{RUBY_PLATFORM}]"
if defined?(RUBY_DESCRIPTION)
ruby_version = RUBY_DESCRIPTION
else
ruby_version = RUBY_VERSION.dup
ruby_version << "p#{RUBY_PATCHLEVEL}" if defined?(RUBY_PATCHLEVEL)
ruby_version << " (#{RUBY_RELEASE_DATE} revision #{RUBY_REVISION})"
ruby_version << " [#{RUBY_PLATFORM}]"
end

puts "Here's your Ruby and OpenSSL environment:"
puts
puts "Ruby: %s" % ruby_version
puts "RubyGems: %s" % Gem::VERSION if defined?(Gem::VERSION)
puts "Bundler: %s" % Bundler::VERSION if defined?(Bundler::VERSION)
puts "Compiled with: %s" % OpenSSL::OPENSSL_VERSION
puts "Loaded version: %s" % OpenSSL::OPENSSL_LIBRARY_VERSION if defined?(OpenSSL::OPENSSL_LIBRARY_VERSION)
puts "SSL_CERT_FILE: %s" % OpenSSL::X509::DEFAULT_CERT_FILE
puts "SSL_CERT_DIR: %s" % OpenSSL::X509::DEFAULT_CERT_DIR
puts "", "Here's your Ruby and OpenSSL environment:"
puts
puts "With that out of the way, let's see if you can connect to #{host}..."
puts "Ruby: %s" % ruby_version
puts "RubyGems: %s" % Gem::VERSION if defined?(Gem::VERSION)
puts "Bundler: %s" % Bundler::VERSION if defined?(Bundler::VERSION)
puts "OpenSSL: %s" % OpenSSL::VERSION if defined?(OpenSSL::VERSION)
puts "Compiled with: %s" % OpenSSL::OPENSSL_VERSION
puts "Loaded with: %s" % OpenSSL::OPENSSL_LIBRARY_VERSION if defined?(OpenSSL::OPENSSL_LIBRARY_VERSION)
puts

def show_ssl_certs
puts "", "Below affect only Ruby net/http connections:"
puts
t = ENV['SSL_CERT_FILE'] || OpenSSL::X509::DEFAULT_CERT_FILE
ssl_file = if Dir.exist? t
"βœ… exists #{t}"
elsif RUBY_PLATFORM.end_with? 'linux'
t = '/etc/ssl/certs/ca-certificates.crt'
Dir.exist?(t) ? "βœ… exists #{t}" : "❌ is missing #{t}"
else
"❌ is missing #{t}"
end
puts "SSL_CERT_FILE: %s" % ssl_file

t = ENV['SSL_CERT_DIR'] || OpenSSL::X509::DEFAULT_CERT_DIR
ssl_dir = Dir.exist?(t) ? "βœ… exists #{t}" : "❌ is missing #{t}"
puts "SSL_CERT_DIR: %s" % ssl_dir
puts
end

def error_reason(error)
case error.message
when /certificate verify failed/
Expand All @@ -73,85 +95,101 @@ def error_reason(error)
end
end

puts "Trying connections to #{uri.to_s}:"
puts
begin
b_uri = defined?(Bundler::URI) ? Bundler::URI(uri.to_s) : uri
Bundler::Fetcher.new(Bundler::Source::Rubygems::Remote.new(b_uri)).send(:connection).request(b_uri)
bundler_status = "success βœ…"
bundler_status = "βœ… success"
rescue => error
bundler_status = "failed ❌ (#{error_reason(error)})"
bundler_status = "❌ failed (#{error_reason(error)})"
end
puts "Bundler connection to #{host}: #{bundler_status}"
puts "Bundler: #{bundler_status}"

begin
require 'rubygems/remote_fetcher'
Gem::RemoteFetcher.fetcher.fetch_path(uri)
rubygems_status = "success βœ…"
rubygems_status = "βœ… success"
rescue => error
rubygems_status = "failed ❌ (#{error_reason(error)})"
rubygems_status = "❌ failed (#{error_reason(error)})"
end
puts "RubyGems connection to #{host}: #{rubygems_status}"
puts "RubyGems: #{rubygems_status}"

begin
# Try to connect using HTTPS
Net::HTTP.new(uri.host, uri.port).tap do |http|
http.use_ssl = true
if ssl_version
if tls_version
if http.respond_to? :min_version=
vers = ssl_version.sub("v", "").to_sym
vers = tls_version.sub("v", "").to_sym
http.min_version = vers
http.max_version = vers
else
http.ssl_version = ssl_version.to_sym
http.ssl_version = tls_version.to_sym
end
end
http.verify_mode = verify_mode
end.start

puts "Ruby net/http connection to #{host}: success βœ…"
puts "Ruby net/http: βœ… success"
puts
rescue => error
puts "Ruby net/http connection to #{host}: failed ❌"
puts "Ruby net/http: ❌ failed"
puts
puts "Unfortunately, this Ruby can't connect to #{host}. 😑"

case error.message
# Check for certificate errors
when /certificate verify failed/
abort "Your Ruby can't connect to #{host} because you are missing the certificate " \
"files OpenSSL needs to verify you are connecting to the genuine #{host} servers."
show_ssl_certs
puts "\nYour Ruby can't connect to #{host} because you are missing the certificate",
"files OpenSSL needs to verify you are connecting to the genuine #{host} servers.", ""
# Check for TLS version errors
when /read server hello A/, /tlsv1 alert protocol version/
if ssl_version == "TLSv1_3"
abort "Your Ruby can't connect to #{host} because #{ssl_version} isn't supported yet."
if tls_version == "TLSv1_3"
puts "\nYour Ruby can't connect to #{host} because #{tls_version} isn't supported yet.\n\n"
else
abort "Your Ruby can't connect to #{host} because your version of OpenSSL is too old. " \
"You'll need to upgrade your OpenSSL install and/or recompile Ruby to use a newer OpenSSL."
puts "\nYour Ruby can't connect to #{host} because your version of OpenSSL is too old.",
"You'll need to upgrade your OpenSSL install and/or recompile Ruby to use a newer OpenSSL.", ""
end
# OpenSSL doesn't support TLS version specified by argument
when /unknown SSL method/
puts "\nYour Ruby can't connect because #{tls_version} isn't supported by your version of OpenSSL.\n\n"
else
puts "Even worse, we're not sure why. πŸ˜•"
puts "\nEven worse, we're not sure why. πŸ˜•"
puts
puts "Here's the full error information:"
puts "#{error.class}: #{error.message}"
puts " " << error.backtrace.join("\n ")
puts "Here's the full error information:",
"#{error.class}: #{error.message}",
" #{error.backtrace.join("\n ")}"
puts
puts "You might have more luck using Mislav's SSL doctor.rb script. You can get it here:"
puts "https://github.com/mislav/ssl-tools/blob/8b3dec4/doctor.rb"
puts "Read more about the script and how to use it in this blog post:"
puts "https://mislav.net/2013/07/ruby-openssl/"
abort
puts "You might have more luck using Mislav's SSL doctor.rb script. You can get it here:",
"https://github.com/mislav/ssl-tools/blob/8b3dec4/doctor.rb",
"Read more about the script and how to use it in this blog post:",
"https://mislav.net/2013/07/ruby-openssl/", ""
end
exit 1
end

guide_url = "http://ruby.to/ssl-check-failed"
if bundler_status =~ /success/ && rubygems_status =~ /success/
# Whoa, it seems like it's working!
puts "Hooray! This Ruby can connect to #{host}. You are all set to use Bundler and RubyGems. πŸ‘Œ"
puts "Hooray! This Ruby can connect to #{host}.",
"You are all set to use Bundler and RubyGems. πŸ‘Œ", ""
elsif rubygems_status !~ /success/
puts "It looks like Ruby and Bundler can connect to #{host}, but RubyGems itself cannot. You can likely solve this by manually downloading and installing a RubyGems update. Visit #{guide_url} for instructions on how to manually upgrade RubyGems. πŸ’Ž"
puts "It looks like Ruby and Bundler can connect to #{host}, but RubyGems itself",
"cannot. You can likely solve this by manually downloading and installing a",
"RubyGems update. Visit #{guide_url} for instructions on how to manually upgrade RubyGems. πŸ’Ž"
elsif bundler_status !~ /success/
puts "Although your Ruby installation and RubyGems can both connect to #{host}, Bundler is having trouble. The most likely way to fix this is to upgrade Bundler by running `gem install bundler`. Run this script again after doing that to make sure everything is all set. If you're still having trouble, check out the troubleshooting guide at #{guide_url} πŸ“¦"
puts "Although your Ruby installation and RubyGems can both connect to #{host},",
"Bundler is having trouble. The most likely way to fix this is to upgrade",
"Bundler by running `gem install bundler`. Run this script again after doing",
"that to make sure everything is all set. If you're still having trouble,",
"check out the troubleshooting guide at #{guide_url} πŸ“¦"
else
puts "For some reason, your Ruby installation can connect to #{host}, but neither RubyGems nor Bundler can. The most likely fix is to manually upgrade RubyGems by following the instructions at #{guide_url}. After you've done that, run `gem install bundler` to upgrade Bundler, and then run this script again to make sure everything worked. ❣️"
puts "For some reason, your Ruby installation can connect to #{host}, but neither",
"RubyGems nor Bundler can. The most likely fix is to manually upgrade RubyGems by",
"following the instructions at #{guide_url}. After you've done that, run `gem install",
"bundler` to upgrade Bundler, and then run this script again to make sure everything worked. ❣️"
end

def tls12_supported?
Expand All @@ -167,10 +205,9 @@ def tls12_supported?

# We were able to connect, but perhaps this Ruby will have trouble when we require TLSv1.2
unless tls12_supported?
puts
puts "WARNING: Although your Ruby can connect to #{host} today, your OpenSSL is very old! πŸ‘΄"
puts "WARNING: You will need to upgrade OpenSSL before January 2018 in order to keep using #{host}."
abort
puts "\nWARNING: Although your Ruby can connect to #{host} today, your OpenSSL is very old! πŸ‘΄",
"WARNING: You will need to upgrade OpenSSL to use #{host}."
exit 1
end

exit 0

0 comments on commit 1a9015d

Please sign in to comment.