Skip to content

Commit 4213389

Browse files
Net::SMTP.start() and #start() accepts ssl_context_params keyword argument
Additional params are passed to OpenSSL::SSL::SSLContext#set_params. For example, `Net::SMTP#start(ssl_context_params: { cert_store: my_store, timeout: 123 })` calls `set_params({ cert_store: my_store, timeout: 123 })`.
1 parent e4bbf95 commit 4213389

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

lib/net/smtp.rb

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,9 @@ class << self
191191
alias default_ssl_port default_tls_port
192192
end
193193

194-
def SMTP.default_ssl_context(verify_peer=true)
194+
def SMTP.default_ssl_context(ssl_context_params = nil)
195195
context = OpenSSL::SSL::SSLContext.new
196-
context.verify_mode = verify_peer ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
197-
store = OpenSSL::X509::Store.new
198-
store.set_default_paths
199-
context.cert_store = store
196+
context.set_params(ssl_context_params ? ssl_context_params : {})
200197
context
201198
end
202199

@@ -409,14 +406,14 @@ def debug_output=(arg)
409406

410407
#
411408
# :call-seq:
412-
# start(address, port = nil, helo: 'localhost', user: nil, secret: nil, authtype: nil, tls_verify: true, tls_hostname: nil) { |smtp| ... }
409+
# start(address, port = nil, helo: 'localhost', user: nil, secret: nil, authtype: nil, tls_verify: true, tls_hostname: nil, ssl_context_params: nil) { |smtp| ... }
413410
# start(address, port = nil, helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... }
414411
#
415412
# Creates a new Net::SMTP object and connects to the server.
416413
#
417414
# This method is equivalent to:
418415
#
419-
# Net::SMTP.new(address, port).start(helo: helo_domain, user: account, secret: password, authtype: authtype, tls_verify: flag, tls_hostname: hostname)
416+
# Net::SMTP.new(address, port).start(helo: helo_domain, user: account, secret: password, authtype: authtype, tls_verify: flag, tls_hostname: hostname, ssl_context_params: nil)
420417
#
421418
# === Example
422419
#
@@ -450,6 +447,11 @@ def debug_output=(arg)
450447
# If the hostname in the server certificate is different from +address+,
451448
# it can be specified with +tls_hostname+.
452449
#
450+
# Additional SSLContext params can be added to +ssl_context_params+ hash argument and are passed to
451+
# +OpenSSL::SSL::SSLContext#set_params+
452+
#
453+
# +tls_verify: true+ is equivalent to +ssl_context_params: { verify_mode: OpenSSL::SSL::VERIFY_PEER }+.
454+
#
453455
# === Errors
454456
#
455457
# This method may raise:
@@ -465,14 +467,14 @@ def debug_output=(arg)
465467
#
466468
def SMTP.start(address, port = nil, *args, helo: nil,
467469
user: nil, secret: nil, password: nil, authtype: nil,
468-
tls_verify: true, tls_hostname: nil,
470+
tls_verify: true, tls_hostname: nil, ssl_context_params: nil,
469471
&block)
470472
raise ArgumentError, "wrong number of arguments (given #{args.size + 2}, expected 1..6)" if args.size > 4
471473
helo ||= args[0] || 'localhost'
472474
user ||= args[1]
473475
secret ||= password || args[2]
474476
authtype ||= args[3]
475-
new(address, port).start(helo: helo, user: user, secret: secret, authtype: authtype, tls_verify: tls_verify, tls_hostname: tls_hostname, &block)
477+
new(address, port).start(helo: helo, user: user, secret: secret, authtype: authtype, tls_verify: tls_verify, tls_hostname: tls_hostname, ssl_context_params: ssl_context_params, &block)
476478
end
477479

478480
# +true+ if the SMTP session has been started.
@@ -482,7 +484,7 @@ def started?
482484

483485
#
484486
# :call-seq:
485-
# start(helo: 'localhost', user: nil, secret: nil, authtype: nil, tls_verify: true, tls_hostname: nil) { |smtp| ... }
487+
# start(helo: 'localhost', user: nil, secret: nil, authtype: nil, tls_verify: true, tls_hostname: nil, ssl_context_params: nil) { |smtp| ... }
486488
# start(helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... }
487489
#
488490
# Opens a TCP connection and starts the SMTP session.
@@ -501,6 +503,11 @@ def started?
501503
# If the hostname in the server certificate is different from +address+,
502504
# it can be specified with +tls_hostname+.
503505
#
506+
# Additional SSLContext params can be added to +ssl_context_params+ hash argument and are passed to
507+
# +OpenSSL::SSL::SSLContext#set_params+
508+
#
509+
# +tls_verify: true+ is equivalent to +ssl_context_params: { verify_mode: OpenSSL::SSL::VERIFY_PEER }+.
510+
#
504511
# === Block Usage
505512
#
506513
# When this methods is called with a block, the newly-started SMTP
@@ -539,17 +546,23 @@ def started?
539546
# * IOError
540547
#
541548
def start(*args, helo: nil,
542-
user: nil, secret: nil, password: nil, authtype: nil, tls_verify: true, tls_hostname: nil)
549+
user: nil, secret: nil, password: nil, authtype: nil, tls_verify: true, tls_hostname: nil, ssl_context_params: nil)
543550
raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 0..4)" if args.size > 4
544551
helo ||= args[0] || 'localhost'
545552
user ||= args[1]
546553
secret ||= password || args[2]
547554
authtype ||= args[3]
555+
ssl_context_params = ssl_context_params ? ssl_context_params : {}
556+
if ssl_context_params.has_key?(:verify_mode)
557+
tls_verify = ssl_context_params[:verify_mode] != OpenSSL::SSL::VERIFY_NONE
558+
else
559+
ssl_context_params[:verify_mode] = tls_verify ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
560+
end
548561
if @tls && @ssl_context_tls.nil?
549-
@ssl_context_tls = SMTP.default_ssl_context(tls_verify)
562+
@ssl_context_tls = SMTP.default_ssl_context(ssl_context_params)
550563
end
551564
if @starttls && @ssl_context_starttls.nil?
552-
@ssl_context_starttls = SMTP.default_ssl_context(tls_verify)
565+
@ssl_context_starttls = SMTP.default_ssl_context(ssl_context_params)
553566
end
554567
@tls_hostname = tls_hostname
555568
if block_given?

0 commit comments

Comments
 (0)