Module | Atom::DigestAuth |
In: |
lib/atom/http.rb
|
CNONCE | = | Digest::MD5.hexdigest("%x" % (Time.now.to_i + rand(65535))) |
HTTP Digest authentication (RFC 2617)
# File lib/atom/http.rb, line 47 def digest_authenticate(req, url, param_string = "") raise "Digest authentication requires a WWW-Authenticate header" if param_string.empty? params = parse_wwwauth_digest(param_string) qop = params[:qop] user, pass = username_and_password_for_realm(url, params[:realm]) if params[:algorithm] == "MD5" a1 = user + ":" + params[:realm] + ":" + pass else # XXX MD5-sess raise "I only support MD5 digest authentication (not #{params[:algorithm].inspect})" end if qop.nil? or qop.member? "auth" a2 = req.method + ":" + req.path else # XXX auth-int raise "only 'auth' qop supported (none of: #{qop.inspect})" end if qop.nil? response = kd(h(a1), params[:nonce] + ":" + h(a2)) else @@nonce_count += 1 nc = ('%08x' % @@nonce_count) # XXX auth-int data = "#{params[:nonce]}:#{nc}:#{CNONCE}:#{"auth"}:#{h(a2)}" response = kd(h(a1), data) end header = %Q<Digest username="#{user}", uri="#{req.path}", realm="#{params[:realm]}", response="#{response}", nonce="#{params[:nonce]}"> if params[:opaque] header += %Q<, opaque="#{params[:opaque]}"> end if params[:algorithm] != "MD5" header += ", algorithm=#{algo}" end if qop # XXX auth-int header += %Q<, nc=#{nc}, cnonce="#{CNONCE}", qop=auth> end req["Authorization"] = header end
quoted-strings plus a few special cases for Digest
# File lib/atom/http.rb, line 29 def parse_wwwauth_digest param_string params = parse_quoted_wwwauth param_string qop = params[:qop] ? params[:qop].split(",") : nil param_string.gsub(/stale=([^,]*)/) do params[:stale] = ($1.downcase == "true") end params[:algorithm] = "MD5" param_string.gsub(/algorithm=([^,]*)/) { params[:algorithm] = $1 } params end