Skip to content

Commit 25199dd

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 ea47e34 commit 25199dd

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
@@ -802,8 +802,21 @@ def idle_response_timeout; config.idle_response_timeout end
802802
# Returns +false+ for a plaintext connection.
803803
attr_reader :ssl_ctx_params
804804

805-
# Creates a new Net::IMAP object and connects it to the specified
806-
# +host+.
805+
# Creates a new Net::IMAP object and connects it to the specified +host+.
806+
#
807+
# ==== Default port and SSL
808+
#
809+
# When both both +port+ and +ssl+ are unspecified or +nil+,
810+
# +ssl+ is determined by {config.default_ssl}[rdoc-ref:Config#default_ssl]
811+
# and +port+ is based on that implicit value for +ssl+.
812+
#
813+
# When only one of the two is specified:
814+
# * When +ssl+ is truthy, +port+ defaults to +993+.
815+
# * When +ssl+ is +false+, +port+ defaults to +143+.
816+
# * When +port+ is +993+, +ssl+ defaults to +true+.
817+
# * When +port+ is +143+, +ssl+ defaults to +false+.
818+
# * When +port+ is nonstandard, the default for +ssl+ is determined
819+
# by {config.default_ssl}[rdoc-ref:Config#default_ssl].
807820
#
808821
# ==== Options
809822
#
@@ -831,7 +844,9 @@ def idle_response_timeout; config.idle_response_timeout end
831844
# SSL session verification mode. Valid modes include
832845
# +OpenSSL::SSL::VERIFY_PEER+ and +OpenSSL::SSL::VERIFY_NONE+.
833846
#
834-
# See {OpenSSL::SSL::SSLContext}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html] for other valid SSL context params.
847+
# See
848+
# {OpenSSL::SSL::SSLContext}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html]
849+
# for other valid SSL context params.
835850
#
836851
# See DeprecatedClientOptions.new for deprecated SSL arguments.
837852
#
@@ -912,7 +927,7 @@ def initialize(host, port: nil, ssl: nil,
912927
# Config options
913928
@host = host
914929
@config = Config.new(config, **config_options)
915-
@port = port || (ssl ? SSL_PORT : PORT)
930+
ssl, @port = default_ssl_and_port(ssl, port)
916931
@ssl_ctx_params, @ssl_ctx = build_ssl_ctx(ssl)
917932

918933
# Basic Client State
@@ -2887,6 +2902,27 @@ def remove_response_handler(handler)
28872902
PORT = 143 # :nodoc:
28882903
SSL_PORT = 993 # :nodoc:
28892904

2905+
def default_ssl_and_port(tls, port)
2906+
if tls.nil? && port
2907+
tls = true if port == SSL_PORT || /\Aimaps\z/i === port
2908+
tls = false if port == PORT
2909+
elsif port.nil? && !tls.nil?
2910+
port = tls ? SSL_PORT : PORT
2911+
end
2912+
if tls.nil? && port.nil?
2913+
tls = config.default_tls.dup.freeze
2914+
port = tls ? SSL_PORT : PORT
2915+
if tls.nil?
2916+
warn "A future version of Net::IMAP::Config#default_tls " \
2917+
"will default to 'true', for secure connections by default. " \
2918+
"Use 'Net::IMAP.new(host, ssl: false)' or " \
2919+
"Net::IMAP.config.default_tls = false' to silence this warning."
2920+
end
2921+
end
2922+
tls &&= tls.respond_to?(:to_hash) ? tls.to_hash : {}
2923+
[tls, port]
2924+
end
2925+
28902926
def start_imap_connection
28912927
@greeting = get_server_greeting
28922928
@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)