Skip to content

Commit

Permalink
Merge pull request #25 from rhenium/ky/openssl-updates
Browse files Browse the repository at this point in the history
Miscellaneous OpenSSL-related improvements
  • Loading branch information
tmtm authored May 15, 2021
2 parents 11bcc44 + 5513ae0 commit 76fddd1
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 194 deletions.
37 changes: 17 additions & 20 deletions lib/net/smtp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ class SMTPUnsupportedCommand < ProtocolError
# user: 'Your Account', secret: 'Your Password', authtype: :cram_md5)
#
class SMTP < Protocol
VERSION = "0.2.1-patch-ssl-context"
VERSION = "0.2.1"

Revision = %q$Revision$.split[1]

Expand Down Expand Up @@ -298,7 +298,7 @@ def tls?
# this object. Must be called before the connection is established
# to have any effect. +context+ is a OpenSSL::SSL::SSLContext object.
def enable_tls(context = nil)
raise 'openssl library not installed' unless defined?(OpenSSL)
raise 'openssl library not installed' unless defined?(OpenSSL::VERSION)
raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @starttls == :always
@tls = true
@ssl_context_tls = context
Expand Down Expand Up @@ -335,7 +335,7 @@ def starttls_auto?
# Enables SMTP/TLS (STARTTLS) for this object.
# +context+ is a OpenSSL::SSL::SSLContext object.
def enable_starttls(context = nil)
raise 'openssl library not installed' unless defined?(OpenSSL)
raise 'openssl library not installed' unless defined?(OpenSSL::VERSION)
raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @tls
@starttls = :always
@ssl_context_starttls = context
Expand All @@ -344,7 +344,7 @@ def enable_starttls(context = nil)
# Enables SMTP/TLS (STARTTLS) for this object if server accepts.
# +context+ is a OpenSSL::SSL::SSLContext object.
def enable_starttls_auto(context = nil)
raise 'openssl library not installed' unless defined?(OpenSSL)
raise 'openssl library not installed' unless defined?(OpenSSL::VERSION)
raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @tls
@starttls = :auto
@ssl_context_starttls = context
Expand Down Expand Up @@ -552,19 +552,19 @@ def start(*args, helo: nil,
user ||= args[1]
secret ||= password || args[2]
authtype ||= args[3]
ssl_context_params = ssl_context_params ? ssl_context_params : {}
if ssl_context_params.has_key?(:verify_mode)
tls_verify = ssl_context_params[:verify_mode] != OpenSSL::SSL::VERIFY_NONE
else
ssl_context_params[:verify_mode] = tls_verify ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
end
if @tls && @ssl_context_tls.nil?
@ssl_context_tls = SMTP.default_ssl_context(ssl_context_params)
end
if @starttls && @ssl_context_starttls.nil?
@ssl_context_starttls = SMTP.default_ssl_context(ssl_context_params)
if defined?(OpenSSL::VERSION)
ssl_context_params = ssl_context_params ? ssl_context_params : {}
unless ssl_context_params.has_key?(:verify_mode)
ssl_context_params[:verify_mode] = tls_verify ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
end
if @tls && @ssl_context_tls.nil?
@ssl_context_tls = SMTP.default_ssl_context(ssl_context_params)
end
if @starttls && @ssl_context_starttls.nil?
@ssl_context_starttls = SMTP.default_ssl_context(ssl_context_params)
end
@tls_hostname = tls_hostname
end
@tls_hostname = tls_hostname
if block_given?
begin
do_start helo, user, secret, authtype
Expand Down Expand Up @@ -636,11 +636,8 @@ def tlsconnect(s, context)
s = ssl_socket(s, context)
logging "TLS connection started"
s.sync_close = true
s.hostname = @tls_hostname || @address if s.respond_to? :hostname=
s.hostname = @tls_hostname || @address
ssl_socket_connect(s, @open_timeout)
if context.verify_mode && context.verify_mode != OpenSSL::SSL::VERIFY_NONE
s.post_connection_check(@tls_hostname || @address)
end
verified = true
s
ensure
Expand Down
74 changes: 35 additions & 39 deletions test/net/smtp/test_smtp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ def test_crlf_injection
end

def test_tls_connect
omit "openssl library not loaded" unless defined?(OpenSSL::VERSION)

servers = Socket.tcp_server_sockets("localhost", 0)
ctx = OpenSSL::SSL::SSLContext.new
ctx.ca_file = CA_FILE
Expand All @@ -132,52 +134,46 @@ def test_tls_connect
ctx.cert = File.open(SERVER_CERT) { |f|
OpenSSL::X509::Certificate.new(f)
}
begin
sock = nil
Thread.start do
s = accept(servers)
sock = OpenSSL::SSL::SSLSocket.new(s, ctx)
sock.sync_close = true
sock.accept
sock.write("220 localhost Service ready\r\n")
sock.gets
sock.write("250 localhost\r\n")
sock.gets
sock.write("221 localhost Service closing transmission channel\r\n")
end
smtp = Net::SMTP.new("localhost", servers[0].local_address.ip_port)
smtp.enable_tls
smtp.open_timeout = 1
smtp.start(tls_verify: false) do
end
ensure
sock.close if sock
servers.each(&:close)
sock = nil
Thread.start do
s = accept(servers)
sock = OpenSSL::SSL::SSLSocket.new(s, ctx)
sock.sync_close = true
sock.accept
sock.write("220 localhost Service ready\r\n")
sock.gets
sock.write("250 localhost\r\n")
sock.gets
sock.write("221 localhost Service closing transmission channel\r\n")
end
rescue LoadError
# skip (require openssl)
smtp = Net::SMTP.new("localhost", servers[0].local_address.ip_port)
smtp.enable_tls
smtp.open_timeout = 1
smtp.start(tls_verify: false) do
end
ensure
sock&.close
servers&.each(&:close)
end

def test_tls_connect_timeout
omit "openssl library not loaded" unless defined?(OpenSSL::VERSION)

servers = Socket.tcp_server_sockets("localhost", 0)
begin
sock = nil
Thread.start do
sock = accept(servers)
end
smtp = Net::SMTP.new("localhost", servers[0].local_address.ip_port)
smtp.enable_tls
smtp.open_timeout = 0.1
assert_raise(Net::OpenTimeout) do
smtp.start do
end
sock = nil
Thread.start do
sock = accept(servers)
end
smtp = Net::SMTP.new("localhost", servers[0].local_address.ip_port)
smtp.enable_tls
smtp.open_timeout = 0.1
assert_raise(Net::OpenTimeout) do
smtp.start do
end
rescue LoadError
# skip (require openssl)
ensure
sock.close if sock
servers.each(&:close)
end
ensure
sock&.close
servers&.each(&:close)
end

def test_eof_error_backtrace
Expand Down
99 changes: 0 additions & 99 deletions test/net/smtp/test_ssl_socket.rb

This file was deleted.

Loading

0 comments on commit 76fddd1

Please sign in to comment.