Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Net::SMTP behaves differently in JRuby than in MRI #204

Open
ylansegal opened this issue Sep 28, 2015 · 16 comments
Open

Net::SMTP behaves differently in JRuby than in MRI #204

ylansegal opened this issue Sep 28, 2015 · 16 comments

Comments

@ylansegal
Copy link

Sometime after jruby-1.7.19 a change was introduced that changes the Net::SMTP behavior with respect with MRI.

Repro:

require "net/smtp"

message = <<-END_OF_MESSAGE
From: Your Name <your@mail.address>
To: Destination Address <someone@example.com>
Subject: test message
Date: Sat, 23 Jun 2001 16:26:43 +0900
Message-Id: <unique.message.id.string@example.com>

This is a test message.
END_OF_MESSAGE

smtp = Net::SMTP.new("smtp.somewhere.com", 25)

# This is weird, since we are not using TLS but done by default in the "mail" gem
# In any case, in MRI it doesn't cause any issue.
smtp.enable_starttls_auto

smtp.start("localhost") do |smtp_obj|
 response = smtp_obj.send_message(message, "sender@somewhere.com", "receiver@somewhere.com")
end

In jruby-1.7.22 and jruby-9.0.1.0 I get a Java stack-trace:

$ ruby repro.rb
Handshaker.java:1429:in `checkThrown': java.lang.RuntimeException: Algorithm NONE not available
    from SSLEngineImpl.java:535:in `checkTaskThrown'
    from SSLEngineImpl.java:813:in `readNetRecord'
    from SSLEngineImpl.java:781:in `unwrap'
    from SSLEngine.java:624:in `unwrap'
    from SSLSocket.java:605:in `readAndUnwrap'
    from SSLSocket.java:483:in `doHandshake'
    from SSLSocket.java:233:in `connectImpl'
    from SSLSocket.java:210:in `connect'

I can confirm that in jruby-1.7.19 and MRI (2.2.3) the mail message is sent as expected.

I think it's a little weird that the mail gem call enable_starttls_auto by default, unless explicitly told not to (https://github.com/mikel/mail/blob/master/lib/mail/network/delivery_methods/smtp.rb), but in any case, I believe the difference in behavior of the current JRuby release and MRI is worth addressing.

Please do let me know if more information is needed.

Thanks.

@GUI
Copy link

GUI commented Oct 30, 2015

I can confirm we hit the same thing after upgrading to jruby-1.7.22. In our case, the SMTP server was also over port 25, but should be supporting STARTTLS (it's Mandrill's SMTP server if that helps).

As one other data point, we were actually getting a slightly different error messages in our default jruby-1.7.22 installation originally:

OpenSSL::SSL::SSLError: RSA ServerKeyExchange does not comply to algorithm constraints
    from org/jruby/ext/openssl/SSLSocket.java:210:in `connect'
    from /opt/rbenv/versions/jruby-1.7.22/lib/ruby/1.9/net/smtp.rb:584:in `tlsconnect'
    from /opt/rbenv/versions/jruby-1.7.22/lib/ruby/1.9/net/smtp.rb:561:in `do_start'
    from /opt/rbenv/versions/jruby-1.7.22/lib/ruby/1.9/net/smtp.rb:520:in `start'
    from /srv/data/apps/shared/vendor/bundle/jruby/1.9/gems/mail-2.6.3/lib/mail/network/delivery_methods/smtp.rb:112:in `deliver!'
    from /srv/data/apps/shared/vendor/bundle/jruby/1.9/gems/mail-2.6.3/lib/mail/message.rb:2141:in `do_delivery'
    from /srv/data/apps/shared/vendor/bundle/jruby/1.9/gems/mail-2.6.3/lib/mail/message.rb:236:in `deliver'
    from /srv/data/apps/shared/vendor/bundle/jruby/1.9/gems/actionmailer-4.0.13/lib/action_mailer/base.rb:456:in `deliver_mail'
    from /srv/data/apps/shared/vendor/bundle/jruby/1.9/gems/activesupport-4.0.13/lib/active_support/notifications.rb:159:in `instrument'
    from /srv/data/apps/shared/vendor/bundle/jruby/1.9/gems/activesupport-4.0.13/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
    from /srv/data/apps/shared/vendor/bundle/jruby/1.9/gems/activesupport-4.0.13/lib/active_support/notifications.rb:159:in `instrument'
    from /srv/data/apps/shared/vendor/bundle/jruby/1.9/gems/actionmailer-4.0.13/lib/action_mailer/base.rb:454:in `deliver_mail'
    from /srv/data/apps/shared/vendor/bundle/jruby/1.9/gems/mail-2.6.3/lib/mail/message.rb:236:in `deliver'
    from (irb):3:in `evaluate'
    from org/jruby/RubyKernel.java:1079:in `eval'
    from org/jruby/RubyKernel.java:1479:in `loop'
    from org/jruby/RubyKernel.java:1242:in `catch'
    from org/jruby/RubyKernel.java:1242:in `catch'
    from /srv/data/apps/shared/vendor/bundle/jruby/1.9/gems/railties-4.0.13/lib/rails/commands/console.rb:90:in `start'
    from /srv/data/apps/shared/vendor/bundle/jruby/1.9/gems/railties-4.0.13/lib/rails/commands/console.rb:9:in `start'
    from /srv/data/apps/shared/vendor/bundle/jruby/1.9/gems/railties-4.0.13/lib/rails/commands.rb:62:in `(root)'
    from org/jruby/RubyKernel.java:1040:in `require'

