POP3 with TLS in Perl

The famous libnet modules provide Perl programmers with a low level interface to POP3 and SMTP servers, among others.

This works fine in general but over the past years most mail servers stopped offering 'plain' SMTP and POP3 access, but use either SSL or TLS encryption. This has lead to a plethora of modules on CPAN to support SMTP via SSL or TLS and also for POP3 via SSL. Until recently this was not the case for POP3 using TLS security. But earlier this week Steffen Ullrich, the maintainer of IO::Socket::SSL, released a new version of Net::SSLGlue that also allows for connecting to POP3 over TLS. And as opposed to many of the other modules, it also allows to verify the SSL certificate on the remote server for extra security. Net::SSLGlue works for Net::SMTP, Net::POP3, Net::LDAP, and LWP.

Here is an example of how you can connect to a POP3 mail server over TLS:

#!/usr/bin/env perl

use strict;
use warnings;

use Net::SSLGlue::POP3;

my $host  = 'pop.aol.com';
my $login = 'myusername@aol.com';
my $pass  = '4Radfsai8fsfd9sdf9sdf';

my $pop3 = Net::POP3->new( $host) || die "Can't connect to $host: $!";
# no SSL verification: vulnerable for Man in the Middle attack
$pop3->starttls( SSL_verify_mode => 0 ) || die "Can't perform starttls: $!";

my $messages = $pop3->login( $login, $pass ) || die "Failed to authenticate login $login on $host: $!";

print "There are $messages messages on $host for $login.\n";

This would give you all the safety of SSL encryption, so no-one can eavesdrop on your communication; but you still have not verified the remote certificate. So in theory, people could set up a server impersonating the mail server and poison DNS. You connect to their mail server nice and securely, thinking it is the original mail server, and you tell them your password. This is called a "Man in the Middle-attack". Luckily Net::SSLGlue also exposes the internals of IO::Socket::SSL. This is no coincidence because they both have the same maintainer. Read the module documentation for the fine details; if you do not have OpenSSL installed or certificate bundles at hand a convenient way is to use the certificates of Mozilla::CA as in the code example below.

#!/usr/bin/env perl

use strict;
use warnings;

use Net::SSLGlue::POP3;
use Mozilla::CA;

my $host  = 'pop.aol.com';
my $login = 'myusername@aol.com';
my $pass  = '4Radfsai8fsfd9sdf9sdf';

my $pop3 = Net::POP3->new( $host) || die "Can't connect to $host: $!";
$pop3->starttls(
    SSL_verify_mode => 1,
    SSL_ca_file => Mozilla::CA::SSL_ca_file(),
) || die "Can't perform starttls: $!";

my $messages = $pop3->login( $login, $pass ) || die "Failed to authenticate login $login on $host: $!";

print "There are $messages messages on $host for $login.\n";

Thanks to Steffen for an awesome module!

2 Comments

On the topic of pop3, ssl and perl; 'swaks' is a great pop3 debugging tool written in perl. apt-get it.

Leave a comment

About Mike B

user-pic I blog about Perl.