Skip Menu |

This queue is for tickets about the Mail-POP3Client CPAN distribution.

Report information
The Basics
Id: 83288
Status: new
Priority: 0/
Queue: Mail-POP3Client

People
Owner: Nobody in particular
Requestors: christopher_wood [...] pobox.com
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: 2.18
Fixed in: (no value)



Subject: patch for starttls support
(Short form: patch attached to implement rudimentary STARTTLS support into Mail::POP3Client.) Good afternoon, For work I've had to implement starttls support into a pop3 client for testing, so I ended up patching Mail::POP3Client as the simple/obvious solution. I attempted to keep to the coding style where I could. I haven't tested it for weeks/months and it's likely not feature-complete, but it at least solves my immediate problem. Thank you for the module, it has been quite useful. I would use the patch to be able to do this: my $pop = new Hostopia::Mail::POP3Client( HOST => $host, PORT => $port, USER => $user, PASSWORD => $pass, USESTARTTLS => 1, ); And this too: my $pop = new Hostopia::Mail::POP3Client( HOST => $host, PORT => $port, ); $pop->starttls(); $pop->User($user); $pop->Pass($pass); $pop->Login();
Subject: POP3Client.patch
*** POP3Client.pm.orig 2013-02-12 15:47:25.493463321 -0500 --- POP3Client.pm 2013-02-12 15:47:25.493463321 -0500 *************** *** 68,73 **** --- 68,76 ---- LOCALADDR => undef, SOCKET => undef, USESSL => 0, + USESTARTTLS => 0, + SSL_VERIFY_MODE => 1, + SSL_CA_PATH => '/etc/ssl/certs', }; $self->{tranlog} = (); $^O =~ /MacOS/i && ($self->{STRIPCR} = 1); *************** *** 196,201 **** --- 199,229 ---- #****************************************************************************** + #* set/query the SSL_verify_mode + #****************************************************************************** + sub Ssl_verify_mode + { + my $me = shift; + my $SSL_verify_mode = shift or return $me->{SSL_VERIFY_MODE}; + + $me->{SSL_VERIFY_MODE} = $SSL_verify_mode; + + } # end Ssl_verify_mode + + #****************************************************************************** + #* set/query the SSL_ca_path + #****************************************************************************** + sub Ssl_ca_path + { + my $me = shift; + my $SSL_ca_path = shift or return $me->{SSL_CA_PATH}; + + $me->{SSL_CA_PATH} = $SSL_ca_path; + + } # end Ssl_ca_path + + + #****************************************************************************** #* set the host #****************************************************************************** sub Host *************** *** 306,311 **** --- 334,379 ---- #****************************************************************************** #* #****************************************************************************** + sub Starttls + { + my ($me, $SSL_verify_mode, $SSL_ca_path) = @_; + + $SSL_verify_mode and $me->Ssl_verify_mode($SSL_verify_mode); + $SSL_ca_path and $me->Ssl_ca_path($SSL_ca_path); + + my $has_starttls = 0; + foreach my $capa ($me->Capa()) { + $capa =~ /STLS/ and $has_starttls = 1 and last; + } + + if ($has_starttls && $me->Socket() && $me->Socket()->connected() ) { + $me->_sockprint( "STLS", $me->EOL ); + my $line = $me->_sockread(); + unless (defined $line) { + $me->Message("Socket read failed for STLS"); + undef $me->{SOCKET}; + return 0; + } + $line =~ /^\+OK/i || return 0; + require IO::Socket::SSL; + IO::Socket::SSL->start_SSL( + $me->Socket(), + SSL_verify_mode => $me->Ssl_verify_mode(), + SSL_ca_path => $me->Ssl_ca_path(), + ) or $me->Message("Could not upgrade to TLS: $!") and + return 0; + } + 1; + } # end Starttls + + sub Stls { Starttls(@_); } + sub starttls { Starttls(@_); } + sub stls { Starttls(@_); } + + + #****************************************************************************** + #* + #****************************************************************************** sub Close { my $me = shift; *************** *** 378,383 **** --- 446,453 ---- Proto => "tcp", Type => SOCK_STREAM, LocalAddr => $me->LocalAddr(), + SSL_verify_mode => $me->Ssl_verify_mode(), + SSL_ca_path => $me->Ssl_ca_path(), Timeout => $me->{TIMEOUT} ) or $me->Message( "could not connect SSL socket [$me->{HOST}, $me->{PORT}]: $!" ) and return 0; *************** *** 413,419 **** $me->Message($msg); $me->State('AUTHORIZATION'); ! defined($me->User()) and defined($me->Pass()) and $me->Login(); } # end Connect --- 483,498 ---- $me->Message($msg); $me->State('AUTHORIZATION'); ! ! if (!$me->{USESSL} && $me->{USESTARTTLS}) { ! $me->Starttls() or $me->Message("Starttls problem: $!") and return 0; ! } ! ! if (defined($me->User()) and defined($me->Pass())) { ! $me->Login(); ! } else { ! return 1; ! } } # end Connect *************** *** 1250,1255 **** --- 1329,1337 ---- LOCALADDR => 'xxx.xxx.xxx.xxx[:xx]', SOCKET => undef, USESSL => 0, + USESTARTTLS => 0, + SSL_VERIFY_MODE => 1, + SSL_CA_PATH => '/etc/ssl/certs', ); =over 4 *************** *** 1278,1283 **** --- 1360,1368 ---- =item * LOCALADDR - allow selecting a local inet address to use + =item * + USESTARTTLS - uses STLS, but ignored if USESSL is set + =back =head1 METHODS *************** *** 1499,1508 **** --- 1584,1605 ---- Set/Return the current user name. + =item I<Ssl_verify_mode>( [1|0] ) + + Set/Return the SSL verification mode. + + =item I<Ssl_ca_path>( [/path/to/ca/certs] ) + + Set/Return the SSL CA directory path. + =item I<Login> Attempt to login to the server connection. + =item I<Starttls> + + Attempt to upgrade the connection to TLS. + =item I<Host>( [HOSTNAME] ) Set/Return the current host.