However, after adding the latest jruby-openssl v0.9.12 gem to our Gemfile, then we started getting this same Algorithm NONE not available error instead.

@bartkamphorst
Copy link

We are seeing the same Algorithm NONE not available error in our application using jruby v.1.7.22 (and not v.1.7.19), even without starttls.

@k77ch7
Copy link

k77ch7 commented Nov 14, 2015

I cannot reproduce using jruby-1.7.22. What version of Java are you using?

@bartkamphorst
Copy link

For me it's java version "1.7.0_85":
OpenJDK Runtime Environment (IcedTea 2.6.1) (7u85-2.6.1-6~deb7u1)
OpenJDK 64-Bit Server VM (build 24.85-b03, mixed mode)

@ylansegal
Copy link
Author

The original report was using Oracle's java 8:

$ java -version
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode)

@BanzaiMan
Copy link
Member

It seems to me that this is a failure to negotiate SSL handshake with the server in question.

[1] pry(main)> RUBY_DESCRIPTION
=> "jruby 9.0.4.0 (2.2.2) 2015-11-12 b9fb7aa Java HotSpot(TM) 64-Bit Server VM 25.40-b25 on 1.8.0_40-b25 +jit [darwin-x86_64]"
[2] pry(main)> require 'net/smtp'
=> true
[3] pry(main)> smtp = Net::SMTP.new('smtp.mandrillapp.com', 587)
=> #<Net::SMTP smtp.mandrillapp.com:587 started=false>
[4] pry(main)> smtp.enable_starttls_auto
=> #<OpenSSL::SSL::SSLContext:0x65c86db8>
[5] pry(main)> smtp.start
Java::JavaLang::RuntimeException: Algorithm NONE not available
from sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1419)
[6] pry(main)> smtp = Net::SMTP.new('smtp.gmail.com', 587)
=> #<Net::SMTP smtp.gmail.com:587 started=false>
[7] pry(main)> smtp.enable_starttls_auto
=> #<OpenSSL::SSL::SSLContext:0x66273da0>
[8] pry(main)> smtp.start
=> #<Net::SMTP smtp.gmail.com:587 started=true>

In the above, you see that the negotiation fails with our SMTP service provider, but the same procedure works with Gmail. It is not clear to me what ciphers are tried and what ciphers problematic ones support, but whatever Gmail is using, JRuby 9k can use. (This happens with both 0.9.11 and 0.9.12 jruby-openssl gem.)

