Skip to content

Commit

Permalink
Update AUTH=PLAIN to be a little closer to RFC4616
Browse files Browse the repository at this point in the history
* Add authzid support
* must not contain NULL chars
* improve rdoc
  • Loading branch information
nevans committed Apr 28, 2021
1 parent 23f241b commit a587fc7
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 3 deletions.
21 changes: 18 additions & 3 deletions lib/net/imap/authenticators/plain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,30 @@
#
# See RFC4616[https://tools.ietf.org/html/rfc4616] for the specification.
class Net::IMAP::PlainAuthenticator

def process(data)
return "\0#{@user}\0#{@password}"
return "#@authzid\0#@username\0#@password"
end

NULL = -"\0".b

private

def initialize(user, password)
@user = user
# +username+ is the authentication identity, the identity whose +password+ is
# used. +username+ is referred to as +authcid+ by
# RFC4616[https://tools.ietf.org/html/rfc4616].
#
# +authzid+ is the authorization identity (identity to act as). It can
# usually be left blank. When +authzid+ is left blank (nil or empty string)
# the server will derive an identity from the credentials and use that as the
# authorization identity.
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)
@username = username
@password = password
@authzid = authzid
end

Net::IMAP.add_authenticator "PLAIN", self
Expand Down
23 changes: 23 additions & 0 deletions test/net/imap/test_imap_authenticators.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

require "net/imap"
require "test/unit"

class IMAPAuthenticatorsTest < Test::Unit::TestCase

PLAIN = Net::IMAP::PlainAuthenticator

def test_plain
assert_equal("\0authc\0passwd",
PLAIN.new("authc", "passwd").process(nil))
assert_equal("authz\0user\0pass",
PLAIN.new("user", "pass", authzid: "authz").process(nil))
end

def test_plain_no_null_chars
assert_raise(ArgumentError) { PLAIN.new("bad\0user", "pass") }
assert_raise(ArgumentError) { PLAIN.new("user", "bad\0pass") }
assert_raise(ArgumentError) { PLAIN.new("u", "p", authzid: "bad\0authz") }
end

end

0 comments on commit a587fc7

Please sign in to comment.