Skip to content

Commit 69cd279

Browse files
committed
🗑️ Add deprecation warnings to .new and #starttls [🚧 WIP]
* `ssl` was renamed to `tls` in most places, with backwards compatible aliases. Using `ssl` does not print any deprecation warnings. Using both `tls` and `ssl` keywords raises an ArgumentError. * Preparing for a (backwards-incompatible) secure-by-default configuration, `Net::IMAP.default_tls` will determine the value for `tls` when no explicit port or tls setting is provided. Using port 143 will be insecure by default. Using port 993 will be secure by default. Providing no explicit port will use `Net::IMAP.default_tls` with the appropriate port. And providing any other unknown port will use `default_tls` with a warning. 🚧 TODO: should we use a different config var for default tls params when port is 993 and `tls` is unspecified? 🚧 TODO: should we use a different config var for choosing `tls` when `port` is non-standard vs choosing `port` and `tls` when neither are specified? 🚧 TODO: should we use a different var for `default_tls` be used to config params when port is 993 but tls is implicit? Another var?
1 parent 45c6628 commit 69cd279

File tree

2 files changed

+79
-5
lines changed

2 files changed

+79
-5
lines changed

lib/net/imap.rb

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -816,8 +816,21 @@ def idle_response_timeout; config.idle_response_timeout end
816816
# Returns +false+ for a plaintext connection.
817817
attr_reader :ssl_ctx_params
818818

