# Net/pop.rb: APOP$B$N@H\<e@-BP1~(B

**URL:** <https://www.ruby-forum.com/t/net-pop-rb-apop-b-n-h-e-bp1-b/149818>\
**Category:** Development\
**Created:** [September 30, 2008, 8:30am UTC](https://www.ruby-forum.com/t/net-pop-rb-apop-b-n-h-e-bp1-b/149818 "2008-09-30T08:30:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kazuhiro\_NISHIYAMA](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/77aa72/32.png) [@Kazuhiro\_NISHIYAMA](https://www.ruby-forum.com/u/Kazuhiro_NISHIYAMA)\
**Post date:** [September 30, 2008, 8:30am UTC](https://www.ruby-forum.com/t/net-pop-rb-apop-b-n-h-e-bp1-b/149818/1 "2008-09-30T08:30:17Z")

</div>

e$B@\>;3OB9-$G$9!#e(B

# 

e$B0lEYe(removed\_email\_address@domain.invalide$B$KAw$j$^$7$?$,!"4{$K8x3+$5$l$F$$$k@H\<e@-$Ke(B

# 

e$B$D$$$F$NOC$J$N$G!"e(Bruby-deve$B$G$$$$$N$G$O$J$$$+$H$$$&$3$H$N$h$&$J$N$Ge(B

# ruby-deve$B$KAw$jD\>$7$F$$$^$9!#e(B

[http://sylpheed.sraoss.jp/diary/?date=20080926#p01](http://sylpheed.sraoss.jp/diary/?date=20080926#p01)  
e$B$r$\_$F!“e(Bnet/pop.rbe$B$be(Bsylpheede$B$HF1$8$h$&$JBP1~$re(B  
e$B$9$l$P$$$$$N$G$O$J$$$+$H;W$C$?$N$G$9$,!”$I$&$G$7$g$&$+e(B?

1.8e$B$G$Oe(BNet::POP3Command#apope$B$Ge(B  
if /[^!-~]/n =~ @apop\_stamp || /@/ !~ @apop\_stamp  
raise POPAuthenticationError, ‘Invalid APOP server; cannot  
login’  
end  
e$B$N$h$&$J%A%'%C%/$K$J$k$H;W$$$^$9!#e(B  
(1.9e$B$G$Oe(Bne$B$r$O$:$9$@$1e(B?)

e$B0J2\<$Oe(Btest/net/imap/test\_imap.rbe$B$r;29M$K$7$F:n@.$7$?%F%9%H$G$9!#e(B

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  
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

**END**  
module Net  
class POP3Command  
def apop(account, password)  
raise POPAuthenticationError, ‘not APOP server; cannot login’   
unless @apop\_stamp  
if /[^!-~]/n =~ @apop\_stamp || /@/ !~ @apop\_stamp  
raise POPAuthenticationError, ‘Invalid APOP server; cannot  
login’  
end  
check\_response\_auth(critical {  
get\_response(‘APOP %s %s’,  
account,  
Digest::MD5.hexdigest(@apop\_stamp + password))  
})  
end  
end  
end

---

<div class="post-metadata">

**Author:** ![Kazuhiro\_NISHIYAMA](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/77aa72/32.png) [@Kazuhiro\_NISHIYAMA](https://www.ruby-forum.com/u/Kazuhiro_NISHIYAMA)\
**Post date:** [September 30, 2008, 12:29pm UTC](https://www.ruby-forum.com/t/net-pop-rb-apop-b-n-h-e-bp1-b/149818/2 "2008-09-30T12:29:44Z")

</div>

e$BA0ED$G$9!#e(B

2008/09/30 15:28 Kazuhiro NISHIYAMA [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> [http://sylpheed.sraoss.jp/diary/?date=20080926#p01](http://sylpheed.sraoss.jp/diary/?date=20080926#p01)  
> e$B$r$\_$F!“e(Bnet/pop.rbe$B$be(Bsylpheede$B$HF1$8$h$&$JBP1~$re(B  
> e$B$9$l$P$$$$$N$G$O$J$$$+$H;W$C$?$N$G$9$,!”$I$&$G$7$g$&$+e(B?
> 
> 1.8e$B$G$Oe(BNet::POP3Command#apope$B$Ge(B  
> if /[^!-~]/n =~ @apop\_stamp || /@/ !~ @apop\_stamp  
> raise POPAuthenticationError, ‘Invalid APOP server; cannot login’  
> end  
> e$B$N$h$&$J%A%'%C%/$K$J$k$H;W$$$^$9!#e(B

e$BF1$8$h$&$J$3$H$G$9$,!"e(BPOP3Command#initializee$B$Ge(Btimestampe$B$K%^%C%A$5$;$ke(B  
e$B@55,I=8=\<+BN$r0J2\<$N$h$&$KJQ$($F$7$^$C$F$O$I$&$G$7$g$&$+!#e(B

def initialize(sock)  
@socket = sock  
@error\_occured = false  
res = check\_response(critical { recv\_response() })  
@apop\_stamp = res.slice(/\<[!-~]+@[!-~]+\>/)  
end

RFC1939e$B$K$h$k$H!"e(B"The syntax of the timestamp corresponds to the  
`msg-id’ in  
[RFC822]"e$B$H$N$3$H$J$N$G!"e(B(e$B$A$g$C$H@55,I=8=$,4K$$$G$9$,e(B)  
e$BLdBj$J$$5$$,$7$^$9!#e(B

e$B:,K\E\*$JBP:v$H$7$F$O!"$A$c$s$H$7$?\>ZL@=q$Ge(BPOP over  
SSLe$B$r;H$&$N$,$h$$e(B  
e$B$N$G$7$g$&$M!#e(B

---

<div class="post-metadata">

**Author:** ![Kazuhiro\_NISHIYAMA](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/77aa72/32.png) [@Kazuhiro\_NISHIYAMA](https://www.ruby-forum.com/u/Kazuhiro_NISHIYAMA)\
**Post date:** [September 30, 2008, 4:29pm UTC](https://www.ruby-forum.com/t/net-pop-rb-apop-b-n-h-e-bp1-b/149818/3 "2008-09-30T16:29:23Z")

</div>

e$B@\>;3OB9-$G$9!#e(B

At Tue, 30 Sep 2008 19:25:19 +0900,  
Shugo M. wrote:

> RFC1939e$B$K$h$k$H!"e(B"The syntax of the timestamp corresponds to the  
> `msg-id’ in [RFC822]"e$B$H$N$3$H$J$N$G!"e(B(e$B$A$g$C$H@55,I=8=$,4K$$$G$9$,e(B)  
> e$BLdBj$J$$5$$,$7$^$9!#e(B

initializee$B$r87$7$/$9$k$N$@$H967b$5$l$F$$$k2DG=@-$,$"$k$H$$$&$3$H$,e(B  
e$B$o$+$j$K$/$$$+$H;W$C$FJL%a%C%;!\<%8$NNc30$K$J$kJ}$,$$$$$+$He(B  
e$B;W$C$?$N$G$9$,!"9M$(D\>$7$F$\_$k$H!“e(BAPOPe$B$N$O$:$J$N$Ke(B  
#\<Net::POPAuthenticationError: not APOP server; cannot login\>  
e$B$K$J$k$N$OB\>$N2DG=@-$b4^$a$F$\*$+$7$$$N$G!”$=$l$GNI$5$=$&$K;W$$$^$7$?!#e(B

> e$B:,K\E\*$JBP:v$H$7$F$O!"$A$c$s$H$7$?\>ZL@=q$Ge(BPOP over SSLe$B$r;H$&$N$,$h$$e(B  
> e$B$N$G$7$g$&$M!#e(B

e$B%5!\<%PB&$b4^$a$FBP:v$G$-$k\>l9g$J$i$=$&$9$k$N$,0lHV$$$$$G$9$M!#e(B

---

<div class="post-metadata">

**Author:** ![Kazuhiro\_NISHIYAMA](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/77aa72/32.png) [@Kazuhiro\_NISHIYAMA](https://www.ruby-forum.com/u/Kazuhiro_NISHIYAMA)\
**Post date:** [October 1, 2008, 5:11am UTC](https://www.ruby-forum.com/t/net-pop-rb-apop-b-n-h-e-bp1-b/149818/4 "2008-10-01T05:11:26Z")

</div>

At Wed, 1 Oct 2008 10:18:38 +0900,  
Shugo M. wrote:

> ã—ã°ã‚‰ãä»–ã«æ„è¦‹ãŒãªã‘ã‚Œã°ruby\_1\_8ã«å–ã‚Šè¾¼ã‚€ã¨ã„ã†ã“ã¨ã§ã‚ˆã„ã§ã—ã‚‡ã†ã‹?
> 
> > æ­¦è€…ã•ã‚“  
> > timestampã®ãƒã‚§ãƒƒã‚¯ãŒç·©ã‹ã£ãŸã®ã‚’å°‘ã—åŽ³ã—ãã—ãŸã ã‘ã§ã€APIã®å¤‰æ›´ã¯ã‚ã‚Š  
> > ã¾ã›ã‚“ã€‚

ã€€ã¯ã„ã€å•é¡Œãªã„ã¨æ€ã„ã¾ã™ã€‚ãŠé¡˜ã„ã—ã¾ã™ã€‚

---

<div class="post-metadata">

**Author:** ![Kazuhiro\_NISHIYAMA](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/77aa72/32.png) [@Kazuhiro\_NISHIYAMA](https://www.ruby-forum.com/u/Kazuhiro_NISHIYAMA)\
**Post date:** [October 14, 2008, 3:48am UTC](https://www.ruby-forum.com/t/net-pop-rb-apop-b-n-h-e-bp1-b/149818/5 "2008-10-14T03:48:08Z")

</div>

e$B@\>;3OB9-$G$9!#e(B

At Wed, 1 Oct 2008 10:18:38 +0900,  
Shugo M. wrote:

> commite$B$O@DLZ$5$s$K$7$F$$$?$@$/$N$,$h$$$H;W$&$N$G$9$,!"K;$7$=$&$J$N$G!"e(B  
> e$B@DLZ$5$s$NH?1~$,$J$+$C$?$i@\>;3$5$s$K$\*4j$$$9$k$N$,$h$$$G$7$g$&$+!#e(B

e$BH?1~$,$J$$$h$&$J$N$Ge(Btrunke$B$He(Bruby\_1\_8e$B$Ke(Bcommite$B$7$F$\*$-$^$9!#e(B

---

<div class="post-metadata">

**Author:** ![Kazuhiro\_NISHIYAMA](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/77aa72/32.png) [@Kazuhiro\_NISHIYAMA](https://www.ruby-forum.com/u/Kazuhiro_NISHIYAMA)\
**Post date:** [October 1, 2008, 3:20am UTC](https://www.ruby-forum.com/t/net-pop-rb-apop-b-n-h-e-bp1-b/149818/6 "2008-10-01T03:20:16Z")

</div>

e$BA0ED$G$9!#e(B

2008/09/30 23:27 Kazuhiro NISHIYAMA [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> initializee$B$r87$7$/$9$k$N$@$H967b$5$l$F$$$k2DG=@-$,$"$k$H$$$&$3$H$,e(B  
> e$B$o$+$j$K$/$$$+$H;W$C$FJL%a%C%;!\<%8$NNc30$K$J$kJ}$,$$$$$+$He(B  
> e$B;W$C$?$N$G$9$,!"9M$(D\>$7$F$\_$k$H!“e(BAPOPe$B$N$O$:$J$N$Ke(B  
> #\<Net::POPAuthenticationError: not APOP server; cannot login\>  
> e$B$K$J$k$N$OB\>$N2DG=@-$b4^$a$F$\*$+$7$$$N$G!”$=$l$GNI$5$=$&$K;W$$$^$7$?!#e(B

e$B$=$&$G$9$M!"$A$c$s$H@\_Dj$5$l$F$$$k4D6-$G$O!"IaDL$O$3$NNc30$,H/@8$9$k$3$H$Oe(B  
e$B$J$$$s$8$c$J$$$+$H;W$$$^$9!#e(B

e$B$7$P$i$/B\>$K0U8+$,$J$1$l$Pe(Bruby\_1\_8e$B$K\<h$j9~$`$H$$$&$3$H$G$h$$$G$7$g$&$+e(B?

> e$BIp\<T$5$se(B  
> timestampe$B$N%A%'%C%/$,4K$+$C$?$N$r\>/$787$7$/$7$?$@$1$G!“e(BAPIe$B$NJQ99$O$”$je(B  
> e$B$^$;$s!#e(B

commite$B$O@DLZ$5$s$K$7$F$$$?$@$/$N$,$h$$$H;W$&$N$G$9$,!"K;$7$=$&$J$N$G!"e(B  
e$B@DLZ$5$s$NH?1~$,$J$+$C$?$i@\>;3$5$s$K$\*4j$$$9$k$N$,$h$$$G$7$g$&$+!#e(B
