summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-07-05 05:06:05 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-07-05 05:06:05 +0000
commit8fb2058d825f1e795153255ea99ecc4aa70ed414 (patch)
tree2ad645f107e732fbc1c5dbbac0fbbb6650c4ab64 /test
parentfed26e916bdc9f03f1c27b2bbc47fda6b2236c74 (diff)
* lib/webrick/httpauth/digestauth.rb (_authenticate):
Literal texts in HTTP ABNF is case-insensitive (RFC2616 2.1), and a ample implementation in RFC2617 also ignores the case of algorithms. So now this ignores those cases. [ruby-dev:43965] [Feature #4936] * lib/webrick/httpauth/digestauth.rb (initialize): Because of above, opera_hack is useless and removed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32410 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test')
-rw-r--r--test/webrick/test_httpauth.rb85
1 files changed, 85 insertions, 0 deletions
diff --git a/test/webrick/test_httpauth.rb b/test/webrick/test_httpauth.rb
index a6066908c1..6cfdcc4553 100644
--- a/test/webrick/test_httpauth.rb
+++ b/test/webrick/test_httpauth.rb
@@ -79,4 +79,89 @@ class TestWEBrickHTTPAuth < Test::Unit::TestCase
}
tmpfile.close(true)
end
+
+ DIGESTRES_ = /
+ ([a-zA-z\-]+)
+ [\s\t]*(?:\r\n[\s\t]*)*
+ =
+ [\s\t]*(?:\r\n[\s\t]*)*
+ (?:
+ "((?:[^"]+|\\[\x00-\x7F])*)" |
+ ([!\#$%&'*+\-.0-9A-Z^_`a-z|~]+)
+ )/x
+
+ def test_digest_auth
+ TestWEBrick.start_httpserver{|server, addr, port, log|
+ realm = "WEBrick's realm"
+ path = "/digest_auth"
+
+ tmpfile = Tempfile.new("test_webrick_auth")
+ tmpfile.close
+ tmp_pass = WEBrick::HTTPAuth::Htdigest.new(tmpfile.path)
+ tmp_pass.set_passwd(realm, "webrick", "supersecretpassword")
+ tmp_pass.set_passwd(realm, "foo", "supersecretpassword")
+ tmp_pass.flush
+
+ htdigest = WEBrick::HTTPAuth::Htdigest.new(tmpfile.path)
+ users = []
+ htdigest.each{|user, pass| users << user }
+ assert_equal(2, users.size, log.call)
+ assert(users.member?("webrick"), log.call)
+ assert(users.member?("foo"), log.call)
+
+ auth = WEBrick::HTTPAuth::DigestAuth.new(
+ :Realm => realm, :UserDB => htdigest,
+ :Algorithm => 'MD5',
+ :Logger => server.logger
+ )
+ server.mount_proc(path){|req, res|
+ auth.authenticate(req, res)
+ res.body = "hoge"
+ }
+
+ Net::HTTP.start(addr, port) do |http|
+ g = Net::HTTP::Get.new(path)
+ params = {}
+ http.request(g) do |res|
+ assert_equal('401', res.code, log.call)
+ res["www-authenticate"].scan(DIGESTRES_) do |key, quoted, token|
+ params[key.downcase] = token || quoted.delete('\\')
+ end
+ params['uri'] = "http://#{addr}:#{port}#{path}"
+ end
+
+ g['Authorization'] = credentials_for_request('webrick', "supersecretpassword", params)
+ http.request(g){|res| assert_equal("hoge", res.body, log.call)}
+
+ params['algorithm'].downcase! #4936
+ g['Authorization'] = credentials_for_request('webrick', "supersecretpassword", params)
+ http.request(g){|res| assert_equal("hoge", res.body, log.call)}
+
+ g['Authorization'] = credentials_for_request('webrick', "not super", params)
+ http.request(g){|res| assert_not_equal("hoge", res.body, log.call)}
+ end
+ }
+ end
+
+ private
+ def credentials_for_request(user, password, params)
+ cnonce = "hoge"
+ nonce_count = 1
+ ha1 = "#{user}:#{params['realm']}:#{password}"
+ ha2 = "GET:#{params['uri']}"
+ request_digest =
+ "#{Digest::MD5.hexdigest(ha1)}:" \
+ "#{params['nonce']}:#{'%08x' % nonce_count}:#{cnonce}:#{params['qop']}:" \
+ "#{Digest::MD5.hexdigest(ha2)}"
+ p header = "Digest username=\"#{user}\"" \
+ ", realm=\"#{params['realm']}\"" \
+ ", nonce=\"#{params['nonce']}\"" \
+ ", uri=\"#{params['uri']}\"" \
+ ", qop=#{params['qop']}" \
+ ", nc=#{'%08x' % nonce_count}" \
+ ", cnonce=\"#{cnonce}\"" \
+ ", response=\"#{Digest::MD5.hexdigest(request_digest)}\"" \
+ ", opaque=\"#{params['opaque']}\"" \
+ ", algorithm=#{params['algorithm']}"
+ end
end