1

For the past 2 days, I think I've been through every single available (google'able) post about this SSL-Error in connection with Net::HTTP: OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A

What I tried doing in the first place, was connecting to a EtherPad server (https://test.titanpad.com), signing in, and downloading a zip-archive via using rubygems & mechanize; however, unfortunately I don't even get up to that point due to said SSL-Error. After trying to debug the issue from within a mechanize object (f.e. by setting cert, ca_file, cert_store, verify_mode, etc. manually in the script), I went one level closer to the actual issue, trying to connect to https://test.titanpad.com by simply using Net::HTTP:

(in this example, I first connected to https://encrypted.google.com to make sure, SSL should work out; the attempt to connect to the EtherPad server starts from line 6)

irb(main):001:0> require 'net/https'
=> true
irb(main):002:0> google = Net::HTTP.new('encrypted.google.com', 443)
=> #<Net::HTTP encrypted.google.com:443 open=false>
irb(main):003:0> google.use_ssl = true
=> true
irb(main):004:0> google.ca_file = '/opt/local/share/curl/curl-ca-bundle.crt' if File.exists?('/opt/local/share/curl/curl-ca-bundle.crt')
=> "/opt/local/share/curl/curl-ca-bundle.crt"
irb(main):005:0> google.request_get('/')
=> #<Net::HTTPOK 200 OK readbody=true>

irb(main):006:0> etherpad = Net::HTTP.new('test.titanpad.com', 443)
=> #<Net::HTTP test.titanpad.com:443 open=false>
irb(main):007:0> etherpad.use_ssl = true
=> true
irb(main):008:0> etherpad.ca_file = '/opt/local/share/curl/curl-ca-bundle.crt' if File.exists?('/opt/local/share/curl/curl-ca-bundle.crt')
=> "/opt/local/share/curl/curl-ca-bundle.crt"
irb(main):009:0> etherpad.request_get('/')
OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:799:in `connect'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:799:in `block in connect'
    from /opt/local/lib/ruby1.9/1.9.1/timeout.rb:54:in `timeout'
    from /opt/local/lib/ruby1.9/1.9.1/timeout.rb:99:in `timeout'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:799:in `connect'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:755:in `do_start'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:744:in `start'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:1284:in `request'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:1195:in `request_get'
    from (irb):9
    from /opt/local/bin/irb:12:in `<main>'

Even when using verify_mode OpenSSL::SSL::VERIFY_NONE, OpenSSL bails out:

irb(main):010:0> etherpad.verify_mode = OpenSSL::SSL::VERIFY_NONE
=> 0
irb(main):011:0> etherpad.request_get('/')
OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:799:in `connect'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:799:in `block in connect'
    from /opt/local/lib/ruby1.9/1.9.1/timeout.rb:54:in `timeout'
    from /opt/local/lib/ruby1.9/1.9.1/timeout.rb:99:in `timeout'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:799:in `connect'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:755:in `do_start'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:744:in `start'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:1284:in `request'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:1195:in `request_get'
    from (irb):11
    from /opt/local/bin/irb:12:in `<main>'

After further playing around with openssl itself, it turns out the real trouble in this case is that the use of SSLv3 has to be forced for the handshake with the Jetty 6.1.20 server behind titanpad.com to work:

irb(main):001:0> require 'net/https'
=> true
irb(main):002:0> etherpad = Net::HTTP.new('test.titanpad.com', 443)
=> #<Net::HTTP test.titanpad.com:443 open=false>
irb(main):003:0> etherpad.use_ssl = true
=> true
irb(main):004:0> etherpad.ssl_version = "SSLv3"
=> "SSLv3"
irb(main):005:0> etherpad.ca_file = '/opt/local/share/curl/curl-ca-bundle.crt' if File.exists?('/opt/local/share/curl/curl-ca-bundle.crt')
=> "/opt/local/share/curl/curl-ca-bundle.crt"
irb(main):006:0> etherpad.request_get('/')
=> #<Net::HTTPFound 302 Found readbody=true>

Now while this obviously works when using Net::HTTP, there is no such option as to set the SSL version to use in Mechanize... and I'd therefore be really glad if someone could point out to me as to how I could enforce SSLv3 via said gem o.O

Thanks again!

System: Mac OSX 10.6.8 ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin10] rubygems installed with mechanize: domain_name (0.5.2), mechanize (2.1.1), net-http-digest_auth (1.2), net-http-persistent (2.4.1), nokogiri (1.5.0), ntlm-http (0.1.1), unf (0.0.4), unf_ext (0.0.4), webrobots (0.0.13)

Jav_Rock
  • 22,059
  • 20
  • 123
  • 164
astera
  • 31
  • 1
  • 4
  • In fact, I'm starting to think this is an OpenSSL-problem with the webserver behind titanpad.com, a Jetty 6.1.20 apparently... – astera Feb 05 '12 at 16:00
  • Hokay, update... I was looking on the wrong ends of the problem - it's the difference between using _any_ kind of SSL, and SSLv3 it seems. So while `openssl s_client -connect test.titanpad.com:443` would error out, forcing v3 with `openssl s_client -no_tls1 -no_ssl2 -ssl3 -connect test.titanpad.com:443` works just fine. – astera Feb 05 '12 at 17:07

1 Answers1

2

Has been fixed by porting the ssl_version functionality from Net::HTTP (via net-http-persistent) to Mechanize v. 2.1.2 (see https://github.com/tenderlove/mechanize/commit/4a228899855e0676ab69c2bf548170c8717465d8).

astera
  • 31
  • 1
  • 4
  • 1
    @astera- I have the same issue even using Mechanize v. 2.7.3. The link you have provided above is not found. Could you please help in resolving this? – owgitt May 27 '15 at 09:15