diff --git a/lib/net/imap.rb b/lib/net/imap.rb index e1ce6300..fb03c091 100644 --- a/lib/net/imap.rb +++ b/lib/net/imap.rb @@ -802,8 +802,21 @@ def idle_response_timeout; config.idle_response_timeout end # Returns +false+ for a plaintext connection. attr_reader :ssl_ctx_params - # Creates a new Net::IMAP object and connects it to the specified - # +host+. + # Creates a new Net::IMAP object and connects it to the specified +host+. + # + # ==== Default port and SSL + # + # When both both +port+ and +ssl+ are unspecified or +nil+, + # +ssl+ is determined by {config.default_ssl}[rdoc-ref:Config#default_ssl] + # and +port+ is based on that implicit value for +ssl+. + # + # When only one of the two is specified: + # * When +ssl+ is truthy, +port+ defaults to +993+. + # * When +ssl+ is +false+, +port+ defaults to +143+. + # * When +port+ is +993+, +ssl+ defaults to +true+. + # * When +port+ is +143+, +ssl+ defaults to +false+. + # * When +port+ is nonstandard, the default for +ssl+ is determined + # by {config.default_ssl}[rdoc-ref:Config#default_ssl]. # # ==== Options # @@ -831,7 +844,9 @@ def idle_response_timeout; config.idle_response_timeout end # SSL session verification mode. Valid modes include # +OpenSSL::SSL::VERIFY_PEER+ and +OpenSSL::SSL::VERIFY_NONE+. # - # See {OpenSSL::SSL::SSLContext}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html] for other valid SSL context params. + # See + # {OpenSSL::SSL::SSLContext}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html] + # for other valid SSL context params. # # See DeprecatedClientOptions.new for deprecated SSL arguments. # @@ -912,7 +927,7 @@ def initialize(host, port: nil, ssl: nil, # Config options @host = host @config = Config.new(config, **config_options) - @port = port || (ssl ? SSL_PORT : PORT) + ssl, @port = default_ssl_and_port(ssl, port) @ssl_ctx_params, @ssl_ctx = build_ssl_ctx(ssl) # Basic Client State @@ -2654,6 +2669,27 @@ def remove_response_handler(handler) PORT = 143 # :nodoc: SSL_PORT = 993 # :nodoc: + def default_ssl_and_port(tls, port) + if tls.nil? && port + tls = true if port == SSL_PORT || /\Aimaps\z/i === port + tls = false if port == PORT + elsif port.nil? && !tls.nil? + port = tls ? SSL_PORT : PORT + end + if tls.nil? && port.nil? + tls = config.default_tls.dup.freeze + port = tls ? SSL_PORT : PORT + if tls.nil? + warn "A future version of Net::IMAP::Config#default_tls " \ + "will default to 'true', for secure connections by default. " \ + "Use 'Net::IMAP.new(host, ssl: false)' or " \ + "Net::IMAP.config.default_tls = false' to silence this warning." + end + end + tls &&= tls.respond_to?(:to_hash) ? tls.to_hash : {} + [tls, port] + end + def start_imap_connection @greeting = get_server_greeting @capabilities = capabilities_from_resp_code @greeting diff --git a/lib/net/imap/config.rb b/lib/net/imap/config.rb index bcf5b72d..2100ebd5 100644 --- a/lib/net/imap/config.rb +++ b/lib/net/imap/config.rb @@ -200,6 +200,29 @@ def self.[](config) # The default value is +5+ seconds. attr_accessor :idle_response_timeout, type: Integer + # :markup: markdown + # + # The default value for the +ssl+ option of Net::IMAP.new, when +port+ is + # unspecified or non-standard. + # + # *Note*: A future release of Net::IMAP will set the default to +true+, as + # per RFC7525[https://tools.ietf.org/html/rfc7525], + # RFC7817[https://tools.ietf.org/html/rfc7817], and + # RFC8314[https://tools.ietf.org/html/rfc8314]. + # + # * Set to +true+ for the secure default without warnings. + # * Set to +:warn+ for the secure default _with_ warnings. + # * Set to +nil+ to use insecure defaults with warnings. + # * Set to +false+ to silence warnings and use insecure defaults. + # + # | Starting with version | The default value is | + # |-------------------------|------------------------| + # | _original_ | +false+ | + # | v0.6 (planned) | +nil+ | + # | v0.7 (planned) | +:warn+ | + # | _eventually_ | +true+ | + attr_accessor :default_ssl + # :markup: markdown # # Whether to use the +SASL-IR+ extension when the server and \SASL @@ -331,6 +354,7 @@ def defaults_hash debug: false, open_timeout: 30, idle_response_timeout: 5, + default_ssl: nil, sasl_ir: true, enforce_logindisabled: true, responses_without_block: :warn,