forked from jnunemaker/httparty
-
Notifications
You must be signed in to change notification settings - Fork 0
/
net_digest_auth.rb
84 lines (69 loc) · 2.01 KB
/
net_digest_auth.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
require 'digest/md5'
require 'net/http'
module Net
module HTTPHeader
def digest_auth(username, password, response)
@header['Authorization'] = DigestAuthenticator.new(username, password,
@method, @path, response).authorization_header
end
class DigestAuthenticator
def initialize(username, password, method, path, response_header)
@username = username
@password = password
@method = method
@path = path
@response = parse(response_header)
end
def authorization_header
@cnonce = md5(random)
header = [
%Q(Digest username="#{@username}"),
%Q(realm="#{@response['realm']}"),
%Q(nonce="#{@response['nonce']}"),
%Q(uri="#{@path}"),
%Q(response="#{request_digest}"),
]
if qop_present?
fields = [
%Q(cnonce="#{@cnonce}"),
%Q(qop="#{@response['qop']}"),
%Q(nc=00000001)
]
fields.each { |field| header << field }
end
header << %Q(opaque="#{@response['opaque']}") if opaque_present?
header
end
private
def parse(response_header)
response_header['www-authenticate'] =~ /Digest (.*)/
params = {}
$1.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }
params
end
def opaque_present?
@response.has_key?('opaque') and not @response['opaque'].empty?
end
def qop_present?
@response.has_key?('qop') and not @response['qop'].empty?
end
def random
"%x" % (Time.now.to_i + rand(65535))
end
def request_digest
a = [md5(a1), @response['nonce'], md5(a2)]
a.insert(2, "00000001", @cnonce, @response['qop']) if qop_present?
md5(a.join(":"))
end
def md5(str)
Digest::MD5.hexdigest(str)
end
def a1
[@username, @response['realm'], @password].join(":")
end
def a2
[@method, @path].join(":")
end
end
end
end