Skip to content

Commit 5567a93

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 364869b commit 5567a93

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

lib/net/imap.rb

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,20 @@ def max_response_size=(val) config.max_response_size = val end
955955
# Creates a new Net::IMAP object and connects it to the specified
956956
# +host+.
957957
#
958+
# ==== Default port and SSL
959+
#
960+
# When both both +port+ and +ssl+ are unspecified or +nil+,
961+
# +ssl+ is determined by {config.default_ssl}[rdoc-ref:Config#default_ssl]
962+
# and +port+ is based on that implicit value for +ssl+.
963+
#
964+
# When only one of the two is specified:
965+
# * When +ssl+ is truthy, +port+ defaults to +993+.
966+
# * When +ssl+ is +false+, +port+ defaults to +143+.
967+
# * When +port+ is +993+, +ssl+ defaults to +true+.
968+
# * When +port+ is +143+, +ssl+ defaults to +false+.
969+
# * When +port+ is nonstandard, the default for +ssl+ is determined
970+
# by {config.default_ssl}[rdoc-ref:Config#default_ssl].
971+
#
958972
# ==== Options
959973
#
960974
# Accepts the following options:
@@ -1068,7 +1082,7 @@ def initialize(host, port: nil, ssl: nil, response_handlers: nil,
10681082
# Config options
10691083
@host = host
10701084
@config = Config.new(config, **config_options)
1071-
@port = port || (ssl ? SSL_PORT : PORT)
1085+
ssl, @port = default_ssl_and_port(ssl, port)
10721086
@ssl_ctx_params, @ssl_ctx = build_ssl_ctx(ssl)
10731087

10741088
# Basic Client State
@@ -3318,6 +3332,27 @@ def remove_response_handler(handler)
33183332
PORT = 143 # :nodoc:
33193333
SSL_PORT = 993 # :nodoc:
33203334

3335+
def default_ssl_and_port(tls, port)
3336+
if tls.nil? && port
3337+
tls = true if port == SSL_PORT || /\Aimaps\z/i === port
3338+
tls = false if port == PORT
3339+
elsif port.nil? && !tls.nil?
3340+
port = tls ? SSL_PORT : PORT
3341+
end
3342+
if tls.nil? && port.nil?
3343+
tls = config.default_tls.dup.freeze
3344+
port = tls ? SSL_PORT : PORT
3345+
if tls.nil?
3346+
warn "A future version of Net::IMAP::Config#default_tls " \
3347+
"will default to 'true', for secure connections by default. " \
3348+
"Use 'Net::IMAP.new(host, ssl: false)' or " \
3349+
"Net::IMAP.config.default_tls = false' to silence this warning."
3350+
end
3351+
end
3352+
tls &&= tls.respond_to?(:to_hash) ? tls.to_hash : {}
3353+
[tls, port]
3354+
end
3355+
33213356
def start_imap_connection
33223357
@greeting = get_server_greeting
33233358
@capabilities = capabilities_from_resp_code @greeting

lib/net/imap/config.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,35 @@ def self.[](config)
228228
# The default value is +5+ seconds.
229229
attr_accessor :idle_response_timeout, type: Integer
230230

231+
# The default value for the +ssl+ option of Net::IMAP.new, when +port+ is
232+
# unspecified or non-standard and +ssl+ is unspecified. default_ssl is
233+
# ignored when Net::IMAP.new is called with any value for +ssl+ besides
234+
# +nil+,
235+
#
236+
# *Note*: A future release of Net::IMAP will set the default to +true+, as
237+
# per RFC7525[https://tools.ietf.org/html/rfc7525],
238+
# RFC7817[https://tools.ietf.org/html/rfc7817], and
239+
# RFC8314[https://tools.ietf.org/html/rfc8314].
240+
#
241+
# <em>(The default_ssl config attribute was added in +v0.5.?+.)</em>
242+
#
243+
# ==== Valid options
244+
#
245+
# [+false+ <em>(original behavior)</em>]
246+
# Plaintext by default, with no warnings.
247+
# [+nil+ <em>(planned default for +v0.6+)</em>]
248+
# Plaintext by default, and prints a warning.
249+
#
250+
# <em>This option will be removed in +v0.7+, when +:warn+ becomes the
251+
# default.</em>
252+
# [+:warn+ <em>(planned default for +v0.7+)</em>]
253+
# A warning will be printed, and behave as if the default were +true+.
254+
# [+true+ <em>(planned future default)</em>]
255+
# Use TLS by default, with the default SSL context params set by calling
256+
# {OpenSSL::SSL::SSLContext#set_params}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-set_params]
257+
# with no params.
258+
attr_accessor :default_ssl, type: Enum[false, nil, :warn, true]
259+
231260
# Whether to use the +SASL-IR+ extension when the server and \SASL
232261
# mechanism both support it. Can be overridden by the +sasl_ir+ keyword
233262
# parameter to Net::IMAP#authenticate.
@@ -478,6 +507,7 @@ def defaults_hash
478507
debug: false,
479508
open_timeout: 30,
480509
idle_response_timeout: 5,
510+
default_ssl: false,
481511
sasl_ir: true,
482512
enforce_logindisabled: true,
483513
max_response_size: 512 << 20, # 512 MiB
@@ -518,11 +548,13 @@ def defaults_hash
518548

519549
version_defaults[0.6r] = Config[0.5r].dup.update(
520550
responses_without_block: :frozen_dup,
551+
default_ssl: nil,
521552
parser_use_deprecated_uidplus_data: false,
522553
parser_max_deprecated_uidplus_data_size: 0,
523554
).freeze
524555

525556
version_defaults[0.7r] = Config[0.6r].dup.update(
557+
default_ssl: :warn,
526558
).freeze
527559

528560
# Safe conversions one way only:

0 commit comments

Comments
 (0)