Class: Innards::DigestHandler

Inherits:
Object
  • Object
show all
Includes:
Exceptions
Defined in:
lib/innards/digest_handler.rb

Overview

Handles Digest Authentication

Instance Method Summary collapse

Constructor Details

#initialize(params) ⇒ DigestHandler

Returns a new instance of DigestHandler.



8
9
10
# File 'lib/innards/digest_handler.rb', line 8

def initialize(params)
  @params = params
end

Instance Method Details

#build_digest(path, cnonce) ⇒ Object



50
51
52
53
54
55
56
57
58
# File 'lib/innards/digest_handler.rb', line 50

def build_digest path, cnonce
  digest = @params[:digest]
  digest_parts = [
                  generate_md5_hash(generate_ha1_hash),
                  digest['nonce'],
                  generate_md5_hash(generate_ha2_hash(path))]
  digest_parts.insert(2, request_nc, cnonce, digest['qop']) if has_qop?
  generate_md5_hash(digest_parts.join(":"))
end

#build_for(path) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/innards/digest_handler.rb', line 24

def build_for path
  digest = @params[:digest]
  return nil if digest.empty?

  cnonce = generate_md5_hash(random)
  header = [
    %Q(Digest username="#{@params[:login_uri].user}"),
    %Q(realm="#{digest['realm']}"),
    %Q(nonce="#{digest['nonce']}"),
    %Q(uri="#{path}"),
    %Q(response="#{build_digest(path, cnonce)}"),
  ]

  if has_qop?
    fields = [
      %Q(cnonce="#{cnonce}"),
      %Q(qop="#{digest['qop']}"),
      %Q(nc=#{request_nc})
    ]
    fields.each { |field| header << field }
  end

  header << %Q(opaque="#{digest['opaque']}") if has_opaque?
  header.join(", ")
end

#generate_ha1_hashObject



70
71
72
73
74
# File 'lib/innards/digest_handler.rb', line 70

def generate_ha1_hash
   = @params[:login_uri]
  digest = @params[:digest]
  [.user, digest['realm'], .password].join(":")
end

#generate_ha2_hash(path) ⇒ Object



76
77
78
# File 'lib/innards/digest_handler.rb', line 76

def generate_ha2_hash(path)
  ["GET", path].join(":")
end

#generate_md5_hash(str) ⇒ Object



88
89
90
# File 'lib/innards/digest_handler.rb', line 88

def generate_md5_hash(str)
  Digest::MD5.hexdigest(str)
end

#has_opaque?Boolean

Returns:

  • (Boolean)


60
61
62
63
# File 'lib/innards/digest_handler.rb', line 60

def has_opaque?
  digest = @params[:digest]
  digest.has_key?('opaque') and !digest['opaque'].empty?
end

#has_qop?Boolean

Returns:

  • (Boolean)


65
66
67
68
# File 'lib/innards/digest_handler.rb', line 65

def has_qop?
  digest = @params[:digest]
  digest.has_key?('qop') and !digest['qop'].empty?
end

#parse(www_authenticate_header) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/innards/digest_handler.rb', line 12

def parse www_authenticate_header
  digest = {}
  www_authenticate_header.scan(/(\w+)="(.*?)"/) {
    digest[$1] = $2
  }
  if www_authenticate_header =~ /stale=true$/
    digest[:stale] = true
    raise StaleDigestException.new
  end
  @params[:digest] = digest
end

#randomObject



84
85
86
# File 'lib/innards/digest_handler.rb', line 84

def random
  "%x" % (Time.now.to_i + rand(65535))
end

#request_ncObject



80
81
82
# File 'lib/innards/digest_handler.rb', line 80

def request_nc
  "%08d" % @params[:request_count]
end