1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 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
|