Skip to content

Commit 4c359c1

Browse files
committed
📚 Update SASL DIGEST-MD5 docs, add attr_readers
Also renamed ivars to match the names used by other authenticators. However... `DIGEST-MD5` is still deprecated, so don't use it! 😉
1 parent 49e5b0a commit 4c359c1

File tree

1 file changed

+49
-6
lines changed

1 file changed

+49
-6
lines changed

lib/net/imap/sasl/digest_md5_authenticator.rb

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,72 @@
11
# frozen_string_literal: true
22

33
# Net::IMAP authenticator for the "`DIGEST-MD5`" SASL mechanism type, specified
4-
# in RFC2831(https://tools.ietf.org/html/rfc2831). See Net::IMAP#authenticate.
4+
# in RFC-2831[https://tools.ietf.org/html/rfc2831]. See Net::IMAP#authenticate.
55
#
66
# == Deprecated
77
#
88
# "+DIGEST-MD5+" has been deprecated by
9-
# {RFC6331}[https://tools.ietf.org/html/rfc6331] and should not be relied on for
9+
# RFC-6331[https://tools.ietf.org/html/rfc6331] and should not be relied on for
1010
# security. It is included for compatibility with existing servers.
1111
class Net::IMAP::SASL::DigestMD5Authenticator
1212
STAGE_ONE = :stage_one
1313
STAGE_TWO = :stage_two
1414
private_constant :STAGE_ONE, :STAGE_TWO
1515

16-
def initialize(user, password, authname = nil, warn_deprecation: true)
16+
# Authentication identity: the identity that matches the #password.
17+
#
18+
# RFC-2831[https://tools.ietf.org/html/rfc2831] uses the term +username+.
19+
# "Authentication identity" is the generic term used by
20+
# RFC-4422[https://tools.ietf.org/html/rfc4422].
21+
# RFC-4616[https://tools.ietf.org/html/rfc4616] and many later RFCs abbreviate
22+
# that to +authcid+. So +authcid+ is available as an alias for #username.
23+
attr_reader :username
24+
25+
# A password or passphrase that matches the #username.
26+
#
27+
# The +password+ will be used to create the response digest.
28+
attr_reader :password
29+
30+
# Authorization identity: an identity to act as or on behalf of. The identity
31+
# form is application protocol specific. If not provided or left blank, the
32+
# server derives an authorization identity from the authentication identity.
33+
# The server is responsible for verifying the client's credentials and
34+
# verifying that the identity it associates with the client's authentication
35+
# identity is allowed to act as (or on behalf of) the authorization identity.
36+
#
37+
# For example, an administrator or superuser might take on another role:
38+
#
39+
# imap.authenticate "DIGEST-MD5", "root", ->{passwd}, authzid: "user"
40+
#
41+
attr_reader :authzid
42+
43+
# :call-seq:
44+
# new(username, password, authzid = nil) -> authenticator
45+
#
46+
# Creates an Authenticator for the "+DIGEST-MD5+" SASL mechanism.
47+
#
48+
# Called by Net::IMAP#authenticate and similar methods on other clients.
49+
#
50+
# ==== Parameters
51+
#
52+
# * #username — Identity whose #password is used.
53+
# * #password — A password or passphrase associated with this #username.
54+
# * #authzid ― Alternate identity to act as or on behalf of. Optional.
55+
# * +warn_deprecation+ — Set to +false+ to silence the warning.
56+
#
57+
# See the documentation for each attribute for more details.
58+
def initialize(username, password, authzid = nil, warn_deprecation: true)
1759
if warn_deprecation
1860
warn "WARNING: DIGEST-MD5 SASL mechanism was deprecated by RFC6331."
1961
# TODO: recommend SCRAM instead.
2062
end
2163
require "digest/md5"
2264
require "strscan"
23-
@user, @password, @authname = user, password, authname
65+
@username, @password, @authzid = username, password, authzid
2466
@nc, @stage = {}, STAGE_ONE
2567
end
2668

69+
# Responds to server challenge in two stages.
2770
def process(challenge)
2871
case @stage
2972
when STAGE_ONE
@@ -46,7 +89,7 @@ def process(challenge)
4689

4790
response = {
4891
:nonce => sparams['nonce'],
49-
:username => @user,
92+
:username => @username,
5093
:realm => sparams['realm'],
5194
:cnonce => Digest::MD5.hexdigest("%.15f:%.15f:%d" % [Time.now.to_f, rand, Process.pid.to_s]),
5295
:'digest-uri' => 'imap/' + sparams['realm'],
@@ -56,7 +99,7 @@ def process(challenge)
5699
:charset => sparams['charset'],
57100
}
58101

59-
response[:authzid] = @authname unless @authname.nil?
102+
response[:authzid] = @authzid unless @authzid.nil?
60103

61104
# now, the real thing
62105
a0 = Digest::MD5.digest( [ response.values_at(:username, :realm), @password ].join(':') )

0 commit comments

Comments
 (0)