Skip to content

Commit

Permalink
🔥 Remove SASL.initial_response?, SASL.done?
Browse files Browse the repository at this point in the history
Since they haven't been in any release yet, `SASL.initial_response?` and
`SASL.done?` have been removed without deprecation.  The logic has been
moved directly into `Net::IMAP#authenticate` (for now).

Implementing `#initial_response?` is still optional.  But, to simplify
the tests, `#initial_response? => false` was added to all of the
deprecated SASL mechanisms.
  • Loading branch information
nevans committed Sep 29, 2023
1 parent 146ad37 commit 9c8fbdb
Show file tree
Hide file tree
Showing 6 changed files with 12 additions and 25 deletions.
5 changes: 3 additions & 2 deletions lib/net/imap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
18 changes: 0 additions & 18 deletions lib/net/imap/sasl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 2 additions & 0 deletions lib/net/imap/sasl/cram_md5_authenticator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions lib/net/imap/sasl/digest_md5_authenticator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions lib/net/imap/sasl/login_authenticator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 3 additions & 5 deletions test/net/imap/test_imap_authenticators.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

# ----------------------
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 9c8fbdb

Please sign in to comment.