From 092299fc4f3c67bea9374ed877d4cd83f8a4f8c4 Mon Sep 17 00:00:00 2001 From: nick evans Date: Fri, 4 Nov 2022 22:09:46 -0400 Subject: [PATCH 1/4] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Support=20keyword=20ar?= =?UTF-8?q?gs=20for=20SASL=20DIGEST-MD5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/net/imap/sasl/digest_md5_authenticator.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/net/imap/sasl/digest_md5_authenticator.rb b/lib/net/imap/sasl/digest_md5_authenticator.rb index 8833a43a..d1576ba5 100644 --- a/lib/net/imap/sasl/digest_md5_authenticator.rb +++ b/lib/net/imap/sasl/digest_md5_authenticator.rb @@ -41,7 +41,8 @@ class Net::IMAP::SASL::DigestMD5Authenticator attr_reader :authzid # :call-seq: - # new(username, password, authzid = nil) -> authenticator + # new(username, password, authzid = nil, **options) -> authenticator + # new(username:, password:, authzid: nil, **options) -> authenticator # # Creates an Authenticator for the "+DIGEST-MD5+" SASL mechanism. # @@ -55,7 +56,12 @@ class Net::IMAP::SASL::DigestMD5Authenticator # * +warn_deprecation+ — Set to +false+ to silence the warning. # # See the documentation for each attribute for more details. - def initialize(username, password, authzid = nil, warn_deprecation: true) + def initialize(user = nil, pass = nil, authz = nil, + username: nil, password: nil, authzid: nil, + warn_deprecation: true, **) + username ||= user or raise ArgumentError, "missing username" + password ||= pass or raise ArgumentError, "missing password" + authzid ||= authz if warn_deprecation warn "WARNING: DIGEST-MD5 SASL mechanism was deprecated by RFC6331." # TODO: recommend SCRAM instead. From 8660f242ebcb13eb94540097d28ba8098dee92e0 Mon Sep 17 00:00:00 2001 From: nick evans Date: Mon, 7 Nov 2022 22:27:42 -0500 Subject: [PATCH 2/4] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Support=20keyword=20ar?= =?UTF-8?q?gs=20for=20SASL=20PLAIN?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/net/imap/sasl/plain_authenticator.rb | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/net/imap/sasl/plain_authenticator.rb b/lib/net/imap/sasl/plain_authenticator.rb index 7b2de294..8b04ab7f 100644 --- a/lib/net/imap/sasl/plain_authenticator.rb +++ b/lib/net/imap/sasl/plain_authenticator.rb @@ -37,7 +37,8 @@ class Net::IMAP::SASL::PlainAuthenticator attr_reader :authzid # :call-seq: - # new(username, password, authzid: nil) -> authenticator + # new(username, password, authzid: nil, **) -> authenticator + # new(username:, password:, authzid: nil, **) -> authenticator # # Creates an Authenticator for the "+PLAIN+" SASL mechanism. # @@ -50,10 +51,13 @@ class Net::IMAP::SASL::PlainAuthenticator # * #authzid ― Alternate identity to act as or on behalf of. Optional. # # See attribute documentation for more details. - def initialize(username, password, authzid: nil) - raise ArgumentError, "username contains NULL" if username&.include?(NULL) - raise ArgumentError, "password contains NULL" if password&.include?(NULL) - raise ArgumentError, "authzid contains NULL" if authzid&.include?(NULL) + def initialize(user = nil, pass = nil, + username: nil, password: nil, authzid: nil, **) + username ||= user or raise ArgumentError, "missing username" + password ||= pass or raise ArgumentError, "missing password" + raise ArgumentError, "username contains NULL" if username.include?(NULL) + raise ArgumentError, "password contains NULL" if password.include?(NULL) + raise ArgumentError, "authzid contains NULL" if authzid&.include?(NULL) @username = username @password = password @authzid = authzid From 0b3865526c44f8675440606c3d559797597b4b22 Mon Sep 17 00:00:00 2001 From: nick evans Date: Wed, 20 Sep 2023 15:49:25 -0400 Subject: [PATCH 3/4] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Support=20keyword=20ar?= =?UTF-8?q?gs=20for=20SASL=20XOAUTH2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/net/imap/sasl/xoauth2_authenticator.rb | 16 +++++++++++----- test/net/imap/test_imap_authenticators.rb | 11 +++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/lib/net/imap/sasl/xoauth2_authenticator.rb b/lib/net/imap/sasl/xoauth2_authenticator.rb index 00dc397e..98debbc0 100644 --- a/lib/net/imap/sasl/xoauth2_authenticator.rb +++ b/lib/net/imap/sasl/xoauth2_authenticator.rb @@ -32,8 +32,8 @@ class Net::IMAP::SASL::XOAuth2Authenticator attr_reader :oauth2_token # :call-seq: - # :call-seq: - # new(username, oauth2_token) -> authenticator + # new(username, oauth2_token, **) -> authenticator + # new(username:, oauth2_token:, **) -> authenticator # # Creates an Authenticator for the "+XOAUTH2+" SASL mechanism, as specified by # Google[https://developers.google.com/gmail/imap/xoauth2-protocol], @@ -47,9 +47,15 @@ class Net::IMAP::SASL::XOAuth2Authenticator # the service for #username. # # See the documentation for each attribute for more details. - def initialize(username, oauth2_token) - @username = username - @oauth2_token = oauth2_token + def initialize(user = nil, token = nil, username: nil, oauth2_token: nil, **) + @username = username || user or + raise ArgumentError, "missing username" + @oauth2_token = oauth2_token || token or + raise ArgumentError, "missing oauth2_token" + [username, user].compact.count == 1 or + raise ArgumentError, "conflicting values for username" + [oauth2_token, token].compact.count == 1 or + raise ArgumentError, "conflicting values for oauth2_token" end # :call-seq: diff --git a/test/net/imap/test_imap_authenticators.rb b/test/net/imap/test_imap_authenticators.rb index 8e63c883..5c3600d0 100644 --- a/test/net/imap/test_imap_authenticators.rb +++ b/test/net/imap/test_imap_authenticators.rb @@ -95,6 +95,17 @@ def test_xoauth2_response ) end + def test_xoauth2_kwargs + assert_equal( + "user=arg\1auth=Bearer kwarg\1\1", + xoauth2("arg", oauth2_token: "kwarg").process(nil) + ) + assert_equal( + "user=user\1auth=Bearer kwarg\1\1", + xoauth2(username: "user", oauth2_token: "kwarg").process(nil) + ) + end + def test_xoauth2_supports_initial_response assert xoauth2("foo", "bar").initial_response? assert Net::IMAP::SASL.initial_response?(xoauth2("foo", "bar")) From 87c1fe9f2997bc06b1c7afe761ae907df162a606 Mon Sep 17 00:00:00 2001 From: nick evans Date: Wed, 20 Sep 2023 15:51:22 -0400 Subject: [PATCH 4/4] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Ignore=20unknown=20key?= =?UTF-8?q?word=20args=20for=20SASL=20EXTERNAL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/net/imap/sasl/external_authenticator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/net/imap/sasl/external_authenticator.rb b/lib/net/imap/sasl/external_authenticator.rb index 12a0113a..921b2ce6 100644 --- a/lib/net/imap/sasl/external_authenticator.rb +++ b/lib/net/imap/sasl/external_authenticator.rb @@ -29,7 +29,7 @@ class ExternalAuthenticator # #authzid is an optional identity to act as or on behalf of. # # Any other keyword parameters are quietly ignored. - def initialize(authzid: nil) + def initialize(authzid: nil, **) @authzid = authzid&.to_str&.encode "UTF-8" if @authzid&.match?(/\u0000/u) # also validates UTF8 encoding raise ArgumentError, "contains NULL"