mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
fed26e916b
commit
8fb2058d82
3 changed files with 98 additions and 5 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
Tue Jul 5 14:05:43 2011 NARUSE, Yui <naruse@ruby-lang.org>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
Tue Jul 5 01:30:01 2011 Yusuke Endoh <mame@tsg.ne.jp>
|
Tue Jul 5 01:30:01 2011 Yusuke Endoh <mame@tsg.ne.jp>
|
||||||
|
|
||||||
* thread_pthread.c (native_sleep): cut the waiting time up to
|
* thread_pthread.c (native_sleep): cut the waiting time up to
|
||||||
|
|
|
@ -83,7 +83,6 @@ module WEBrick
|
||||||
@nonce_expire_period = @config[:NonceExpirePeriod]
|
@nonce_expire_period = @config[:NonceExpirePeriod]
|
||||||
@nonce_expire_delta = @config[:NonceExpireDelta]
|
@nonce_expire_delta = @config[:NonceExpireDelta]
|
||||||
@internet_explorer_hack = @config[:InternetExplorerHack]
|
@internet_explorer_hack = @config[:InternetExplorerHack]
|
||||||
@opera_hack = @config[:OperaHack]
|
|
||||||
|
|
||||||
case @algorithm
|
case @algorithm
|
||||||
when 'MD5','MD5-sess'
|
when 'MD5','MD5-sess'
|
||||||
|
@ -175,8 +174,7 @@ module WEBrick
|
||||||
end
|
end
|
||||||
|
|
||||||
auth_req['algorithm'] ||= 'MD5'
|
auth_req['algorithm'] ||= 'MD5'
|
||||||
if auth_req['algorithm'] != @algorithm &&
|
if auth_req['algorithm'].upcase != @algorithm.upcase
|
||||||
(@opera_hack && auth_req['algorithm'] != @algorithm.upcase)
|
|
||||||
error('%s: algorithm unmatch. "%s" for "%s"',
|
error('%s: algorithm unmatch. "%s" for "%s"',
|
||||||
auth_req['username'], auth_req['algorithm'], @algorithm)
|
auth_req['username'], auth_req['algorithm'], @algorithm)
|
||||||
return false
|
return false
|
||||||
|
@ -212,8 +210,7 @@ module WEBrick
|
||||||
nonce_is_invalid = true
|
nonce_is_invalid = true
|
||||||
end
|
end
|
||||||
|
|
||||||
if /-sess$/ =~ auth_req['algorithm'] ||
|
if /-sess$/i =~ auth_req['algorithm']
|
||||||
(@opera_hack && /-SESS$/ =~ auth_req['algorithm'])
|
|
||||||
ha1 = hexdigest(password, auth_req['nonce'], auth_req['cnonce'])
|
ha1 = hexdigest(password, auth_req['nonce'], auth_req['cnonce'])
|
||||||
else
|
else
|
||||||
ha1 = password
|
ha1 = password
|
||||||
|
|
|
@ -79,4 +79,89 @@ class TestWEBrickHTTPAuth < Test::Unit::TestCase
|
||||||
}
|
}
|
||||||
tmpfile.close(true)
|
tmpfile.close(true)
|
||||||
end
|
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
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue