Send email from Ruby program with TLS - ruby

I am trying to send an email from a Ruby program. The smtp server is an Exchange 2007 server that requires me to login to send the email.
#!/usr/bin/ruby
require 'rubygems'
require 'net/smtp'
msgstr = "Test email."
smtp = Net::SMTP.start('smtp.server.com', 587,
'mail.server.com', 'username', 'password', :login) do |smtp|
smtp.send_message msgstr, 'from#server.com', 'to#server.com'
end
When I run this I get the following error.
/usr/lib/ruby/1.8/net/smtp.rb:948:in `check_auth_continue':
530 5.7.0 Must issue a STARTTLS command first (Net::SMTPAuthenticationError)
from /usr/lib/ruby/1.8/net/smtp.rb:740:in `auth_login'
from /usr/lib/ruby/1.8/net/smtp.rb:921:in `critical'
from /usr/lib/ruby/1.8/net/smtp.rb:739:in `auth_login'
from /usr/lib/ruby/1.8/net/smtp.rb:725:in `send'
from /usr/lib/ruby/1.8/net/smtp.rb:725:in `authenticate'
from /usr/lib/ruby/1.8/net/smtp.rb:566:in `do_start'
from /usr/lib/ruby/1.8/net/smtp.rb:525:in `start'
from /usr/lib/ruby/1.8/net/smtp.rb:463:in `start'
I can't find anything in the Ruby api for Net::SMTP referencing TLS or a STARTTLS command.
EDIT:
Download smtp-tls.rb, the code doesn't change much but here is what I got to work.
#!/usr/bin/ruby
require 'rubygems'
require 'net/smtp'
require 'smtp-tls'
msgstr = <<MESSAGE_END
From: me <me#test.com>
To: you <you#test.com>
Subject: e-mail test
body of email
MESSAGE_END
smtp = Net::SMTP.start('smtp.test.com', 587, 'test.com', 'username', 'passwd', :login) do |smtp|
smtp.send_message msgstr, 'me#test.com', ['you#test.com']
end
EDIT: Works with ruby 1.8.6

No gem required in Ruby 1.9.3
You don't need a gem to do this (at least, not for Gmail and Ruby 1.9.3), the documentation is just terrible.
See https://stackoverflow.com/a/3559598/4376

I couldn't get it working using your updated example. But the following did work for me.
require 'rubygems'
require 'smtp_tls'
require 'net/smtp'
smtp = Net::SMTP.new 'smtp.gmail.com', 587
smtp.enable_starttls
smtp.start(Socket.gethostname,username,password,:login) do |server|
server.send_message msg, from, to
end

Net::SMTP doesn't look like it supports startTLS encryption. I did find a project on github that has code for dealing with this, though.
smtp-tls

This is a solution using the tlsmail gem:
require 'rubygems'
require 'tlsmail'
require 'net/smtp'
Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)
Net::SMTP.start(server,25,Socket.gethostname,username,password,:login) do |server|
server.send_message msg, from, to
end

Related

Rest-Client gem RoR, Getting SSL wrong version error

I want to build a cli ruby app which sends requests to Rails API server. I wanted to use rest-client gem to do that. Every time i use
RestClient.post
I get the following error
SSL_connect returned=1 errno=0 state=error: wrong version number (OpenSSL::SSL::SSLError)
Is there anything i can do for it to run from the console? The code is pretty simple, I just wanted to test out the feature, so don't worry, that's not final.
I am running rails 6.0.3, ruby 2.6.3.
require "tty-prompt"
prompt = TTY::Prompt.new
require 'rest-client'
if prompt.yes? "Do you have an account ?"
email = prompt.ask('What is your email?') do |q|
q.validate(/\A\w+#\w+\.\w+\Z/, 'Invalid email address')
end
pass = prompt.mask('password:')
puts email
puts pass
RestClient.post "https://localhost:3000/auth/sign_in", "email: #{email},password:#{pass}"
puts response.code
else
RestClient.post "https://localhost:3000/auth", "email: #{email},password:#{pass}"
end
I would like for the cli app to send a request to API, That's it, rest-client doesn't want to cooperate with me. Thank You :D
Likely the port 3000 you access is only http:// and not https://. Accessing a plain http:// port with https:// will cause the client to interpret the servers HTTP error message (since the beginning of the TLS handshake sent by the client was not valid HTTP) wrongly as HTTPS which can result in strange errors like invalid packet length or also wrong version number.

Ruby Windows - Eventmachine gem got installed, but throws error when executing EM.run

Sir, I follow the link https://github.com/eventmachine/eventmachine/wiki/Building-EventMachine-with-SSL-on-Windows
to install eventmachine gem in my windows system.
The gem got successfully installed.
But, I am getting this following error, when I used the following piece of code to connect to websocket and tried to fetch some data.
require 'faye/websocket'
require 'eventmachine'
require 'json'
EM.run {
ws = Faye::WebSocket::Client.new('wss://ws.binaryws.com/websockets/v3')
ws.on :open do |event|
p [:open]
ws.send(JSON.generate({ticks: 'frxUSDJPY'}))
end
ws.on :message do |event|
p [:message, event.data]
end
}
Please help.
terminate called after throwing an instance of 'std::runtime_error'
what(): Encryption not available on this event-machine
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Pony Mail Gem Throws Broken Pipe Error

So I'm using sinatra, and I'm trying to send emails from the app for basic verification reasons. I was poking around the docs, and I found the gem pony, which seems to be right up my alley. In my app.rb file I have
require 'rubygems'
require 'sinatra'
require 'pony'
require 'mail'
post '/signup' do
Pony.mail :to => "myself#me.com", :body => "User Sign Up!", :subject => "score"
end
but I end up with a broken pipe error. See below.
I went in to the sendmail.rb, but any change to that and I just got different errors. I think some other people have experienced a similar problem.
Can you send mail with Pony manually via IRB?
$ irb
>> require 'rubygems'
>> require 'pony'
>> mail = Pony.mail :to => "myself#me.com", :body => "User sign up!", :subject => "score"
You may need to add more options (such as SMTP servers). See https://github.com/benprew/pony for configuration.
If you find yourself having the same problem as me, it's very easy to fix. Info here
Basically you just have to run these three lines in the terminal
sudo mkdir -p /Library/Server/Mail/Data/spool
sudo /usr/sbin/postfix set-permissions
sudo /usr/sbin/postfix start
This answer was given to me at https://apple.stackexchange.com/questions/54051/sendmail-error-on-os-x-mountain-lion

Ruby http client with "native" ntlm proxy support

I am looking for a ruby HTTP client gem that supports NTLM proxy authentication "natively" - not through cntlm or similar local proxies.
Any hints appreciated.
A little digging unearthed Typhoeus:
require 'typhoeus'
e=Typhoeus::Easy.new
e.url="http://www.google.com/"
e.proxy = {:server => "1.2.3.4:80"}
e.proxy_auth={:username => "user", :password => 'password'}
e.perform
Typhoeus seems to have been repurposed. The libcurl wrapper is now Ethon (https://github.com/typhoeus/ethon).
I've successfully authenticated with an NTLM proxy using Curb (https://github.com/taf2/curb), another libcurl wrapper:
require 'spec_helper'
require 'curl'
describe Curl do
it 'should connect via an ISA proxy' do
c = Curl::Easy.new('http://example.com/') do |curl|
curl.proxy_url = 'http://username:password#localhost:8080'
curl.proxy_auth_types = Curl::CURLAUTH_NTLM
end
c.perform
headers = c.header_str.split("\r\n")
#puts headers.inspect
headers.should include 'X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 3.0.19'
end
end
Change your settings and assertion as required.
You can do ntlm with Typhoeus and Ethon - depending how many features you need. Typhoeus has more than Ethon, but Ethon is more powerful as it is more low level.
require 'ethon'
easy = Ethon::Easy.new(
url: "http://www.google.com/",
proxy: "1.2.3.4:80",
proxyuserpwd: "user:password",
proxyauth: "ntlm"
)
easy.perform
Typhoeus accepts the same options:
require 'typhoeus'
request = Typhoeus::Request.new(
"http://www.google.com/",
proxy: "1.2.3.4:80",
proxyuserpwd: "user:password",
proxyauth: "ntlm"
)
request.run
I wrote both code examples without testing them b/c I lack a proxy and with the latest Typhoeus/Ethon versions (which you don't have already according to your example).

How do I get an HTTPS request with SSL client cert to work with Ruby EventMachine?

I am trying to access an HTTPS web service that uses SSL cert authentication using Ruby EventMachine but I am not getting it to work.
I have written the following simple code block to test it end-to-end:
require 'rubygems'
require 'em-http'
EventMachine.run do
url = 'https://foobar.com/'
ssl_opts = {:private_key_file => '/tmp/private.key',
:cert_chain_file => '/tmp/ca.pem',
:verify_peer => false}
http = EventMachine::HttpRequest.new(url).get :ssl => ssl_opts
http.callback do
p http.response_header.status
p http.response_header
p http.response
EventMachine.stop
end
http.errback do
EventMachine.stop
fail "Request failed"
end
end
Running the above outputs <SSL_incomp> followed by the raised RuntimeError message. I have tried running with :verify_peer set to both true and false and it gives me the same error. Running EventMachine::HttpRequest#get without the :ssl option does the same.
I have also tried sending the request to GMail (https://mail.google.com) without the :ssl option (i.e. plain HTTPS without cert) and that works, outputting status code 200, the headers and the body.
I have tried doing the same request to the web service with curl and that works:
curl --silent --cert /tmp/private.key --cacert /tmp/ca.pem https://foobar.com/
I am thinking that I am either using the em-http-request gem or EventMachine incorrectly or that the SSL files are in a format that works with curl but not EventMachine.
I someone knows how to solve the example above or provide a similar example using EventMachine directly would be much appreciated!
The file passed to curl's --cert contains both the cert and the key (unless you pass in a --key separately). Just use /tmp/private.key as the argument to both :private_key_file and :cert_chain_file
See http://github.com/eventmachine/eventmachine/issues/#issue/115 for more details about the issue and a patch that exposes the underlying error (instead of just printing out SSL_incomp).

Resources