@k77ch7
Copy link

k77ch7 commented Nov 20, 2015

I was debugging with -J-Djavax.net.debug=ssl option.

  • Gmail ; cipher is TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
  • Mandrill ; cipher is SSL_RSA_EXPORT_WITH_DES40_CBC_SHA

My Env

jruby 1.7.22 (1.9.3p551) 2015-08-20 c28f492 on Java HotSpot(TM) 64-Bit Server VM 1.8.0_66-b17 +jit [darwin-x86_64]

@bartkamphorst
Copy link

I've done some digging as well, and it turns out (no real surprise) that TLS is attempted in my case as well and that the cipher suite for my local postfix is the same as Mandrill's. My bet is that DES 40 is simply not supported anymore.

@TheKidCoder
Copy link

Since I am also having the same issue and the culprit is mandrill, has anyone been able to fix this yet?
I tried changing my port to 465 and now have this:

2015-11-26T00:31:19.379Z 28509 TID-afw WARN: org/jruby/ext/socket/RubyTCPSocket.java:111:in `initialize'
org/jruby/RubyIO.java:1179:in `open'
/home/func01admin/.rbenv/versions/jruby-1.7.23/lib/ruby/1.9/net/smtp.rb:541:in `tcp_socket'
/home/func01admin/.rbenv/versions/jruby-1.7.23/lib/ruby/1.9/net/smtp.rb:550:in `do_start'
org/jruby/ext/timeout/Timeout.java:115:in `timeout'
/home/func01admin/.rbenv/versions/jruby-1.7.23/lib/ruby/1.9/net/smtp.rb:550:in `do_start'
/home/func01admin/.rbenv/versions/jruby-1.7.23/lib/ruby/1.9/net/smtp.rb:520:in `start'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/mail-2.6.3/lib/mail/network/delivery_methods/smtp.rb:112:in `deliver!'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/mail-2.6.3/lib/mail/message.rb:2141:in `do_delivery'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/mail-2.6.3/lib/mail/message.rb:236:in `deliver'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/actionmailer-4.1.14/lib/action_mailer/base.rb:527:in `deliver_mail'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/activesupport-4.1.14/lib/active_support/notifications.rb:159:in `instrument'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/activesupport-4.1.14/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/activesupport-4.1.14/lib/active_support/notifications.rb:159:in `instrument'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/actionmailer-4.1.14/lib/action_mailer/base.rb:525:in `deliver_mail'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/mail-2.6.3/lib/mail/message.rb:236:in `deliver'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq_mailer-0.0.8/lib/sidekiq_mailer/proxy.rb:24:in `deliver!'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq_mailer-0.0.8/lib/sidekiq_mailer/worker.rb:5:in `perform'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq-3.4.2/lib/sidekiq/processor.rb:75:in `execute_job'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq-3.4.2/lib/sidekiq/processor.rb:52:in `process'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq-3.4.2/lib/sidekiq/middleware/chain.rb:127:in `invoke'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/newrelic_rpm-3.11.1.284/lib/new_relic/agent/instrumentation/sidekiq.rb:33:in `call'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/newrelic_rpm-3.11.1.284/lib/new_relic/agent/instrumentation/controller_instrumentation.rb:353:in `perform_action_with_newrelic_trace'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/newrelic_rpm-3.11.1.284/lib/new_relic/agent/instrumentation/sidekiq.rb:29:in `call'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq-3.4.2/lib/sidekiq/middleware/chain.rb:129:in `invoke'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq-3.4.2/lib/sidekiq/middleware/server/active_record.rb:6:in `call'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq-3.4.2/lib/sidekiq/middleware/chain.rb:129:in `invoke'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq-3.4.2/lib/sidekiq/middleware/server/retry_jobs.rb:74:in `call'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq-3.4.2/lib/sidekiq/middleware/chain.rb:129:in `invoke'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq-3.4.2/lib/sidekiq/middleware/server/logging.rb:15:in `call'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq-3.4.2/lib/sidekiq/logging.rb:30:in `with_context'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq-3.4.2/lib/sidekiq/middleware/server/logging.rb:11:in `call'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq-3.4.2/lib/sidekiq/middleware/chain.rb:129:in `invoke'
org/jruby/RubyProc.java:281:in `call'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq-3.4.2/lib/sidekiq/middleware/chain.rb:132:in `invoke'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq-3.4.2/lib/sidekiq/processor.rb:51:in `process'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq-3.4.2/lib/sidekiq/processor.rb:98:in `stats'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/sidekiq-3.4.2/lib/sidekiq/processor.rb:50:in `process'
org/jruby/RubyKernel.java:1930:in `public_send'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/celluloid-0.16.0/lib/celluloid/calls.rb:26:in `dispatch'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/celluloid-0.16.0/lib/celluloid/calls.rb:122:in `dispatch'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/celluloid-0.16.0/lib/celluloid/cell.rb:60:in `invoke'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/celluloid-0.16.0/lib/celluloid/cell.rb:71:in `task'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/celluloid-0.16.0/lib/celluloid/actor.rb:357:in `task'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/celluloid-0.16.0/lib/celluloid/tasks.rb:57:in `initialize'
/srv/www/reppro/shared/bundle/jruby/1.9/gems/celluloid-0.16.0/lib/celluloid/tasks/task_fiber.rb:15:in `create'

