Skip to content

Commit

Permalink
Merge pull request #14 from tmtm/tls_hostname
Browse files Browse the repository at this point in the history
add tls_hostname parameter.
  • Loading branch information
tmtm authored Oct 25, 2020
2 parents 23f99c2 + d406a20 commit 5c2cfb3
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
22 changes: 14 additions & 8 deletions lib/net/smtp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -409,14 +409,14 @@ def debug_output=(arg)

#
# :call-seq:
# start(address, port = nil, helo: 'localhost', user: nil, secret: nil, authtype: nil, tls_verify: true) { |smtp| ... }
# start(address, port = nil, helo: 'localhost', user: nil, secret: nil, authtype: nil, tls_verify: true, tls_hostname: nil) { |smtp| ... }
# start(address, port = nil, helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... }
#
# Creates a new Net::SMTP object and connects to the server.
#
# This method is equivalent to:
#
# Net::SMTP.new(address, port).start(helo: helo_domain, user: account, secret: password, authtype: authtype, tls_verify: flag)
# Net::SMTP.new(address, port).start(helo: helo_domain, user: account, secret: password, authtype: authtype, tls_verify: flag, tls_hostname: hostname)
#
# === Example
#
Expand Down Expand Up @@ -447,6 +447,8 @@ def debug_output=(arg)
# type, one of :plain, :login, or :cram_md5. See the discussion of
# SMTP Authentication in the overview notes.
# If +tls_verify+ is true, verify the server's certificate. The default is true.
# If the hostname in the server certificate is different from +address+,
# it can be specified with +tls_hostname+.
#
# === Errors
#
Expand All @@ -462,14 +464,15 @@ def debug_output=(arg)
# * IOError
#
def SMTP.start(address, port = nil, *args, helo: nil,
user: nil, secret: nil, password: nil, authtype: nil, tls_verify: true,
user: nil, secret: nil, password: nil, authtype: nil,
tls_verify: true, tls_hostname: nil,
&block)
raise ArgumentError, "wrong number of arguments (given #{args.size + 2}, expected 1..6)" if args.size > 4
helo ||= args[0] || 'localhost'
user ||= args[1]
secret ||= password || args[2]
authtype ||= args[3]
new(address, port).start(helo: helo, user: user, secret: secret, authtype: authtype, tls_verify: tls_verify, &block)
new(address, port).start(helo: helo, user: user, secret: secret, authtype: authtype, tls_verify: tls_verify, tls_hostname: tls_hostname, &block)
end

# +true+ if the SMTP session has been started.
Expand All @@ -479,7 +482,7 @@ def started?

#
# :call-seq:
# start(helo: 'localhost', user: nil, secret: nil, authtype: nil, tls_verify: true) { |smtp| ... }
# start(helo: 'localhost', user: nil, secret: nil, authtype: nil, tls_verify: true, tls_hostname: nil) { |smtp| ... }
# start(helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... }
#
# Opens a TCP connection and starts the SMTP session.
Expand All @@ -495,6 +498,8 @@ def started?
# :login, :plain, and :cram_md5. See the notes on SMTP Authentication
# in the overview.
# If +tls_verify+ is true, verify the server's certificate. The default is true.
# If the hostname in the server certificate is different from +address+,
# it can be specified with +tls_hostname+.
#
# === Block Usage
#
Expand Down Expand Up @@ -534,7 +539,7 @@ def started?
# * IOError
#
def start(*args, helo: nil,
user: nil, secret: nil, password: nil, authtype: nil, tls_verify: true)
user: nil, secret: nil, password: nil, authtype: nil, tls_verify: true, tls_hostname: nil)
raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 0..4)" if args.size > 4
helo ||= args[0] || 'localhost'
user ||= args[1]
Expand All @@ -546,6 +551,7 @@ def start(*args, helo: nil,
if @starttls && @ssl_context_starttls.nil?
@ssl_context_starttls = SMTP.default_ssl_context(tls_verify)
end
@tls_hostname = tls_hostname
if block_given?
begin
do_start helo, user, secret, authtype
Expand Down Expand Up @@ -614,10 +620,10 @@ def tlsconnect(s, context)
s = ssl_socket(s, context)
logging "TLS connection started"
s.sync_close = true
s.hostname = @address if s.respond_to? :hostname=
s.hostname = @tls_hostname || @address if s.respond_to? :hostname=
ssl_socket_connect(s, @open_timeout)
if context.verify_mode && context.verify_mode != OpenSSL::SSL::VERIFY_NONE
s.post_connection_check(@address)
s.post_connection_check(@tls_hostname || @address)
end
verified = true
s
Expand Down
18 changes: 16 additions & 2 deletions test/net/smtp/test_sslcontext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
module Net
class TestSSLContext < Test::Unit::TestCase
class MySMTP < SMTP
attr_reader :__ssl_context
attr_reader :__ssl_context, :__tls_hostname

def initialize(socket)
@fake_socket = socket
Expand All @@ -26,7 +26,8 @@ def tlsconnect(*)
def ssl_socket(socket, context)
@__ssl_context = context
s = super
s.define_singleton_method(:post_connection_check){|_|}
hostname = @__tls_hostname = ''
s.define_singleton_method(:post_connection_check){ |name| hostname.replace(name) }
s
end
end
Expand Down Expand Up @@ -110,5 +111,18 @@ def test_start_with_tls_verify_false
smtp.start(tls_verify: false)
assert_equal(OpenSSL::SSL::VERIFY_NONE, smtp.__ssl_context.verify_mode)
end

def test_start_with_tls_hostname
smtp = MySMTP.new(start_smtpd(true))
smtp.start(tls_hostname: "localhost")
assert_equal("localhost", smtp.__tls_hostname)
end

def test_start_without_tls_hostname
smtp = MySMTP.new(start_smtpd(true))
smtp.start
assert_equal("smtp.example.com", smtp.__tls_hostname)
end

end
end

0 comments on commit 5c2cfb3

Please sign in to comment.