ruby-changes:59783
From: Yuta <ko1@a...>
Date: Thu, 23 Jan 2020 17:23:41 +0900 (JST)
Subject: [ruby-changes:59783] be6931f7f7 (master): Add #verify_hostname= and #verify_hostname to skip hostname verification (#2858)
https://git.ruby-lang.org/ruby.git/commit/?id=be6931f7f7 From be6931f7f7d2eed46226f0cc452de64cdeec0dab Mon Sep 17 00:00:00 2001 From: Yuta Iwama <ganmacs@g...> Date: Thu, 23 Jan 2020 17:23:17 +0900 Subject: Add #verify_hostname= and #verify_hostname to skip hostname verification (#2858) According to https://github.com/ruby/openssl/pull/60, > Currently an user who wants to do the hostname verification needs to call SSLSocket#post_connection_check explicitly after the TLS connection is established. if an user who wants to skip the hostname verification, SSLSocket#post_connection_check doesn't need to be called https://bugs.ruby-lang.org/issues/16555 diff --git a/lib/net/http.rb b/lib/net/http.rb index 88a174a..de9963d 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -844,6 +844,7 @@ module Net #:nodoc: https://github.com/ruby/ruby/blob/trunk/lib/net/http.rb#L844 :@verify_callback, :@verify_depth, :@verify_mode, + :@verify_hostname, ] SSL_ATTRIBUTES = [ :ca_file, @@ -859,6 +860,7 @@ module Net #:nodoc: https://github.com/ruby/ruby/blob/trunk/lib/net/http.rb#L860 :verify_callback, :verify_depth, :verify_mode, + :verify_hostname, ] # Sets path of a CA certification file in PEM format. @@ -908,6 +910,10 @@ module Net #:nodoc: https://github.com/ruby/ruby/blob/trunk/lib/net/http.rb#L910 # OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER are acceptable. attr_accessor :verify_mode + # Sets to check the server certificate is valid for the hostname. + # See OpenSSL::SSL::SSLContext#verify_hostname= + attr_accessor :verify_hostname + # Returns the X.509 certificates the server presented. def peer_cert if not use_ssl? or not @socket @@ -986,9 +992,11 @@ module Net #:nodoc: https://github.com/ruby/ruby/blob/trunk/lib/net/http.rb#L992 ssl_parameters = Hash.new iv_list = instance_variables SSL_IVNAMES.each_with_index do |ivname, i| - if iv_list.include?(ivname) and + if iv_list.include?(ivname) value = instance_variable_get(ivname) - ssl_parameters[SSL_ATTRIBUTES[i]] = value if value + unless value.nil? + ssl_parameters[SSL_ATTRIBUTES[i]] = value + end end end @ssl_context = OpenSSL::SSL::SSLContext.new @@ -1007,7 +1015,7 @@ module Net #:nodoc: https://github.com/ruby/ruby/blob/trunk/lib/net/http.rb#L1015 s.session = @ssl_session end ssl_socket_connect(s, @open_timeout) - if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE + if (@ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE) && @ssl_context.verify_hostname s.post_connection_check(@address) end D "SSL established, protocol: #{s.ssl_version}, cipher: #{s.cipher[0]}" diff --git a/test/net/http/test_https.rb b/test/net/http/test_https.rb index 17fabb6..204bfb7 100644 --- a/test/net/http/test_https.rb +++ b/test/net/http/test_https.rb @@ -204,6 +204,29 @@ class TestNetHTTPS < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/net/http/test_https.rb#L204 skip $! end + def test_skip_hostname_verfiction + TestNetHTTPUtils.clean_http_proxy_env do + http = Net::HTTP.new('invalid_servername', config('port')) + http.ipaddr = config('host') + http.use_ssl = true + http.cert_store = TEST_STORE + http.verify_hostname = false + assert_nothing_raised { http.start } + end + end + + def test_fail_if_verify_hostname_is_true + TestNetHTTPUtils.clean_http_proxy_env do + http = Net::HTTP.new('invalid_servername', config('port')) + http.ipaddr = config('host') + http.use_ssl = true + http.cert_store = TEST_STORE + http.verify_hostname = true + @log_tester = lambda { |_| } + assert_raise(OpenSSL::SSL::SSLError) { http.start } + end + end + def test_certificate_verify_failure http = Net::HTTP.new("localhost", config("port")) http.use_ssl = true -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/