819-
# Creates a new Net::IMAP object and connects it to the specified
820-
# +host+.
819+
# Creates a new Net::IMAP object and connects it to the specified +host+.
820+
#
821+
# ==== Default port and SSL
822+
#
823+
# When both both +port+ and +ssl+ are unspecified or +nil+,
824+
# +ssl+ is determined by {config.default_ssl}[rdoc-ref:Config#default_ssl]
825+
# and +port+ is based on that implicit value for +ssl+.
826+
#
827+
# When only one of the two is specified:
828+
# * When +ssl+ is truthy, +port+ defaults to +993+.
829+
# * When +ssl+ is +false+, +port+ defaults to +143+.
830+
# * When +port+ is +993+, +ssl+ defaults to +true+.
831+
# * When +port+ is +143+, +ssl+ defaults to +false+.
832+
# * When +port+ is nonstandard, the default for +ssl+ is determined
833+
# by {config.default_ssl}[rdoc-ref:Config#default_ssl].
821834
#
822835
# ==== Options
823836
#
@@ -845,7 +858,9 @@ def idle_response_timeout; config.idle_response_timeout end
845858
# SSL session verification mode. Valid modes include
846859
# +OpenSSL::SSL::VERIFY_PEER+ and +OpenSSL::SSL::VERIFY_NONE+.
847860
#
848-
# See {OpenSSL::SSL::SSLContext}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html] for other valid SSL context params.
861+
# See
862+
# {OpenSSL::SSL::SSLContext}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html]
863+
# for other valid SSL context params.
849864
#
850865
# See DeprecatedClientOptions.new for deprecated SSL arguments.
851866
#
@@ -926,7 +941,7 @@ def initialize(host, port: nil, ssl: nil,
926941
# Config options
927942
@host = host
928943
@config = Config.new(config, **config_options)
929-
@port = port || (ssl ? SSL_PORT : PORT)
944+
ssl, @port = default_ssl_and_port(ssl, port)
930945
@ssl_ctx_params, @ssl_ctx = build_ssl_ctx(ssl)
931946

932947
# Basic Client State
@@ -3100,6 +3115,27 @@ def remove_response_handler(handler)
31003115
PORT = 143 # :nodoc:
31013116
SSL_PORT = 993 # :nodoc:
31023117

3118+
def default_ssl_and_port(tls, port)
3119+
if tls.nil? && port
3120+
tls = true if port == SSL_PORT || /\Aimaps\z/i === port
3121+
tls = false if port == PORT
3122+
elsif port.nil? && !tls.nil?
3123+
port = tls ? SSL_PORT : PORT
3124+
end
3125+
if tls.nil? && port.nil?
3126+
tls = config.default_tls.dup.freeze
3127+
port = tls ? SSL_PORT : PORT
3128+
if tls.nil?
3129+
warn "A future version of Net::IMAP::Config#default_tls " \
3130+
"will default to 'true', for secure connections by default. " \
3131+
"Use 'Net::IMAP.new(host, ssl: false)' or " \
3132+
"Net::IMAP.config.default_tls = false' to silence this warning."
3133+
end
3134+
end
3135+
tls &&= tls.respond_to?(:to_hash) ? tls.to_hash : {}
3136+
[tls, port]
3137+
end
3138+
31033139
def start_imap_connection
31043140
@greeting = get_server_greeting
31053141
@capabilities = capabilities_from_resp_code @greeting

lib/net/imap/config.rb

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,35 @@ def self.[](config)
207207
# The default value is +5+ seconds.
208208
attr_accessor :idle_response_timeout, type: Integer
209209

210+
# The default value for the +ssl+ option of Net::IMAP.new, when +port+ is
211+
# unspecified or non-standard and +ssl+ is unspecified. default_ssl is
212+
# ignored when Net::IMAP.new is called with any value for +ssl+ besides
213+
# +nil+,
214+
#
215+
# *Note*: A future release of Net::IMAP will set the default to +true+, as
216+
# per RFC7525[https://tools.ietf.org/html/rfc7525],
217+
# RFC7817[https://tools.ietf.org/html/rfc7817], and
218+
# RFC8314[https://tools.ietf.org/html/rfc8314].
219+
#
220+
# <em>(The default_ssl config attribute was added in +v0.5.?+.)</em>
221+
#
222+
# ==== Valid options
223+
#
224+
# [+false+ <em>(original behavior)</em>]
225+
# Plaintext by default, with no warnings.
226+
# [+nil+ <em>(planned default for +v0.6+)</em>]
227+
# Plaintext by default, and prints a warning.
228+
#
229+
# <em>This option will be removed in +v0.7+, when +:warn+ becomes the
230+
# default.</em>
231+
# [+:warn+ <em>(planned default for +v0.7+)</em>]
232+
# A warning will be printed, and behave as if the default were +true+.
233+
# [+true+ <em>(planned future default)</em>]
234+
# Use TLS by default, with the default SSL context params set by calling
235+
# {OpenSSL::SSL::SSLContext#set_params}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-set_params]
236+
# with no params.
237+
attr_accessor :default_ssl, type: [false, nil, :warn, true]
238+
210239
# Whether to use the +SASL-IR+ extension when the server and \SASL
211240
# mechanism both support it. Can be overridden by the +sasl_ir+ keyword
212241
# parameter to Net::IMAP#authenticate.
@@ -362,6 +391,7 @@ def defaults_hash
362391
debug: false,
363392
open_timeout: 30,
364393
idle_response_timeout: 5,
394+
default_ssl: false,
365395
sasl_ir: true,
366396
enforce_logindisabled: true,
367397
responses_without_block: :warn,
@@ -390,9 +420,17 @@ def defaults_hash
390420

391421
version_defaults[0.6] = Config[0.5].dup.update(
392422
responses_without_block: :frozen_dup,
423+
default_ssl: nil,
393424
).freeze
394425
version_defaults[:next] = Config[0.6]
395-
version_defaults[:future] = Config[:next]
426+
427+
version_defaults[0.7] = Config[0.6].dup.update(
428+
default_ssl: :warn,
429+
).freeze
430+
431+
version_defaults[:future] = Config[0.7].dup.update(
432+
default_ssl: true,
433+
).freeze
396434

397435
version_defaults.freeze
398436
end

0 commit comments

Comments
 (0)