mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/net/pop.rb: check for invalid APOP timestamp. (CVE-2007-1558)
[ruby-dev:36631] * test/net/pop/test_pop.rb: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19776 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
339ceda4e8
commit
0e0d05d5f4
3 changed files with 140 additions and 1 deletions
|
@ -1,3 +1,10 @@
|
|||
Tue Oct 14 11:14:26 2008 Kazuhiro NISHIYAMA <zn@mbf.nifty.com>
|
||||
|
||||
* lib/net/pop.rb: check for invalid APOP timestamp. (CVE-2007-1558)
|
||||
[ruby-dev:36631]
|
||||
|
||||
* test/net/pop/test_pop.rb: ditto.
|
||||
|
||||
Tue Oct 14 09:39:32 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* ruby.c (set_internal_encoding_once): check double contradicted
|
||||
|
|
|
@ -870,7 +870,7 @@ module Net
|
|||
@socket = sock
|
||||
@error_occured = false
|
||||
res = check_response(critical { recv_response() })
|
||||
@apop_stamp = res.slice(/<.+>/)
|
||||
@apop_stamp = res.slice(/<[!-~]+@[!-~]+>/)
|
||||
end
|
||||
|
||||
attr_reader :socket
|
||||
|
|
132
test/net/pop/test_pop.rb
Normal file
132
test/net/pop/test_pop.rb
Normal file
|
@ -0,0 +1,132 @@
|
|||
require 'net/pop'
|
||||
require 'test/unit'
|
||||
require 'digest/md5'
|
||||
|
||||
class TestPOP < Test::Unit::TestCase
|
||||
def setup
|
||||
@users = {'user' => 'pass' }
|
||||
@ok_user = 'user'
|
||||
@stamp_base = "#{$$}.#{Time.now.to_i}@localhost"
|
||||
end
|
||||
|
||||
def test_pop_auth_ok
|
||||
pop_test(false) do |pop|
|
||||
assert_instance_of Net::POP3, pop
|
||||
assert_nothing_raised do
|
||||
pop.start(@ok_user, @users[@ok_user])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_pop_auth_ng
|
||||
pop_test(false) do |pop|
|
||||
assert_instance_of Net::POP3, pop
|
||||
assert_raise Net::POPAuthenticationError do
|
||||
pop.start(@ok_user, 'bad password')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_apop_ok
|
||||
pop_test(@stamp_base) do |pop|
|
||||
assert_instance_of Net::APOP, pop
|
||||
assert_nothing_raised do
|
||||
pop.start(@ok_user, @users[@ok_user])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_apop_ng
|
||||
pop_test(@stamp_base) do |pop|
|
||||
assert_instance_of Net::APOP, pop
|
||||
assert_raise Net::POPAuthenticationError do
|
||||
pop.start(@ok_user, 'bad password')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_apop_invalid
|
||||
pop_test("\x80"+@stamp_base) do |pop|
|
||||
assert_instance_of Net::APOP, pop
|
||||
assert_raise Net::POPAuthenticationError do
|
||||
pop.start(@ok_user, @users[@ok_user])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_apop_invalid_at
|
||||
pop_test(@stamp_base.sub('@', '.')) do |pop|
|
||||
assert_instance_of Net::APOP, pop
|
||||
e = assert_raise Net::POPAuthenticationError do
|
||||
pop.start(@ok_user, @users[@ok_user])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pop_test(apop=false)
|
||||
host = 'localhost'
|
||||
server = TCPServer.new(host, 0)
|
||||
port = server.addr[1]
|
||||
thread = Thread.start do
|
||||
sock = server.accept
|
||||
begin
|
||||
pop_server_loop(sock, apop)
|
||||
ensure
|
||||
sock.close
|
||||
end
|
||||
end
|
||||
begin
|
||||
pop = Net::POP3::APOP(apop).new(host, port)
|
||||
#pop.set_debug_output $stderr
|
||||
yield pop
|
||||
ensure
|
||||
begin
|
||||
pop.finish
|
||||
rescue IOError
|
||||
raise unless $!.message == "POP session not yet started"
|
||||
end
|
||||
end
|
||||
ensure
|
||||
server.close
|
||||
thread.value
|
||||
end
|
||||
|
||||
def pop_server_loop(sock, apop)
|
||||
if apop
|
||||
sock.print "+OK ready <#{apop}>\r\n"
|
||||
else
|
||||
sock.print "+OK ready\r\n"
|
||||
end
|
||||
user = nil
|
||||
while line = sock.gets
|
||||
case line
|
||||
when /^USER (.+)\r\n/
|
||||
user = $1
|
||||
if @users.key?(user)
|
||||
sock.print "+OK\r\n"
|
||||
else
|
||||
sock.print "-ERR unknown user\r\n"
|
||||
end
|
||||
when /^PASS (.+)\r\n/
|
||||
if @users[user] == $1
|
||||
sock.print "+OK\r\n"
|
||||
else
|
||||
sock.print "-ERR invalid password\r\n"
|
||||
end
|
||||
when /^APOP (.+) (.+)\r\n/
|
||||
user = $1
|
||||
if apop && Digest::MD5.hexdigest("<#{apop}>#{@users[user]}") == $2
|
||||
sock.print "+OK\r\n"
|
||||
else
|
||||
sock.print "-ERR authentication failed\r\n"
|
||||
end
|
||||
when /^QUIT/
|
||||
sock.print "+OK bye\r\n"
|
||||
return
|
||||
else
|
||||
sock.print "-ERR command not recognized\r\n"
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue