diff --git a/lib/net/imap.rb b/lib/net/imap.rb index 1368ba30..4832e7d8 100644 --- a/lib/net/imap.rb +++ b/lib/net/imap.rb @@ -1236,7 +1236,8 @@ def authenticate(mechanism, *creds, sasl_ir: true, **props, &callback) cmdargs = ["AUTHENTICATE", mechanism] if sasl_ir && capable?("SASL-IR") && auth_capable?(mechanism) && SASL.initial_response?(authenticator) - cmdargs << [authenticator.process(nil)].pack("m0") + response = authenticator.process(nil) + cmdargs << (response.empty? ? "=" : [response].pack("m0")) end result = send_command(*cmdargs) do |resp| if resp.instance_of?(ContinuationRequest) diff --git a/test/net/imap/test_imap.rb b/test/net/imap/test_imap.rb index d67889f7..81ebc269 100644 --- a/test/net/imap/test_imap.rb +++ b/test/net/imap/test_imap.rb @@ -847,6 +847,24 @@ def test_id end end + test("#authenticate sends '=' as the initial reponse " \ + "when the initial response is an empty string") do + with_fake_server( + preauth: false, cleartext_auth: true, + sasl_ir: true, sasl_mechanisms: %i[EXTERNAL], + ) do |server, imap| + server.on "AUTHENTICATE" do |cmd| + server.state.authenticate(server.config.user) + cmd.done_ok + end + imap.authenticate("EXTERNAL") + cmd = server.commands.pop + assert_equal "AUTHENTICATE", cmd.name + assert_equal %w[EXTERNAL =], cmd.args + assert_empty server.commands rescue pp server.commands.pop + end + end + test("#authenticate never sends an initial response " \ "when the server doesn't explicitly support the mechanism") do with_fake_server(