summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-04-20 00:10:09 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-04-20 00:10:09 +0000
commit6253fbea8a7f267e91c3f8c8303297725c8de9d3 (patch)
tree7b309184d1c30262e58dc01c34cdb8d7f32547de /test
parentb570f60d86a50551e5162eb7fb550f3b60346607 (diff)
Backport security fixes for RubyGems 1.3.7:
* lib/rubygems: Apply the following security fixes to RubyGems 1.3.7: RubyGems now disallows redirection from HTTPS to HTTP. RubyGems now verifies SSL connections. Patch by Hiroshi Nakamura. * test/rubygems: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_2@35407 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test')
-rw-r--r--test/rubygems/ca_cert.pem45
-rw-r--r--test/rubygems/ssl_cert.pem19
-rw-r--r--test/rubygems/ssl_key.pem15
-rw-r--r--test/rubygems/test_gem_config_file.rb20
-rw-r--r--test/rubygems/test_gem_remote_fetcher.rb101
5 files changed, 200 insertions, 0 deletions
diff --git a/test/rubygems/ca_cert.pem b/test/rubygems/ca_cert.pem
new file mode 100644
index 0000000000..5acdcf8f32
--- /dev/null
+++ b/test/rubygems/ca_cert.pem
@@ -0,0 +1,45 @@
+-----BEGIN CERTIFICATE-----
+MIID0DCCArigAwIBAgIBADANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES
+MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
+DTA0MDEzMDAwNDIzMloXDTM2MDEyMjAwNDIzMlowPDELMAkGA1UEBgwCSlAxEjAQ
+BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQswCQYDVQQDDAJDQTCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANbv0x42BTKFEQOE+KJ2XmiSdZpR
+wjzQLAkPLRnLB98tlzs4xo+y4RyY/rd5TT9UzBJTIhP8CJi5GbS1oXEerQXB3P0d
+L5oSSMwGGyuIzgZe5+vZ1kgzQxMEKMMKlzA73rbMd4Jx3u5+jdbP0EDrPYfXSvLY
+bS04n2aX7zrN3x5KdDrNBfwBio2/qeaaj4+9OxnwRvYP3WOvqdW0h329eMfHw0pi
+JI0drIVdsEqClUV4pebT/F+CPUPkEh/weySgo9wANockkYu5ujw2GbLFcO5LXxxm
+dEfcVr3r6t6zOA4bJwL0W/e6LBcrwiG/qPDFErhwtgTLYf6Er67SzLyA66UCAwEA
+AaOB3DCB2TAPBgNVHRMBAf8EBTADAQH/MDEGCWCGSAGG+EIBDQQkFiJSdWJ5L09w
+ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRJ7Xd380KzBV7f
+USKIQ+O/vKbhDzAOBgNVHQ8BAf8EBAMCAQYwZAYDVR0jBF0wW4AUSe13d/NCswVe
+31EiiEPjv7ym4Q+hQKQ+MDwxCzAJBgNVBAYMAkpQMRIwEAYDVQQKDAlKSU4uR1Iu
+SlAxDDAKBgNVBAsMA1JSUjELMAkGA1UEAwwCQ0GCAQAwDQYJKoZIhvcNAQEFBQAD
+ggEBAIu/mfiez5XN5tn2jScgShPgHEFJBR0BTJBZF6xCk0jyqNx/g9HMj2ELCuK+
+r/Y7KFW5c5M3AQ+xWW0ZSc4kvzyTcV7yTVIwj2jZ9ddYMN3nupZFgBK1GB4Y05GY
+MJJFRkSu6d/Ph5ypzBVw2YMT/nsOo5VwMUGLgS7YVjU+u/HNWz80J3oO17mNZllj
+PvORJcnjwlroDnS58KoJ7GDgejv3ESWADvX1OHLE4cRkiQGeLoEU4pxdCxXRqX0U
+PbwIkZN9mXVcrmPHq8MWi4eC/V7hnbZETMHuWhUoiNdOEfsAXr3iP4KjyyRdwc7a
+d/xgcK06UVQRL/HbEYGiQL056mc=
+-----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIIDaDCCAlCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES
+MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
+DTA0MDEzMDAwNDMyN1oXDTM1MDEyMjAwNDMyN1owPzELMAkGA1UEBgwCSlAxEjAQ
+BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQ4wDAYDVQQDDAVTdWJDQTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0Ou7AyRcRXnB/kVHv/6kwe
+ANzgg/DyJfsAUqW90m7Lu1nqyug8gK0RBd77yU0w5HOAMHTVSdpjZK0g2sgx4Mb1
+d/213eL9TTl5MRVEChTvQr8q5DVG/8fxPPE7fMI8eOAzd98/NOAChk+80r4Sx7fC
+kGVEE1bKwY1MrUsUNjOY2d6t3M4HHV3HX1V8ShuKfsHxgCmLzdI8U+5CnQedFgkm
+3e+8tr8IX5RR1wA1Ifw9VadF7OdI/bGMzog/Q8XCLf+WPFjnK7Gcx6JFtzF6Gi4x
+4dp1Xl45JYiVvi9zQ132wu8A1pDHhiNgQviyzbP+UjcB/tsOpzBQF8abYzgEkWEC
+AwEAAaNyMHAwDwYDVR0TAQH/BAUwAwEB/zAxBglghkgBhvhCAQ0EJBYiUnVieS9P
+cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUlCjXWLsReYzH
+LzsxwVnCXmKoB/owCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCJ/OyN
+rT8Cq2Y+G2yA/L1EMRvvxwFBqxavqaqHl/6rwsIBFlB3zbqGA/0oec6MAVnYynq4
+c4AcHTjx3bQ/S4r2sNTZq0DH4SYbQzIobx/YW8PjQUJt8KQdKMcwwi7arHP7A/Ha
+LKu8eIC2nsUBnP4NhkYSGhbmpJK+PFD0FVtD0ZIRlY/wsnaZNjWWcnWF1/FNuQ4H
+ySjIblqVQkPuzebv3Ror6ZnVDukn96Mg7kP4u6zgxOeqlJGRe1M949SS9Vudjl8X
+SF4aZUUB9pQGhsqQJVqaz2OlhGOp9D0q54xko/rekjAIcuDjl1mdX4F2WRrzpUmZ
+uY/bPeOBYiVsOYVe
+-----END CERTIFICATE-----
diff --git a/test/rubygems/ssl_cert.pem b/test/rubygems/ssl_cert.pem
new file mode 100644
index 0000000000..998ccc5892
--- /dev/null
+++ b/test/rubygems/ssl_cert.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIC/zCCAeegAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQGDAJKUDES
+MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxDjAMBgNVBAMMBVN1YkNB
+MB4XDTA0MDEzMTAzMTMxNloXDTMzMDEyMzAzMTMxNlowQzELMAkGA1UEBgwCSlAx
+EjAQBgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMRIwEAYDVQQDDAlsb2Nh
+bGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANFJTxWqup3nV9dsJAku
+p+WaXnPNIzcpAA3qMGZDJTJsfa8Du7ZxTP0XJK5mETttBrn711cJxAuP3KjqnW9S
+vtZ9lY2sXJ6Zj62sN5LwG3VVe25dI28yR1EsbHjJ5Zjf9tmggMC6am52dxuHbt5/
+vHo4ngJuKE/U+eeGRivMn6gFAgMBAAGjgYUwgYIwDAYDVR0TAQH/BAIwADAxBglg
+hkgBhvhCAQ0EJBYiUnVieS9PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd
+BgNVHQ4EFgQUpZIyygD9JxFYHHOTEuWOLbCKfckwCwYDVR0PBAQDAgWgMBMGA1Ud
+JQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4IBAQBwAIj5SaBHaA5X31IP
+CFCJiep96awfp7RANO0cuUj+ZpGoFn9d6FXY0g+Eg5wAkCNIzZU5NHN9xsdOpnUo
+zIBbyTfQEPrge1CMWMvL6uGaoEXytq84VTitF/xBTky4KtTn6+es4/e7jrrzeUXQ
+RC46gkHObmDT91RkOEGjHLyld2328jo3DIN/VTHIryDeVHDWjY5dENwpwdkhhm60
+DR9IrNBbXWEe9emtguNXeN0iu1ux0lG1Hc6pWGQxMlRKNvGh0yZB9u5EVe38tOV0
+jQaoNyL7qzcQoXD3Dmbi1p0iRmg/+HngISsz8K7k7MBNVsSclztwgCzTZOBiVtkM
+rRlQ
+-----END CERTIFICATE-----
diff --git a/test/rubygems/ssl_key.pem b/test/rubygems/ssl_key.pem
new file mode 100644
index 0000000000..9ba2218a03
--- /dev/null
+++ b/test/rubygems/ssl_key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDRSU8Vqrqd51fXbCQJLqflml5zzSM3KQAN6jBmQyUybH2vA7u2
+cUz9FySuZhE7bQa5+9dXCcQLj9yo6p1vUr7WfZWNrFyemY+trDeS8Bt1VXtuXSNv
+MkdRLGx4yeWY3/bZoIDAumpudncbh27ef7x6OJ4CbihP1PnnhkYrzJ+oBQIDAQAB
+AoGBAIf4CstW2ltQO7+XYGoex7Hh8s9lTSW/G2vu5Hbr1LTHy3fzAvdq8MvVR12O
+rk9fa+lU9vhzPc0NMB0GIDZ9GcHuhW5hD1Wg9OSCbTOkZDoH3CAFqonjh4Qfwv5W
+IPAFn9KHukdqGXkwEMdErsUaPTy9A1V/aROVEaAY+HJgq/eZAkEA/BP1QMV04WEZ
+Oynzz7/lLizJGGxp2AOvEVtqMoycA/Qk+zdKP8ufE0wbmCE3Qd6GoynavsHb6aGK
+gQobb8zDZwJBANSK6MrXlrZTtEaeZuyOB4mAmRzGzOUVkUyULUjEx2GDT93ujAma
+qm/2d3E+wXAkNSeRpjUmlQXy/2oSqnGvYbMCQQDRM+cYyEcGPUVpWpnj0shrF/QU
+9vSot/X1G775EMTyaw6+BtbyNxVgOIu2J+rqGbn3c+b85XqTXOPL0A2RLYkFAkAm
+syhSDtE9X55aoWsCNZY/vi+i4rvaFoQ/WleogVQAeGVpdo7/DK9t9YWoFBIqth0L
+mGSYFu9ZhvZkvQNV8eYrAkBJ+rOIaLDsmbrgkeDruH+B/9yrm4McDtQ/rgnOGYnH
+LjLpLLOrgUxqpzLWe++EwSLwK2//dHO+SPsQJ4xsyQJy
+-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/test_gem_config_file.rb b/test/rubygems/test_gem_config_file.rb
index b76ff7b180..e331ac333b 100644
--- a/test/rubygems/test_gem_config_file.rb
+++ b/test/rubygems/test_gem_config_file.rb
@@ -53,6 +53,8 @@ class TestGemConfigFile < RubyGemTestCase
fp.puts ":gempath:"
fp.puts "- /usr/ruby/1.8/lib/ruby/gems/1.8"
fp.puts "- /var/ruby/1.8/gem_home"
+ fp.puts ":ssl_verify_mode: 0"
+ fp.puts ":ssl_ca_cert: /etc/ssl/certs"
end
util_config_file
@@ -67,6 +69,8 @@ class TestGemConfigFile < RubyGemTestCase
assert_equal '--wrappers', @cfg[:install]
assert_equal(['/usr/ruby/1.8/lib/ruby/gems/1.8', '/var/ruby/1.8/gem_home'],
@cfg.path)
+ assert_equal 0, @cfg.ssl_verify_mode
+ assert_equal '/etc/ssl/certs', @cfg.ssl_ca_cert
end
def test_initialize_handle_arguments_config_file
@@ -279,6 +283,22 @@ class TestGemConfigFile < RubyGemTestCase
assert_equal "701229f217cdf23b1344c7b4b54ca97", @cfg.rubygems_api_key
end
+ def test_load_ssl_verify_mode_from_config
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts ":ssl_verify_mode: 1"
+ end
+ util_config_file
+ assert_equal(1, @cfg.ssl_verify_mode)
+ end
+
+ def test_load_ssl_ca_cert_from_config
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts ":ssl_ca_cert: /home/me/certs"
+ end
+ util_config_file
+ assert_equal('/home/me/certs', @cfg.ssl_ca_cert)
+ end
+
def util_config_file(args = @cfg_args)
@cfg = Gem::ConfigFile.new args
end
diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb
index d6b78dc7cc..1430bd186b 100644
--- a/test/rubygems/test_gem_remote_fetcher.rb
+++ b/test/rubygems/test_gem_remote_fetcher.rb
@@ -1,6 +1,7 @@
require_relative 'gemutilities'
require 'ostruct'
require 'webrick'
+require 'webrick/https'
require 'rubygems/remote_fetcher'
require 'rubygems/format'
@@ -73,6 +74,8 @@ gems:
PROXY_PORT = process_based_port + 100 + $1.to_i * 100 + $2.to_i * 10 + $3.to_i
SERVER_PORT = process_based_port + 200 + $1.to_i * 100 + $2.to_i * 10 + $3.to_i
+ DIR = File.expand_path(File.dirname(__FILE__))
+
def setup
super
self.class.start_servers
@@ -632,6 +635,53 @@ gems:
end
end
+ def test_ssl_connection
+ ssl_server = self.class.start_ssl_server
+ temp_ca_cert = File.join(DIR, 'ca_cert.pem')
+ with_configured_fetcher(":ssl_ca_cert: #{temp_ca_cert}") do |fetcher|
+ fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/yaml")
+ end
+ end
+
+ def test_do_not_allow_insecure_ssl_connection_by_default
+ ssl_server = self.class.start_ssl_server
+ with_configured_fetcher do |fetcher|
+ assert_raises Gem::RemoteFetcher::FetchError do
+ fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/yaml")
+ end
+ end
+ end
+
+ def test_ssl_connection_allow_verify_none
+ ssl_server = self.class.start_ssl_server
+ with_configured_fetcher(":ssl_verify_mode: 0") do |fetcher|
+ fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/yaml")
+ end
+ end
+
+ def test_do_not_follow_insecure_redirect
+ ssl_server = self.class.start_ssl_server
+ temp_ca_cert = File.join(DIR, 'ca_cert.pem'),
+ with_configured_fetcher(":ssl_ca_cert: #{temp_ca_cert}") do |fetcher|
+ assert_raises Gem::RemoteFetcher::FetchError do
+ fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/insecure_redirect?to=#{@server_uri}")
+ end
+ end
+ end
+
+ def with_configured_fetcher(config_str = nil, &block)
+ if config_str
+ temp_conf = File.join @tempdir, '.gemrc'
+ File.open temp_conf, 'w' do |fp|
+ fp.puts config_str
+ end
+ Gem.configuration = Gem::ConfigFile.new %W[--config-file #{temp_conf}]
+ end
+ yield Gem::RemoteFetcher.new
+ ensure
+ Gem.configuration = nil
+ end
+
def util_stub_connection_for hash
def @fetcher.connection= conn
@conn = conn
@@ -692,6 +742,49 @@ gems:
@enable_zip = false
end
+ DIR = File.expand_path(File.dirname(__FILE__))
+ DH_PARAM = OpenSSL::PKey::DH.new(128)
+
+ def start_ssl_server(config = {})
+ null_logger = NilLog.new
+ server = WEBrick::HTTPServer.new({
+ :Port => 0,
+ :Logger => null_logger,
+ :AccessLog => [],
+ :SSLEnable => true,
+ :SSLCACertificateFile => File.join(DIR, 'ca_cert.pem'),
+ :SSLCertificate => cert('ssl_cert.pem'),
+ :SSLPrivateKey => key('ssl_key.pem'),
+ :SSLVerifyClient => nil,
+ :SSLCertName => nil
+ }.merge(config))
+ server.mount_proc("/yaml") { |req, res|
+ res.body = "--- true\n"
+ }
+ server.mount_proc("/insecure_redirect") { |req, res|
+ res.set_redirect(WEBrick::HTTPStatus::MovedPermanently, req.query['to'])
+ }
+ server.ssl_context.tmp_dh_callback = proc { DH_PARAM }
+ t = Thread.new do
+ begin
+ server.start
+ rescue Exception => ex
+ abort ex.message
+ puts "ERROR during server thread: #{ex.message}"
+ end
+ end
+ while server.status != :Running
+ sleep 0.1
+ unless t.alive?
+ t.join
+ raise
+ end
+ end
+ server
+ end
+
+
+
private
def start_server(port, data)
@@ -734,6 +827,14 @@ gems:
end
sleep 0.2 # Give the servers time to startup
end
+
+ def cert(filename)
+ OpenSSL::X509::Certificate.new(File.read(File.join(DIR, filename)))
+ end
+
+ def key(filename)
+ OpenSSL::PKey::RSA.new(File.read(File.join(DIR, filename)))
+ end
end
end