Class: Net::IMAP::DigestMD5Authenticator (Ruby 2.2.3)
Description: Class : Net::IMAP::DigestMD5Authenticator - Ruby 2.2.3

- Home
- Core 2.2.3
- Std-lib 2.2.3
- Downloads

Support for the Ruby 2.2 series has ended. See here for reference.

### Home Classes Methods

### In Files

- net/imap.rb

### Parent

Object

### Methods

- ::new
- #process

### Class/Module Index

Quicksearch

- Net
- Net::IMAP
- Net::IMAP::BadResponseError
- Net::IMAP::BodyTypeAttachment
- Net::IMAP::BodyTypeBasic
- Net::IMAP::BodyTypeExtension
- Net::IMAP::BodyTypeMessage
- Net::IMAP::BodyTypeMultipart
- Net::IMAP::BodyTypeText
- Net::IMAP::ByeResponseError
- Net::IMAP::CramMD5Authenticator
- Net::IMAP::DataFormatError
- Net::IMAP::DigestMD5Authenticator
- Net::IMAP::Error
- Net::IMAP::FlagCountError
- Net::IMAP::LoginAuthenticator
- Net::IMAP::NoResponseError
- Net::IMAP::NumValidator
- Net::IMAP::OpenSSL
- Net::IMAP::PlainAuthenticator
- Net::IMAP::ResponseError
- Net::IMAP::ResponseParseError

No matching classes.

# Net::IMAP::DigestMD5Authenticator

Authenticator for the “DIGEST-MD5” authentication type. See authenticate().

### Constants

STAGE_ONE
STAGE_TWO

### Public Class Methods

new(user, password, authname = nil) click to toggle source

                   # File net/imap.rb, line 3542
    def initialize(user, password, authname = nil)
      @user, @password, @authname = user, password, authname
      @nc, @stage = {}, STAGE_ONE
    end

### Public Instance Methods

process(challenge) click to toggle source

                   # File net/imap.rb, line 3477
    def process(challenge)
      case @stage
      when STAGE_ONE
        @stage = STAGE_TWO
        sparams = {}
        c = StringScanner.new(challenge)
        while c.scan(/(?:\s*,)?\s*(\w+)=("(?:[^\\"]+|\\.)*"|[^,]+)\s*/)
          k, v = c[1], c[2]
          if v =~ /^"(.*)"$/
            v = $1
            if v =~ /,/
              v = v.split(',')
            end
          end
          sparams[k] = v
        end

        raise DataFormatError, "Bad Challenge: '#{challenge}'" unless c.rest.size == 0
        raise Error, "Server does not support auth (qop = #{sparams['qop'].join(',')})" unless sparams['qop'].include?("auth")

        response = {
          :nonce => sparams['nonce'],
          :username => @user,
          :realm => sparams['realm'],
          :cnonce => Digest::MD5.hexdigest("%.15f:%.15f:%d" % [Time.now.to_f, rand, Process.pid.to_s]),
          :'digest-uri' => 'imap/' + sparams['realm'],
          :qop => 'auth',
          :maxbuf => 65535,
          :nc => "%08d" % nc(sparams['nonce']),
          :charset => sparams['charset'],
        }

        response[:authzid] = @authname unless @authname.nil?

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

        a1 = [ a0, response.values_at(:nonce,:cnonce) ].join(':')
        a1 << ':' + response[:authzid] unless response[:authzid].nil?

        a2 = "AUTHENTICATE:" + response[:'digest-uri']
        a2 << ":00000000000000000000000000000000" if response[:qop] and response[:qop] =~ /^auth-(?:conf|int)$/

        response[:response] = Digest::MD5.hexdigest(
          [
           Digest::MD5.hexdigest(a1),
           response.values_at(:nonce, :nc, :cnonce, :qop),
           Digest::MD5.hexdigest(a2)
          ].join(':')
        )

        return response.keys.map {|key| qdval(key.to_s, response[key]) }.join(',')
      when STAGE_TWO
        @stage = nil
        # if at the second stage, return an empty string
        if challenge =~ /rspauth=/
          return ''
        else
          raise ResponseParseError, challenge
        end
      else
        raise ResponseParseError, challenge
      end
    end