diff --git a/lib/net/imap.rb b/lib/net/imap.rb index 1539dcbc..c5e053f0 100644 --- a/lib/net/imap.rb +++ b/lib/net/imap.rb @@ -1251,7 +1251,8 @@ def authenticate(mechanism, *creds, sasl_ir: true, **props, &callback) authenticator = SASL.authenticator(mechanism, *creds, **props, &callback) cmdargs = ["AUTHENTICATE", mechanism] if sasl_ir && capable?("SASL-IR") && auth_capable?(mechanism) && - SASL.initial_response?(authenticator) + authenticator.respond_to?(:initial_response?) && + authenticator.initial_response? response = authenticator.process(nil) cmdargs << (response.empty? ? "=" : [response].pack("m0")) end @@ -1263,7 +1264,7 @@ def authenticate(mechanism, *creds, sasl_ir: true, **props, &callback) put_string(response + CRLF) end end - unless SASL.done?(authenticator) + if authenticator.respond_to?(:done?) && !authenticator.done? logout! raise SASL::AuthenticationFailed, "authentication ended prematurely" end diff --git a/lib/net/imap/sasl.rb b/lib/net/imap/sasl.rb index 5f01371b..4af1c4be 100644 --- a/lib/net/imap/sasl.rb +++ b/lib/net/imap/sasl.rb @@ -158,24 +158,6 @@ def saslprep(string, **opts) Net::IMAP::StringPrep::SASLprep.saslprep(string, **opts) end - # Returns whether +authenticator+ is client-first and supports sending an - # "initial response". - def initial_response?(authenticator) - authenticator.respond_to?(:initial_response?) && - authenticator.initial_response? - end - - # Returns whether +authenticator+ considers the authentication exchange to - # be complete. - # - # The authentication should not succeed if this returns false, but - # returning true does *not* indicate success. Authentication succeeds - # when this method returns true and the server responds with a - # protocol-specific success. - def done?(authenticator) - !authenticator.respond_to?(:done?) || authenticator.done? - end - end end end diff --git a/lib/net/imap/sasl/cram_md5_authenticator.rb b/lib/net/imap/sasl/cram_md5_authenticator.rb index 6a6242eb..3aac7b35 100644 --- a/lib/net/imap/sasl/cram_md5_authenticator.rb +++ b/lib/net/imap/sasl/cram_md5_authenticator.rb @@ -24,6 +24,8 @@ def initialize(user, password, warn_deprecation: true, **_ignored) @done = false end + def initial_response?; false end + def process(challenge) digest = hmac_md5(challenge, @password) return @user + " " + digest diff --git a/lib/net/imap/sasl/digest_md5_authenticator.rb b/lib/net/imap/sasl/digest_md5_authenticator.rb index d77afdad..dcc6fc59 100644 --- a/lib/net/imap/sasl/digest_md5_authenticator.rb +++ b/lib/net/imap/sasl/digest_md5_authenticator.rb @@ -73,6 +73,8 @@ def initialize(user = nil, pass = nil, authz = nil, @nc, @stage = {}, STAGE_ONE end + def initial_response?; false end + # Responds to server challenge in two stages. def process(challenge) case @stage diff --git a/lib/net/imap/sasl/login_authenticator.rb b/lib/net/imap/sasl/login_authenticator.rb index f13cac6a..5132a09e 100644 --- a/lib/net/imap/sasl/login_authenticator.rb +++ b/lib/net/imap/sasl/login_authenticator.rb @@ -32,6 +32,8 @@ def initialize(user, password, warn_deprecation: true, **_ignored) @state = STATE_USER end + def initial_response?; false end + def process(data) case @state when STATE_USER diff --git a/test/net/imap/test_imap_authenticators.rb b/test/net/imap/test_imap_authenticators.rb index c0c1e299..38773a29 100644 --- a/test/net/imap/test_imap_authenticators.rb +++ b/test/net/imap/test_imap_authenticators.rb @@ -41,7 +41,6 @@ def test_plain_authenticator_matches_mechanism def test_plain_supports_initial_response assert plain("foo", "bar").initial_response? - assert Net::IMAP::SASL.initial_response?(plain("foo", "bar")) end def test_plain_response @@ -194,7 +193,6 @@ def test_xoauth2_kwargs def test_xoauth2_supports_initial_response assert xoauth2("foo", "bar").initial_response? - assert Net::IMAP::SASL.initial_response?(xoauth2("foo", "bar")) end # ---------------------- @@ -276,7 +274,7 @@ def test_login_authenticator_matches_mechanism end def test_login_does_not_support_initial_response - refute Net::IMAP::SASL.initial_response?(login("foo", "bar")) + refute login("foo", "bar").initial_response? end def test_login_authenticator_deprecated @@ -306,7 +304,7 @@ def test_cram_md5_authenticator_matches_mechanism end def test_cram_md5_does_not_support_initial_response - refute Net::IMAP::SASL.initial_response?(cram_md5("foo", "bar")) + refute cram_md5("foo", "bar").initial_response? end def test_cram_md5_authenticator_deprecated @@ -343,7 +341,7 @@ def test_digest_md5_authenticator_deprecated end def test_digest_md5_does_not_support_initial_response - refute Net::IMAP::SASL.initial_response?(digest_md5("foo", "bar")) + refute digest_md5("foo", "bar").initial_response? end def test_digest_md5_authenticator