@k77ch7
Copy link

k77ch7 commented Dec 4, 2015

Workaround:
using smtp.enable_starttls_auto OpenSSL::SSL::SSLContext.new("TLSv1_2_client").

@0xrahulm
Copy link

@TheKidCoder : I had the same issue after changing the port to 465, It's because you need to start Postfix on your mac and also enable port 465, which is disabled by default:

  • First edit the master.conf:
    sudo vim /etc/postfix/master.cf
  • Remove the '#' comment from line 465 inet n - n - - smtpd
  • now start postfix, or reload it: sudo postfix reload or sudo postfix start

@kgx
Copy link

kgx commented Jun 7, 2016

To follow up on @k77ch7 's workaround, the following monkey patch works for me:

require 'net/smtp'

class << Net::SMTP
  remove_method :default_ssl_context # if defined?(Net::SMTP.default_ssl_context)
end

module Net
  class SMTP
    def SMTP.default_ssl_context
      OpenSSL::SSL::SSLContext.new('TLSv1_2_client')
    end
  end
end

This will globally change SMTP to use a TLS v1.2 cipher suite, which avoids this issue.

@maccharlesnmx
Copy link

maccharlesnmx commented Jun 23, 2017

I encountered this error when using Rails with Postfix configured as a gmail relay on Ubuntu.

The solution was to ensure that the default "TLS Parameters" are commented out or removed from /etc/postfix/main.cf after configuring the relay settings. Restart postfix after modifications to main.cf

@headius
Copy link
Member

headius commented Jun 23, 2017

@maccharlesnmx Did you have this issue on a recent version of JRuby? The most recent replies here were all (somewhat older) versions of JRuby 1.7.

@maccharlesnmx
Copy link

@headius I'm using JRuby 9.1.12.0

To be clear, I was able to resolve the "Algorithm NONE not available" error by adjusting my Postfix configuration and no monkey patching. I posted my case here because it seemed like a very specific error message, and searching for it leads directly to this issue, so it might help others.

I can't be certain that my case is the same as the original setup from @ylansegal, but it seems related to those who mention using JRuby with Postfix.

@headius
Copy link
Member

headius commented Jul 18, 2020

I'm pretty sure this is really an OpenSSL bug so I'm transferring the issue there.

Perhaps someone can test against a more recent JRuby? We expanded support for ciphers since this bug was last updated.

@headius headius transferred this issue from jruby/jruby Jul 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants