From 510231342b05afc9e8126fcab808d40773e937de Mon Sep 17 00:00:00 2001 From: nick evans Date: Sat, 23 Sep 2023 20:13:00 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20empty=20SASL-IR=20to=20sen?= =?UTF-8?q?d=20"=3D"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per RFC-4959 and RFC-9051: > To send a zero-length initial response, the client MUST send a single > pad character ("="). This indicates that the response is present, but > is a zero- length string. --- lib/net/imap.rb | 3 ++- test/net/imap/test_imap.rb | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/net/imap.rb b/lib/net/imap.rb index 1368ba303..4832e7d88 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 d67889f74..81ebc2694 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(