我有一个POP3登录测试脚本,它使用IO::Socket::INET
来读取和写入TCP上打开的套接字:110。这就是我习惯的: -
my $sock = IO::Socket::INET->new(
PeerAddr => "$h:$port",
Proto => "tcp",
) or die "$!\n";
但是,我还需要通过SSL加密的POP3S(TCP:995)测试相同的POP3对话。
我发现我可以在命令行中使用以下命令,它使我的状态与“telnet hostname 110”类似,但加密: -
openssl s_client -crlf -connect hostname:995
我希望找到一种方法,我可以在openssl命令上设置某种读/写FileHandle或socket,我可以读取它为空,然后写入所需的POP3命令,然后读取响应等等...
我觉得因为我可以在屏幕上看到它,它足够接近抓,但我不太了解我的方式perl足够好,“得到它”并继续前进!
不幸的是,这个脚本将运行的服务器无法安装更多的perl模块,这可能是一个明显的解决方案。
更新
感谢@ventatsu的灵感,我现在正在使用这样的IPC::Open2
: -
my ($sslread,$sslwrite);
my $ssl_fh = open2(
$sslread,
$sslwrite,
"openssl s_client -crlf -connect mail.example.com:995"
) or die "$!\n";
while (<$sslread>) {
print;
if (/^\+OK.*$/) {
## Try to log in
print $sslwrite "USER $u\r\n";
print "USER $u\n";
while (<$sslread>) {
print;
if (/^\+OK.*$/) {
## Keep going
print $sslwrite "PASS $p\r\n";
print "PASS $p\n";
while (<$sslread>) {
print;
}
}
}
print $sslwrite "QUIT";
print "QUIT\n";
}
}
waitpid( $ssl_fh, 0 );
my $child_exit_status = $? >> 8;
我的非SSL测试脚本如此工作: -
Testing pop3 on mail.example.com:110
+OK The Microsoft Exchange POP3 service is ready.
USER mailtest@example.com
+OK
PASS Abcd3fGh
+OK User successfully logged on.
当我在CLI上的交互式SSL会话中运行POP3命令时,凭据可以正常工作,如下所示: -
openssl s_client -crlf -connect mail.example.com:995
<snip out the SSL bumph />
+OK The Microsoft Exchange POP3 service is ready.
USER mailtest@example.com
+OK
PASS Abcd3fGh
+OK User successfully logged on.
但我的SSL测试脚本几乎只能起作用: -
Testing pop3s on mail.example.com:995
<snip out the SSL bumph />
+OK The Microsoft Exchange POP3 service is ready.
USER mailtest@example.com
+OK
PASS Abcd3fGh
-ERR Logon failure: unknown user name or bad password.
我做错了什么?
答案 0 :(得分:1)
您可以使用IPC::Open2
附加两个文件句柄,一个用于输入,一个用于程序的输出。它可能更接近您真正想要使用的IO::Socket::SSL
,其功能类似IO::Socket::INET
但已加密。
<强>更新强>
我最好的猜测是你加倍\r
个字符。根据{{1}} s_client
的手册页将换行符转换为回车符+换行符。当您打印到-crlf
句柄时,您正在发送$sslwrite
。我认为结果是服务器会在每个命令结束时收到“\ r \ n \ n \ n”。您可能希望从程序中的"\r\n"
命令中删除-crlf
。