Skip to content

Commit 0cf0c21

Browse files
committed
🔒 Add when_capabilities_cached option for sasl_ir
This is the same basic approach used by `enforce_logindisabled`.
1 parent ff86130 commit 0cf0c21

File tree

3 files changed

+66
-1
lines changed

3 files changed

+66
-1
lines changed

lib/net/imap.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1518,6 +1518,7 @@ def starttls(**options)
15181518
# completes. If the TaggedResponse to #authenticate includes updated
15191519
# capabilities, they will be cached.
15201520
def authenticate(*args, sasl_ir: config.sasl_ir, **props, &callback)
1521+
sasl_ir = may_depend_on_capabilities_cached?(sasl_ir)
15211522
sasl_adapter.authenticate(*args, sasl_ir: sasl_ir, **props, &callback)
15221523
.tap do state_authenticated! _1 end
15231524
end

lib/net/imap/config.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,21 @@ def self.[](config)
240240
# Do not use +SASL-IR+, even when it is supported by the server and the
241241
# mechanism.
242242
#
243+
# [+:when_capabilities_cached+]
244+
# Use +SASL-IR+ when Net::IMAP#capabilities_cached? is +true+ and it is
245+
# supported by the server and the mechanism, but do not send a
246+
# +CAPABILITY+ command to discover the server capabilities.
247+
#
248+
# <em>(+:when_capabilities_cached+ option was added by +v0.5.8+)</em>
249+
#
243250
# [+true+ <em>(default since +v0.4+)</em>]
244251
# Use +SASL-IR+ when it is supported by the server and the mechanism.
245-
attr_accessor :sasl_ir, type: :boolean
252+
attr_accessor :sasl_ir, type: Enum[
253+
false, :when_capabilities_cached, true
254+
]
255+
# :stopdoc:
256+
alias sasl_ir? sasl_ir
257+
# :startdoc:
246258

247259
# Controls the behavior of Net::IMAP#login when the +LOGINDISABLED+
248260
# capability is present. When enforced, Net::IMAP will raise a

test/net/imap/test_imap_authenticate.rb

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,58 @@ class IMAPAuthenticateTest < Net::IMAP::TestCase
8484
end
8585
end
8686

87+
test("#authenticate without cached capabilities never sends initial response " \
88+
"when config.sasl_ir: :when_capabilities_cached") do
89+
[true, false].each do |server_support|
90+
with_fake_server(
91+
preauth: false, cleartext_auth: true, sasl_ir: server_support,
92+
greeting_capabilities: false,
93+
) do |server, imap|
94+
imap.config.sasl_ir = :when_capabilities_cached
95+
imap.authenticate("PLAIN", "test_user", "test-password")
96+
cmd, cont = 2.times.map { server.commands.pop }
97+
assert_equal %w[AUTHENTICATE PLAIN], [cmd.name, *cmd.args]
98+
assert_equal(["\x00test_user\x00test-password"].pack("m0"),
99+
cont[:continuation].strip)
100+
assert_empty server.commands
101+
end
102+
end
103+
end
104+
105+
test("#authenticate with cached capabilities sends an initial response " \
106+
"when config.sasl_ir: :when_capabilities_cached " \
107+
"and supported by both the mechanism and the server") do
108+
with_fake_server(
109+
preauth: false, cleartext_auth: true, sasl_ir: true,
110+
greeting_capabilities: true,
111+
) do |server, imap|
112+
imap.config.sasl_ir = :when_capabilities_cached
113+
imap.authenticate("PLAIN", "test_user", "test-password")
114+
cmd = server.commands.pop
115+
assert_equal "AUTHENTICATE", cmd.name
116+
assert_equal(["PLAIN", ["\x00test_user\x00test-password"].pack("m0")],
117+
cmd.args)
118+
assert_empty server.commands
119+
end
120+
end
121+
122+
test("#authenticate with cached capabilities doesn't send initial response " \
123+
"when config.sasl_ir: :when_capabilities_cached " \
124+
"and not supported by the server") do
125+
with_fake_server(
126+
preauth: false, cleartext_auth: true, sasl_ir: false,
127+
greeting_capabilities: true,
128+
) do |server, imap|
129+
imap.config.sasl_ir = :when_capabilities_cached
130+
imap.authenticate("PLAIN", "test_user", "test-password")
131+
cmd, cont = 2.times.map { server.commands.pop }
132+
assert_equal %w[AUTHENTICATE PLAIN], [cmd.name, *cmd.args]
133+
assert_equal(["\x00test_user\x00test-password"].pack("m0"),
134+
cont[:continuation].strip)
135+
assert_empty server.commands
136+
end
137+
end
138+
87139
test("#authenticate never sends an initial response " \
88140
"when config.sasl_ir: false") do
89141
[true, false].each do |server_support|

0 commit comments

Comments
 (0)