# HG changeset patch # User April Chin # Date 1432754712 25200 # Node ID 643c4e910399f75e8d5ac38dc52fb933152880ef # Parent 0a8849e52e36a553731a4d98117a1d6878519a6a 20877795 problem in UTILITY/RUBY diff -r 0a8849e52e36 -r 643c4e910399 components/ruby/ruby-19/Makefile --- a/components/ruby/ruby-19/Makefile Wed May 27 11:09:36 2015 -0500 +++ b/components/ruby/ruby-19/Makefile Wed May 27 12:25:12 2015 -0700 @@ -151,6 +151,15 @@ CLEAN_PATHS += Solaris/gem.1 Solaris/rbconfig.sedscript.mod \ Solaris/ruby.1.sedscript.mod +# This set of tests goes through thousands of entries in the passwd +# and group table, taking hours to run; move it aside so we skip it. +# There may also be spurious errors if group memberships are modified +# during testing. +COMPONENT_PRE_TEST_ACTION += \ + ( if test -e $(SOURCE_DIR)/test/etc/test_etc.rb ; then \ + $(MV) $(SOURCE_DIR)/test/etc/test_etc.rb \ + $(SOURCE_DIR)/test/etc/test_etc.rb-save ; fi ) + # common targets configure: $(CONFIGURE_64) diff -r 0a8849e52e36 -r 643c4e910399 components/ruby/ruby-19/patches/08-ssl-internal_rb.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/ruby/ruby-19/patches/08-ssl-internal_rb.patch Wed May 27 12:25:12 2015 -0700 @@ -0,0 +1,249 @@ +# Fix based on upstream fix to Ruby 2.x +# https://github.com/ruby/openssl/commit/e9a7bcb8bf2902f907c148a00bbcf21d3fa79596 + +diff -rup ruby-1.9.3-p551-orig/ext/openssl/lib/openssl/ssl-internal.rb ruby-1.9.3-p551/ext/openssl/lib/openssl/ssl-internal.rb +--- ruby-1.9.3-p551-orig/ext/openssl/lib/openssl/ssl-internal.rb 2014-10-23 20:06:36.000000000 -0700 ++++ ruby-1.9.3-p551/ext/openssl/lib/openssl/ssl-internal.rb 2015-05-21 16:31:27.271213113 -0700 +@@ -135,8 +135,7 @@ module OpenSSL + case san.tag + when 2 # dNSName in GeneralName (RFC5280) + should_verify_common_name = false +- reg = Regexp.escape(san.value).gsub(/\\\*/, "[^.]+") +- return true if /\A#{reg}\z/i =~ hostname ++ return true if verify_hostname(hostname, san.value) + when 7 # iPAddress in GeneralName (RFC5280) + should_verify_common_name = false + # follows GENERAL_NAME_print() in x509v3/v3_alt.c +@@ -151,8 +150,7 @@ module OpenSSL + if should_verify_common_name + cert.subject.to_a.each{|oid, value| + if oid == "CN" +- reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+") +- return true if /\A#{reg}\z/i =~ hostname ++ return true if verify_hostname(hostname, value) + end + } + end +@@ -160,6 +158,57 @@ module OpenSSL + end + module_function :verify_certificate_identity + ++ def verify_hostname(hostname, san) # :nodoc: ++ # RFC 5280, IA5String is limited to the set of ASCII characters ++ return false unless san.ascii_only? ++ return false unless hostname.ascii_only? ++ ++ # See RFC 6125, section 6.4.1 ++ # Matching is case-insensitive. ++ san_parts = san.downcase.split(".") ++ ++ # TODO: this behavior should probably be more strict ++ return san == hostname if san_parts.size < 2 ++ ++ # Matching is case-insensitive. ++ host_parts = hostname.downcase.split(".") ++ ++ # RFC 6125, section 6.4.3, subitem 2. ++ # If the wildcard character is the only character of the left-most ++ # label in the presented identifier, the client SHOULD NOT compare ++ # against anything but the left-most label of the reference ++ # identifier (e.g., *.example.com would match foo.example.com but ++ # not bar.foo.example.com or example.com). ++ return false unless san_parts.size == host_parts.size ++ ++ # RFC 6125, section 6.4.3, subitem 1. ++ # The client SHOULD NOT attempt to match a presented identifier in ++ # which the wildcard character comprises a label other than the ++ # left-most label (e.g., do not match bar.*.example.net). ++ return false unless verify_wildcard(host_parts.shift, san_parts.shift) ++ ++ san_parts.join(".") == host_parts.join(".") ++ end ++ module_function :verify_hostname ++ ++ def verify_wildcard(domain_component, san_component) # :nodoc: ++ parts = san_component.split("*", -1) ++ ++ return false if parts.size > 2 ++ return san_component == domain_component if parts.size == 1 ++ ++ # RFC 6125, section 6.4.3, subitem 3. ++ # The client SHOULD NOT attempt to match a presented identifier ++ # where the wildcard character is embedded within an A-label or ++ # U-label of an internationalized domain name. ++ return false if domain_component.start_with?("xn--") && san_component != "*" ++ ++ parts[0].length + parts[1].length < domain_component.length && ++ domain_component.start_with?(parts[0]) && ++ domain_component.end_with?(parts[1]) ++ end ++ module_function :verify_wildcard ++ + class SSLSocket + include Buffering + include SocketForwarder +diff -rup ruby-1.9.3-p551-orig/test/openssl/test_ssl.rb ruby-1.9.3-p551/test/openssl/test_ssl.rb +--- ruby-1.9.3-p551-orig/test/openssl/test_ssl.rb 2014-10-23 20:06:36.000000000 -0700 ++++ ruby-1.9.3-p551/test/openssl/test_ssl.rb 2015-05-22 11:46:38.959996713 -0700 +@@ -1,3 +1,4 @@ ++# encoding: UTF-8 + require_relative "utils" + + if defined?(OpenSSL) +@@ -363,6 +364,156 @@ class OpenSSL::TestSSL < OpenSSL::SSLTes + end + end + ++ def test_verify_hostname ++ assert_equal(true, OpenSSL::SSL.verify_hostname("www.example.com", "*.example.com")) ++ assert_equal(false, OpenSSL::SSL.verify_hostname("www.subdomain.example.com", "*.example.com")) ++ end ++ ++ def test_verify_wildcard ++ assert_equal(false, OpenSSL::SSL.verify_wildcard("foo", "x*")) ++ assert_equal(true, OpenSSL::SSL.verify_wildcard("foo", "foo")) ++ assert_equal(true, OpenSSL::SSL.verify_wildcard("foo", "f*")) ++ assert_equal(true, OpenSSL::SSL.verify_wildcard("foo", "*")) ++ assert_equal(false, OpenSSL::SSL.verify_wildcard("abc*bcd", "abcd")) ++ assert_equal(false, OpenSSL::SSL.verify_wildcard("xn--qdk4b9b", "x*")) ++ assert_equal(false, OpenSSL::SSL.verify_wildcard("xn--qdk4b9b", "*--qdk4b9b")) ++ assert_equal(true, OpenSSL::SSL.verify_wildcard("xn--qdk4b9b", "xn--qdk4b9b")) ++ end ++ ++ # Comments in this test is excerpted from http://tools.ietf.org/html/rfc6125#page-27 ++ def test_post_connection_check_wildcard_san ++ # case-insensitive ASCII comparison ++ # RFC 6125, section 6.4.1 ++ # ++ # "..matching of the reference identifier against the presented identifier ++ # is performed by comparing the set of domain name labels using a ++ # case-insensitive ASCII comparison, as clarified by [DNS-CASE] (e.g., ++ # "WWW.Example.Com" would be lower-cased to "www.example.com" for ++ # comparison purposes) ++ assert_equal(true, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_san('DNS:*.example.com'), 'www.example.com')) ++ assert_equal(true, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_san('DNS:*.Example.COM'), 'www.example.com')) ++ assert_equal(true, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_san('DNS:*.example.com'), 'WWW.Example.COM')) ++ # 1. The client SHOULD NOT attempt to match a presented identifier in ++ # which the wildcard character comprises a label other than the ++ # left-most label (e.g., do not match bar.*.example.net). ++ assert_equal(false, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_san('DNS:www.*.com'), 'www.example.com')) ++ # 2. If the wildcard character is the only character of the left-most ++ # label in the presented identifier, the client SHOULD NOT compare ++ # against anything but the left-most label of the reference ++ # identifier (e.g., *.example.com would match foo.example.com but ++ # not bar.foo.example.com or example.com). ++ assert_equal(true, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_san('DNS:*.example.com'), 'foo.example.com')) ++ assert_equal(false, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_san('DNS:*.example.com'), 'bar.foo.example.com')) ++ # 3. The client MAY match a presented identifier in which the wildcard ++ # character is not the only character of the label (e.g., ++ # baz*.example.net and *baz.example.net and b*z.example.net would ++ # be taken to match baz1.example.net and foobaz.example.net and ++ # buzz.example.net, respectively). ... ++ assert_equal(true, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_san('DNS:baz*.example.com'), 'baz1.example.com')) ++ assert_equal(true, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_san('DNS:*baz.example.com'), 'foobaz.example.com')) ++ assert_equal(true, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_san('DNS:b*z.example.com'), 'buzz.example.com')) ++ # Section 6.4.3 of RFC6125 states that client should NOT match identifier ++ # where wildcard is other than left-most label. ++ # ++ # Also implicitly mentions the wildcard character only in singular form, ++ # and discourages matching against more than one wildcard. ++ # ++ # See RFC 6125, section 7.2, subitem 2. ++ assert_equal(false, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_san('DNS:*b*.example.com'), 'abc.example.com')) ++ assert_equal(false, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_san('DNS:*b*.example.com'), 'ab.example.com')) ++ assert_equal(false, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_san('DNS:*b*.example.com'), 'bc.example.com')) ++ # ... However, the client SHOULD NOT ++ # attempt to match a presented identifier where the wildcard ++ # character is embedded within an A-label or U-label [IDNA-DEFS] of ++ # an internationalized domain name [IDNA-PROTO]. ++ assert_equal(true, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_san('DNS:xn*.example.com'), 'xn1ca.example.com')) ++ # part of A-label ++ assert_equal(false, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_san('DNS:xn--*.example.com'), 'xn--1ca.example.com')) ++ # part of U-label ++ # dNSName in RFC5280 is an IA5String so U-label should NOT be allowed ++ # regardless of wildcard. ++ # ++ # See Section 7.2 of RFC 5280: ++ # IA5String is limited to the set of ASCII characters. ++ assert_equal(false, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_san('DNS:á*.example.com'), 'á1.example.com')) ++ end ++ ++ def test_post_connection_check_wildcard_cn ++ assert_equal(true, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_name('*.example.com'), 'www.example.com')) ++ assert_equal(true, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_name('*.Example.COM'), 'www.example.com')) ++ assert_equal(true, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_name('*.example.com'), 'WWW.Example.COM')) ++ assert_equal(false, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_name('www.*.com'), 'www.example.com')) ++ assert_equal(true, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_name('*.example.com'), 'foo.example.com')) ++ assert_equal(false, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_name('*.example.com'), 'bar.foo.example.com')) ++ assert_equal(true, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_name('baz*.example.com'), 'baz1.example.com')) ++ assert_equal(true, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_name('*baz.example.com'), 'foobaz.example.com')) ++ assert_equal(true, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_name('b*z.example.com'), 'buzz.example.com')) ++ # Section 6.4.3 of RFC6125 states that client should NOT match identifier ++ # where wildcard is other than left-most label. ++ # ++ # Also implicitly mentions the wildcard character only in singular form, ++ # and discourages matching against more than one wildcard. ++ # ++ # See RFC 6125, section 7.2, subitem 2. ++ assert_equal(false, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_name('*b*.example.com'), 'abc.example.com')) ++ assert_equal(false, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_name('*b*.example.com'), 'ab.example.com')) ++ assert_equal(false, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_name('*b*.example.com'), 'bc.example.com')) ++ assert_equal(true, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_name('xn*.example.com'), 'xn1ca.example.com')) ++ assert_equal(false, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_name('xn--*.example.com'), 'xn--1ca.example.com')) ++ # part of U-label ++ # Subject in RFC5280 states case-insensitive ASCII comparison. ++ # ++ # See Section 7.2 of RFC 5280: ++ # IA5String is limited to the set of ASCII characters. ++ assert_equal(false, OpenSSL::SSL.verify_certificate_identity( ++ create_cert_with_name('á*.example.com'), 'á1.example.com')) ++ end ++ ++ def create_cert_with_san(san) ++ ef = OpenSSL::X509::ExtensionFactory.new ++ cert = OpenSSL::X509::Certificate.new ++ cert.subject = OpenSSL::X509::Name.parse("/DC=some/DC=site/CN=Some Site") ++ ext = ef.create_ext('subjectAltName', san) ++ cert.add_extension(ext) ++ cert ++ end ++ ++ def create_cert_with_name(name) ++ cert = OpenSSL::X509::Certificate.new ++ cert.subject = OpenSSL::X509::Name.new([['DC', 'some'], ['DC', 'site'], ['CN', name]]) ++ cert ++ end ++ ++ + # Create NULL byte SAN certificate + def create_null_byte_SAN_certificate(critical = false) + ef = OpenSSL::X509::ExtensionFactory.new