Class: Net::IMAP::SASL::DigestMD5Authenticator
- Inherits:
-
Object
- Object
- Net::IMAP::SASL::DigestMD5Authenticator
- Defined in:
- lib/net/imap/sasl/digest_md5_authenticator.rb
Overview
Instance Attribute Summary collapse
-
#authzid ⇒ Object
readonly
Authorization identity: an identity to act as or on behalf of.
-
#charset ⇒ Object
readonly
The charset sent by the server.
-
#host ⇒ Object
readonly
Fully qualified canonical DNS host name for the requested service.
-
#nonce ⇒ Object
readonly
nonce sent by the server.
-
#password ⇒ Object
readonly
A password or passphrase that matches the #username.
-
#qop ⇒ Object
readonly
qop-options sent by the server.
-
#realm ⇒ Object
readonly
A namespace or collection of identities which contains
username
. -
#service ⇒ Object
readonly
The service protocol, a registered GSSAPI service name, e.g.
-
#service_name ⇒ Object
readonly
The generic server name when the server is replicated.
-
#sparams ⇒ Object
readonly
Parameters sent by the server are stored in this hash.
-
#username ⇒ Object
(also: #authcid)
readonly
Authentication identity: the identity that matches the #password.
Instance Method Summary collapse
-
#digest_uri ⇒ Object
From RFC-2831: >>> Indicates the principal name of the service with which the client wishes to connect, formed from the serv-type, host, and serv-name.
- #done? ⇒ Boolean
- #initial_response? ⇒ Boolean
-
#initialize(user = nil, pass = nil, authz = nil, username: nil, password: nil, authzid: nil, authcid: nil, secret: nil, realm: nil, service: "imap", host: nil, service_name: nil, warn_deprecation: true) ⇒ DigestMD5Authenticator
constructor
:call-seq: new(username, password, authzid = nil, **options) -> authenticator new(username:, password:, authzid: nil, **options) -> authenticator new(authcid:, password:, authzid: nil, **options) -> authenticator.
-
#process(challenge) ⇒ Object
Responds to server challenge in two stages.
Constructor Details
#initialize(user = nil, pass = nil, authz = nil, username: nil, password: nil, authzid: nil, authcid: nil, secret: nil, realm: nil, service: "imap", host: nil, service_name: nil, warn_deprecation: true) ⇒ DigestMD5Authenticator
:call-seq:
new(username, password, authzid = nil, **options) -> authenticator
new(username:, password:, authzid: nil, **options) -> authenticator
new(authcid:, password:, authzid: nil, **options) -> authenticator
Creates an Authenticator for the “DIGEST-MD5
” SASL mechanism.
Called by Net::IMAP#authenticate and similar methods on other clients.
Parameters
-
#authcid ― Authentication identity that is associated with #password.
#username ― An alias for
authcid
. -
#password ― A password or passphrase associated with this #authcid.
-
optional #authzid ― Authorization identity to act as or on behalf of.
When
authzid
is not set, the server should derive the authorization identity from the authentication identity. -
optional #realm — A namespace for the #username, e.g. a domain. Defaults to the last realm in the server-provided realms list.
-
optional #host — FQDN for requested service. Defaults to #realm.
-
optional #service_name — The generic host name when the server is replicated.
-
optional #service — the registered service protocol. E.g. “imap”, “smtp”, “ldap”, “xmpp”. For Net::IMAP, this defaults to “imap”.
-
optional
warn_deprecation
— Set tofalse
to silence the warning.
Any other keyword arguments are silently ignored.
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/net/imap/sasl/digest_md5_authenticator.rb', line 154 def initialize(user = nil, pass = nil, authz = nil, username: nil, password: nil, authzid: nil, authcid: nil, secret: nil, realm: nil, service: "imap", host: nil, service_name: nil, warn_deprecation: true, **) username = authcid || username || user or raise ArgumentError, "missing username (authcid)" password ||= secret || pass or raise ArgumentError, "missing password" authzid ||= authz if warn_deprecation warn("WARNING: DIGEST-MD5 SASL mechanism was deprecated by RFC6331.", category: :deprecated) end require "digest/md5" require "securerandom" require "strscan" @username, @password, @authzid = username, password, authzid @realm = realm @host = host @service = service @service_name = service_name @nc, @stage = {}, STAGE_ONE end |
Instance Attribute Details
#authzid ⇒ Object (readonly)
Authorization identity: an identity to act as or on behalf of. The identity form is application protocol specific. If not provided or left blank, the server derives an authorization identity from the authentication identity. The server is responsible for verifying the client’s credentials and verifying that the identity it associates with the client’s authentication identity is allowed to act as (or on behalf of) the authorization identity.
For example, an administrator or superuser might take on another role:
imap.authenticate "DIGEST-MD5", "root", ->{passwd}, authzid: "user"
64 65 66 |
# File 'lib/net/imap/sasl/digest_md5_authenticator.rb', line 64 def authzid @authzid end |
#charset ⇒ Object (readonly)
The charset sent by the server. “UTF-8” (case insensitive) is the only allowed value. nil
should be interpreted as ISO 8859-1.
111 112 113 |
# File 'lib/net/imap/sasl/digest_md5_authenticator.rb', line 111 def charset @charset end |
#host ⇒ Object (readonly)
Fully qualified canonical DNS host name for the requested service.
Defaults to #realm.
78 79 80 |
# File 'lib/net/imap/sasl/digest_md5_authenticator.rb', line 78 def host @host end |
#nonce ⇒ Object (readonly)
nonce sent by the server
114 115 116 |
# File 'lib/net/imap/sasl/digest_md5_authenticator.rb', line 114 def nonce @nonce end |
#password ⇒ Object (readonly)
A password or passphrase that matches the #username.
The password
will be used to create the response digest.
51 52 53 |
# File 'lib/net/imap/sasl/digest_md5_authenticator.rb', line 51 def password @password end |
#qop ⇒ Object (readonly)
qop-options sent by the server
117 118 119 |
# File 'lib/net/imap/sasl/digest_md5_authenticator.rb', line 117 def qop @qop end |
#realm ⇒ Object (readonly)
A namespace or collection of identities which contains username
.
Used by DIGEST-MD5, GSS-API, and NTLM. This is often a domain name that contains the name of the host performing the authentication.
Defaults to the last realm in the server-provided list of realms.
73 74 75 |
# File 'lib/net/imap/sasl/digest_md5_authenticator.rb', line 73 def realm @realm end |
#service ⇒ Object (readonly)
The service protocol, a registered GSSAPI service name, e.g. “imap”, “ldap”, or “xmpp”.
For Net::IMAP, the default is “imap” and should not be overridden. This must be set appropriately to use authenticators in other protocols.
If an IANA-registered name isn’t available, GSS-API (RFC-2743) allows the generic name “host”.
90 91 92 |
# File 'lib/net/imap/sasl/digest_md5_authenticator.rb', line 90 def service @service end |
#service_name ⇒ Object (readonly)
The generic server name when the server is replicated.
service_name
will be ignored when it is nil
or identical to host
.
From RFC-2831:
The service is considered to be replicated if the client’s service-location process involves resolution using standard DNS lookup operations, and if these operations involve DNS records (such as SRV, or MX) which resolve one DNS name into a set of other DNS names. In this case, the initial name used by the client is the “serv-name”, and the final name is the “host” component.
104 105 106 |
# File 'lib/net/imap/sasl/digest_md5_authenticator.rb', line 104 def service_name @service_name end |
#sparams ⇒ Object (readonly)
Parameters sent by the server are stored in this hash.
107 108 109 |
# File 'lib/net/imap/sasl/digest_md5_authenticator.rb', line 107 def sparams @sparams end |
#username ⇒ Object (readonly) Also known as: authcid
45 46 47 |
# File 'lib/net/imap/sasl/digest_md5_authenticator.rb', line 45 def username @username end |
Instance Method Details
#digest_uri ⇒ Object
From RFC-2831:
Indicates the principal name of the service with which the client wishes to connect, formed from the serv-type, host, and serv-name. For example, the FTP service on “ftp.example.com” would have a “digest-uri” value of “ftp/ftp.example.com”; the SMTP server from the example above would have a “digest-uri” value of “smtp/mail3.example.com/example.com”.
186 187 188 189 190 191 192 |
# File 'lib/net/imap/sasl/digest_md5_authenticator.rb', line 186 def digest_uri if service_name && service_name != host "#{service}/#{host}/#{service_name}" else "#{service}/#{host}" end end |
#done? ⇒ Boolean
246 |
# File 'lib/net/imap/sasl/digest_md5_authenticator.rb', line 246 def done?; @stage == STAGE_DONE end |
#initial_response? ⇒ Boolean
194 |
# File 'lib/net/imap/sasl/digest_md5_authenticator.rb', line 194 def initial_response?; false end |
#process(challenge) ⇒ Object
Responds to server challenge in two stages.
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/net/imap/sasl/digest_md5_authenticator.rb', line 197 def process(challenge) case @stage when STAGE_ONE @stage = STAGE_TWO @sparams = parse_challenge(challenge) @qop = sparams.key?("qop") ? ["auth"] : sparams["qop"].flatten @nonce = sparams["nonce"] &.first @charset = sparams["charset"]&.first @realm ||= sparams["realm"] &.last @host ||= realm if !qop.include?("auth") raise DataFormatError, "Server does not support auth (qop = %p)" % [ sparams["qop"] ] elsif (emptykey = REQUIRED.find { sparams[_1].empty? }) raise DataFormatError, "Server didn't send %s (%p)" % [emptykey, challenge] elsif (multikey = NO_MULTIPLES.find { sparams[_1].length > 1 }) raise DataFormatError, "Server sent multiple %s (%p)" % [multikey, challenge] end response = { nonce: nonce, username: username, realm: realm, cnonce: SecureRandom.base64(32), "digest-uri": digest_uri, qop: "auth", maxbuf: 65535, nc: "%08d" % nc(nonce), charset: charset, } response[:authzid] = @authzid unless @authzid.nil? response[:response] = response_value(response) format_response(response) when STAGE_TWO @stage = STAGE_DONE raise ResponseParseError, challenge unless challenge =~ /rspauth=/ "" # if at the second stage, return an empty string else raise ResponseParseError, challenge end rescue => error @stage = error raise end |