Class: Htpasswd::Auths::Digest

Inherits:
Base
  • Object
show all
Defined in:
lib/htpasswd/auths/digest.rb

Constant Summary collapse

PARAMETER_VALID_KEY_MAPPINGS =
{
  :username  => :user,
  :realm     => :realm,
  :qop       => :qop,
  :algorithm => :algorithm,
  :uri       => :uri,
  :nonce     => :nonce,
  :nc        => :nc,
  :cnonce    => :cnonce,
  :response  => :response,
}

Instance Attribute Summary

Attributes inherited from Base

#options

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

<=>, #authorize, #authorize_type, #authorize_user, #initialize, #pass, #random, #realm, #scheme, #user

Constructor Details

This class inherits a constructor from Htpasswd::Auths::Base

Class Method Details

.parse(data, forced_options = {}) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
# File 'lib/htpasswd/auths/digest.rb', line 17

def parse(data, forced_options = {})
  options = HashWithIndifferentAccess.new
  data.to_s.split(/,\s*/).each do |query|
    key, val = query.split('=', 2)
    if valid_key_name = PARAMETER_VALID_KEY_MAPPINGS[key.to_s.intern]
      options[valid_key_name] = val ? val.to_s.delete('"') : nil
#              ActionController::Base.logger.debug("parse: %s => %s" % [valid_key_name,options[valid_key_name]])
    end
  end
  new(options.merge(forced_options))
end

.strengthObject



29
30
31
# File 'lib/htpasswd/auths/digest.rb', line 29

def strength
  100
end

Instance Method Details

#a1Object

A1 = unq(username-value) “:” unq(realm-value) “:” passwd



88
89
90
# File 'lib/htpasswd/auths/digest.rb', line 88

def a1
  digest_algorithm.hexdigest([user, realm, pass] * ":")
end

#a2Object

A2 = Method “:” digest-uri-value



93
94
95
96
# File 'lib/htpasswd/auths/digest.rb', line 93

def a2
#        debug_digest("a2", %w( method uri))
  digest_algorithm.hexdigest([method, uri] * ":")
end

#algorithmObject



50
51
52
# File 'lib/htpasswd/auths/digest.rb', line 50

def algorithm
  options[:algorithm] ||= "MD5"
end

#authorize_pass(pass) ⇒ Object

Authorization



146
147
148
# File 'lib/htpasswd/auths/digest.rb', line 146

def authorize_pass(pass)
  response_digest(pass) == response or raise IncorrectPassword
end

#client_headerObject



118
119
120
121
# File 'lib/htpasswd/auths/digest.rb', line 118

def client_header
  %Q|Digest username="%s", realm="%s", qop=%s, algorithm=%s, uri="%s", nonce="%s", nc=%s, cnonce="%s", response="%s"| %
    [user, realm, qop, algorithm, uri, nonce, nc, cnonce, request_digest]
end

#cnonceObject



66
67
68
# File 'lib/htpasswd/auths/digest.rb', line 66

def cnonce
  options[:cnonce] ||= random(32)
end

#debug_digest(name, element_names, values = {}) ⇒ Object

Debug



125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/htpasswd/auths/digest.rb', line 125

def debug_digest(name, element_names, values = {})
  sources = []
  max = element_names.map(&:size).max
  element_names.each do |method|
    value = values[method.intern] || self.send(method)
    logger.debug("[DIGEST] %s#%-*s : %s" % [name, max, method, value])
    sources << value
  end
  digest = digest_algorithm.hexdigest(sources * ':')
  logger.debug("[DIGEST] %s => : %s" % [name, digest])
  return digest
end

#digest_algorithmObject



78
79
80
81
82
83
84
85
# File 'lib/htpasswd/auths/digest.rb', line 78

def digest_algorithm
  klass_name = algorithm.to_s.upcase
  if klass_name == "SHA1"
    ::Digest::SHA1
  else
    ::Digest::MD5
  end
end

#entryObject

Aliases



140
141
142
# File 'lib/htpasswd/auths/digest.rb', line 140

def entry
  [user, realm, a1] * ':'
end

#methodObject



70
71
72
# File 'lib/htpasswd/auths/digest.rb', line 70

def method
  options[:method] ||= "GET"
end

#ncObject



62
63
64
# File 'lib/htpasswd/auths/digest.rb', line 62

def nc
  options[:nc] ||= '00000001'
end

#nonceObject



39
40
41
42
43
44
45
46
47
48
# File 'lib/htpasswd/auths/digest.rb', line 39

def nonce
  value = options[:nonce]
  unless value
    time  = Time.now.to_i
    etag  = options[:session_key] || random(16)
    pkey  = options[:private_key] || random(16)
    value = Base64.encode64("%s:%s:%s" % [time, etag, pkey]).chomp
  end
  return value
end

#qopObject



54
55
56
# File 'lib/htpasswd/auths/digest.rb', line 54

def qop
  options[:qop] ||= "auth"
end

#request_digestObject

request-digest = <“> < KD ( H(A1), unq(nonce-value)

        ":" nc-value
        ":" unq(cnonce-value)
        ":" unq(qop-value)
        ":" H(A2)
) <">


104
105
106
107
# File 'lib/htpasswd/auths/digest.rb', line 104

def request_digest
#        debug_digest("request_digest", %w( a1 nonce nc cnonce qop a2 ))
  digest_algorithm.hexdigest([a1, nonce, nc, cnonce, qop, a2] * ":")
end

#responseObject



74
75
76
# File 'lib/htpasswd/auths/digest.rb', line 74

def response
  options[:response]
end

#response_digest(htdigest) ⇒ Object



109
110
111
112
# File 'lib/htpasswd/auths/digest.rb', line 109

def response_digest(htdigest)
#        debug_digest("response_digest", %w( htdigest nonce nc cnonce qop a2 ), :htdigest=>htdigest)
  digest_algorithm.hexdigest([htdigest, nonce, nc, cnonce, qop, a2] * ":")
end

#server_headerObject



114
115
116
# File 'lib/htpasswd/auths/digest.rb', line 114

def server_header
  %Q|Digest realm="%s", nonce="%s", algorithm=%s, qop=%s| % [realm, nonce, algorithm, qop]
end

#set_controller(controller) ⇒ Object



34
35
36
37
# File 'lib/htpasswd/auths/digest.rb', line 34

def set_controller(controller)
  options[:uri]    = controller.request.path
  options[:method] = controller.request.method.to_s.upcase
end

#uriObject



58
59
60
# File 'lib/htpasswd/auths/digest.rb', line 58

def uri
  options[:uri] ||= '/'
end