我有一个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 主机名 110"类似的状态,但已加密:-
openssl s_client -crlf -connect hostname:995
我希望找到一种方法,可以在openssl命令上设置某种读/写FileHandle或套接字,我可以读取直到它为空,然后写入所需的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 $urn";
print "USER $un";
while (<$sslread>) {
print;
if (/^+OK.*$/) {
## Keep going
print $sslwrite "PASS $prn";
print "PASS $pn";
while (<$sslread>) {
print;
}
}
}
print $sslwrite "QUIT";
print "QUITn";
}
}
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.
我做错了什么?
IPC::Open2
附加两个文件句柄,一个附加到程序的输入,一个附加到程序的输出。它可能更接近您真正想要使用的 IO::Socket::SSL
,其功能类似于IO::Socket::INET
但加密。
更新:我最好的猜测是你加倍r
角色。根据手册页s_client
-crlf
将换行转换为回车 + 换行。当您打印到$sslwrite
句柄时,您将发送"rn"
。我认为结果是服务器会在每个命令的末尾收到"\r\r"。您可能希望从程序中的 openssl
命令中删除-crlf
。