Fixed issue#240 - TLS/SSL for SMTP with exchange. Improved Net::SMTP.do_start to auto detect available auth types based on SMTP server capabilities.

This commit is contained in:
Martin Edenhofer 2016-11-06 16:45:38 +01:00
parent f07013ac3c
commit db2b329331
2 changed files with 59 additions and 1 deletions

View file

@ -10,8 +10,10 @@ class Channel::Driver::Smtp
host: 'some.host',
port: 25,
enable_starttls_auto: true, # optional
openssl_verify_mode: 'none', # optional
user: 'someuser',
password: 'somepass'
authentication: nil, # nil, autodetection - to use certain schema use 'plain', 'login' or 'cram_md5'
},
mail_attributes,
notification
@ -28,6 +30,9 @@ class Channel::Driver::Smtp
if !options.key?(:port)
options[:port] = 25
end
if !options.key?(:domain)
options[:domain] = Setting.get('fqdn')
end
if !options.key?(:enable_starttls_auto)
options[:enable_starttls_auto] = true
end
@ -39,10 +44,11 @@ class Channel::Driver::Smtp
openssl_verify_mode: options[:openssl_verify_mode],
address: options[:host],
port: options[:port],
domain: options[:host],
domain: options[:domain],
user_name: options[:user],
password: options[:password],
enable_starttls_auto: options[:enable_starttls_auto],
authentication: options[:authentication],
}
mail.deliver
end

52
lib/core_ext/net/smtp.rb Normal file
View file

@ -0,0 +1,52 @@
# rubocop:disable all
module Net
class SMTP
def do_start(helo_domain, user, secret, authtype)
raise IOError, 'SMTP session already started' if @started
if user or secret
check_auth_method(authtype || DEFAULT_AUTH_TYPE)
check_auth_args user, secret
end
s = Timeout.timeout(@open_timeout, Net::OpenTimeout) do
tcp_socket(@address, @port)
end
logging "Connection opened: #{@address}:#{@port}"
@socket = new_internet_message_io(tls? ? tlsconnect(s) : s)
check_response critical { recv_response() }
do_helo helo_domain
if starttls_always? or (capable_starttls? and starttls_auto?)
unless capable_starttls?
raise SMTPUnsupportedCommand,
"STARTTLS is not supported on this server"
end
starttls
@socket = new_internet_message_io(tlsconnect(s))
# helo response may be different after STARTTLS
do_helo helo_domain
# ADD auto detection of authtype - https://github.com/zammad/zammad/issues/240
# set detected authtype based on smtp server capabilities
if !authtype
if auth_capable?(DEFAULT_AUTH_TYPE)
authtype = DEFAULT_AUTH_TYPE
elsif capable_plain_auth?
authtype = 'PLAIN'
elsif capable_login_auth?
authtype = 'LOGIN'
elsif capable_cram_md5_auth?
authtype = 'CRAM-MD5'
end
end
# /ADD auto detection of authtype - https://github.com/zammad/zammad/issues/240
end
authenticate user, secret, (authtype || DEFAULT_AUTH_TYPE) if user
@started = true
ensure
unless @started
# authentication failed, cancel connection.
s.close if s and not s.closed?
@socket = nil
end
end
end
end
# rubocop:enable all