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/branches/ruby_1_8@19774 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
726c93d0b7
commit
9cb436cec8
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.
|
||||||
|
|
||||||
Sat Oct 11 10:20:17 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Sat Oct 11 10:20:17 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* lib/mkmf.rb (CLEANINGS): uses escaped form tabs to preventing the
|
* lib/mkmf.rb (CLEANINGS): uses escaped form tabs to preventing the
|
||||||
|
|
|
@ -870,7 +870,7 @@ module Net
|
||||||
@socket = sock
|
@socket = sock
|
||||||
@error_occured = false
|
@error_occured = false
|
||||||
res = check_response(critical { recv_response() })
|
res = check_response(critical { recv_response() })
|
||||||
@apop_stamp = res.slice(/<.+>/)
|
@apop_stamp = res.slice(/<[!-~]+@[!-~]+>/)
|
||||||
end
|
end
|
||||||
|
|
||||||
def inspect
|
def inspect
|
||||||
|
|
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
Add a link
Reference in a new issue