3 # Copyright (C) 1995-2004 Graham Barr. All rights reserved.
4 # Copyright (C) 2013-2016, 2020 Steve Hay. All rights reserved.
5 # This module is free software; you can redistribute it and/or modify it under
6 # the same terms as Perl itself, i.e. under the terms of either the GNU General
7 # Public License or the Artistic License, as specified in the F<LICENCE> file.
21 our $VERSION = "3.12";
23 # Code for detecting if we can use SSL
24 my $ssl_class = eval {
25 require IO::Socket::SSL;
26 # first version with default CA on most platforms
27 no warnings 'numeric';
28 IO::Socket::SSL->VERSION(2.007);
29 } && 'IO::Socket::SSL';
31 my $nossl_warn = !$ssl_class &&
32 'To use SSL please install IO::Socket::SSL with version>=2.007';
34 # Code for detecting if we can use IPv6
35 my $family_key = 'Domain';
36 my $inet6_class = eval {
37 require IO::Socket::IP;
38 no warnings 'numeric';
39 IO::Socket::IP->VERSION(0.25) || die;
40 $family_key = 'Family';
41 } && 'IO::Socket::IP' || eval {
42 require IO::Socket::INET6;
43 no warnings 'numeric';
44 IO::Socket::INET6->VERSION(2.62);
45 } && 'IO::Socket::INET6';
48 sub can_ssl { $ssl_class };
49 sub can_inet6 { $inet6_class };
51 our @ISA = ('Net::Cmd', $inet6_class || 'IO::Socket::INET');
55 my $type = ref($self) || $self;
63 $host = delete $arg{Host};
65 my $hosts = defined $host ? [$host] : $NetConfig{pop3_hosts};
70 die $nossl_warn if !$ssl_class;
74 $arg{Timeout} = 120 if ! defined $arg{Timeout};
76 foreach my $h (@{$hosts}) {
77 $obj = $type->SUPER::new(
78 PeerAddr => ($host = $h),
79 PeerPort => $arg{Port} || 'pop3(110)',
81 $family_key => $arg{Domain} || $arg{Family},
82 LocalAddr => $arg{LocalAddr},
83 LocalPort => exists($arg{ResvPort}) ? $arg{ResvPort} : $arg{LocalPort},
84 Timeout => $arg{Timeout},
92 ${*$obj}{'net_pop3_arg'} = \%arg;
93 ${*$obj}{'net_pop3_host'} = $host;
95 Net::POP3::_SSL->start_SSL($obj,%arg) or return;
99 $obj->debug(exists $arg{Debug} ? $arg{Debug} : undef);
101 unless ($obj->response() == CMD_OK) {
106 ${*$obj}{'net_pop3_banner'} = $obj->message;
114 ${*$me}{'net_pop3_host'};
118 ## We don't want people sending me their passwords when they report problems
123 sub debug_text { $_[2] =~ /^(pass|rpop)/i ? "$1 ....\n" : $_[2]; }
127 @_ >= 1 && @_ <= 3 or croak 'usage: $pop3->login([$user[, $pass]])';
128 my ($me, $user, $pass) = @_;
131 ($user, $pass) = $me->_lookup_credentials($user);
135 and $me->pass($pass);
140 $ssl_class or die $nossl_warn;
141 $self->_STLS or return;
142 Net::POP3::_SSL->start_SSL($self,
143 %{ ${*$self}{'net_pop3_arg'} }, # (ssl) args given in new
150 @_ >= 1 && @_ <= 3 or croak 'usage: $pop3->apop([$user[, $pass]])';
151 my ($me, $user, $pass) = @_;
155 if (eval { local $SIG{__DIE__}; require Digest::MD5 }) {
156 $md = Digest::MD5->new();
158 elsif (eval { local $SIG{__DIE__}; require MD5 }) {
162 carp "You need to install Digest::MD5 or MD5 to use the APOP command";
167 unless ($banner = (${*$me}{'net_pop3_banner'} =~ /(<.*>)/)[0]);
170 ($user, $pass) = $me->_lookup_credentials($user);
173 $md->add($banner, $pass);
176 unless ($me->_APOP($user, $md->hexdigest));
178 $me->_get_mailbox_count();
183 @_ == 2 or croak 'usage: $pop3->user($user)';
184 $_[0]->_USER($_[1]) ? 1 : undef;
189 @_ == 2 or croak 'usage: $pop3->pass($pass)';
191 my ($me, $pass) = @_;
194 unless ($me->_PASS($pass));
196 $me->_get_mailbox_count();
201 @_ == 1 or croak 'usage: $obj->reset()';
208 if (defined ${*$me}{'net_pop3_mail'}) {
210 foreach (@{${*$me}{'net_pop3_mail'}}) {
211 delete $_->{'net_pop3_deleted'};
218 @_ == 1 or croak 'usage: $obj->last()';
221 unless $_[0]->_LAST && $_[0]->message =~ /(\d+)/;
228 @_ == 2 || @_ == 3 or croak 'usage: $pop3->top($msgnum[, $numlines])';
232 unless $me->_TOP($_[0], $_[1] || 0);
239 @_ == 1 or croak 'usage: $pop3->popstat()';
243 unless $me->_STAT && $me->message =~ /(\d+)\D+(\d+)/;
250 @_ == 1 || @_ == 2 or croak 'usage: $pop3->list([$msgnum])';
254 unless $me->_LIST(@_);
257 $me->message =~ /\d+\D+(\d+)/;
261 my $info = $me->read_until_dot
264 my %hash = map { (/(\d+)\D+(\d+)/) } @$info;
271 @_ == 2 or @_ == 3 or croak 'usage: $pop3->get($msgnum[, $fh])';
275 unless $me->_RETR(shift);
277 $me->read_until_dot(@_);
282 @_ == 2 or croak 'usage: $pop3->getfh($msgnum)';
285 return unless $me->_RETR(shift);
291 @_ == 2 or croak 'usage: $pop3->delete($msgnum)';
293 return 0 unless $me->_DELE(@_);
294 ${*$me}{'net_pop3_deleted'} = 1;
299 @_ == 1 || @_ == 2 or croak 'usage: $pop3->uidl([$msgnum])';
306 $uidl = ($me->message =~ /\d+\s+([\041-\176]+)/)[0];
309 my $ref = $me->read_until_dot
312 foreach my $ln (@$ref) {
313 my ($msg, $uid) = $ln =~ /^\s*(\d+)\s+([\041-\176]+)/;
314 $uidl->{$msg} = $uid;
322 @_ == 2 or croak 'usage: $pop3->ping($user)';
325 return () unless $me->_PING(@_) && $me->message =~ /(\d+)\D+(\d+)/;
331 sub _lookup_credentials {
332 my ($me, $user) = @_;
336 $user ||= eval { local $SIG{__DIE__}; (getpwuid($>))[0] }
341 my $m = Net::Netrc->lookup(${*$me}{'net_pop3_host'}, $user);
342 $m ||= Net::Netrc->lookup(${*$me}{'net_pop3_host'});
352 sub _get_mailbox_count {
354 my $ret = ${*$me}{'net_pop3_count'} =
355 ($me->message =~ /(\d+)\s+message/io) ? $1 : ($me->popstat)[0];
361 sub _STAT { shift->command('STAT' )->response() == CMD_OK }
362 sub _LIST { shift->command('LIST', @_)->response() == CMD_OK }
363 sub _RETR { shift->command('RETR', $_[0])->response() == CMD_OK }
364 sub _DELE { shift->command('DELE', $_[0])->response() == CMD_OK }
365 sub _NOOP { shift->command('NOOP' )->response() == CMD_OK }
366 sub _RSET { shift->command('RSET' )->response() == CMD_OK }
367 sub _QUIT { shift->command('QUIT' )->response() == CMD_OK }
368 sub _TOP { shift->command( 'TOP', @_)->response() == CMD_OK }
369 sub _UIDL { shift->command('UIDL', @_)->response() == CMD_OK }
370 sub _USER { shift->command('USER', $_[0])->response() == CMD_OK }
371 sub _PASS { shift->command('PASS', $_[0])->response() == CMD_OK }
372 sub _APOP { shift->command('APOP', @_)->response() == CMD_OK }
373 sub _PING { shift->command('PING', $_[0])->response() == CMD_OK }
374 sub _RPOP { shift->command('RPOP', $_[0])->response() == CMD_OK }
375 sub _LAST { shift->command('LAST' )->response() == CMD_OK }
376 sub _CAPA { shift->command('CAPA' )->response() == CMD_OK }
377 sub _STLS { shift->command("STLS", )->response() == CMD_OK }
391 if (defined fileno($me) and ${*$me}{'net_pop3_deleted'}) {
398 ## POP3 has weird responses, so we emulate them to look the same :-)
404 my $str = $cmd->getline() or return;
407 $cmd->debug_print(0, $str)
410 if ($str =~ s/^\+OK\s*//io) {
413 elsif ($str =~ s/^\+\s*//io) {
417 $str =~ s/^-ERR\s*//io;
420 ${*$cmd}{'net_cmd_resp'} = [$str];
421 ${*$cmd}{'net_cmd_code'} = $code;
429 my ($capa, %capabilities);
431 # Fake a capability here
432 $capabilities{APOP} = '' if ($this->banner() =~ /<.*>/);
434 if ($this->_CAPA()) {
435 $capabilities{CAPA} = 1;
436 $capa = $this->read_until_dot();
437 %capabilities = (%capabilities, map {/^\s*(\S+)\s*(.*)/} @$capa);
441 # Check AUTH for SASL capabilities
442 if ($this->command('AUTH')->response() == CMD_OK) {
443 my $mechanism = $this->read_until_dot();
444 $capabilities{SASL} = join " ", map {m/([A-Z0-9_-]+)/} @{$mechanism};
448 return ${*$this}{'net_pop3e_capabilities'} = \%capabilities;
455 ${*$this}{'net_pop3e_capabilities'} || $this->capa;
460 my ($self, $username, $password) = @_;
463 require MIME::Base64;
464 require Authen::SASL;
465 } or $self->set_status(500, ["Need MIME::Base64 and Authen::SASL todo auth"]), return 0;
467 my $capa = $self->capa;
468 my $mechanisms = $capa->{SASL} || 'CRAM-MD5';
472 if (ref($username) and UNIVERSAL::isa($username, 'Authen::SASL')) {
474 my $user_mech = $sasl->mechanism || '';
475 my @user_mech = split(/\s+/, $user_mech);
477 @user_mech{@user_mech} = ();
479 my @server_mech = split(/\s+/, $mechanisms);
480 my @mech = @user_mech
481 ? grep { exists $user_mech{$_} } @server_mech
486 [ 'Client SASL mechanisms (',
487 join(', ', @user_mech),
488 ') do not match the SASL mechnism the server announces (',
489 join(', ', @server_mech), ')',
495 $sasl->mechanism(join(" ", @mech));
498 die "auth(username, password)" if not length $username;
499 $sasl = Authen::SASL->new(
500 mechanism => $mechanisms,
504 authname => $username,
509 # We should probably allow the user to pass the host, but I don't
510 # currently know and SASL mechanisms that are used by smtp that need it
511 my ($hostname) = split /:/, ${*$self}{'net_pop3_host'};
512 my $client = eval { $sasl->client_new('pop', $hostname, 0) };
515 my $mech = $sasl->mechanism;
518 [ " Authen::SASL failure: $@",
519 '(please check if your local Authen::SASL installation',
520 "supports mechanism '$mech'"
526 my ($token) = $client->client_start
528 my $mech = $client->mechanism;
531 [ ' Authen::SASL failure: $client->client_start ',
532 "mechanism '$mech' hostname #$hostname#",
539 # We don't support sasl mechanisms that encrypt the socket traffic.
540 # todo that we would really need to change the ISA hierarchy
541 # so we don't inherit from IO::Socket, but instead hold it in an attribute
543 my @cmd = ("AUTH", $client->mechanism);
546 push @cmd, MIME::Base64::encode_base64($token, '')
547 if defined $token and length $token;
549 while (($code = $self->command(@cmd)->response()) == CMD_MORE) {
551 my ($token) = $client->client_step(MIME::Base64::decode_base64(($self->message)[0])) or do {
554 [ ' Authen::SASL failure: $client->client_step ',
555 "mechanism '", $client->mechanism, " hostname #$hostname#, ",
562 @cmd = (MIME::Base64::encode_base64(defined $token ? $token : '', ''));
572 return ${*$this}{'net_pop3_banner'};
576 package Net::POP3::_SSL;
577 our @ISA = ( $ssl_class ? ($ssl_class):(), 'Net::POP3' );
578 sub starttls { die "POP3 connection is already in SSL mode" }
580 my ($class,$pop3,%arg) = @_;
581 delete @arg{ grep { !m{^SSL_} } keys %arg };
582 ( $arg{SSL_verifycn_name} ||= $pop3->host )
583 =~s{(?<!:):[\w()]+$}{}; # strip port
584 $arg{SSL_hostname} = $arg{SSL_verifycn_name}
585 if ! defined $arg{SSL_hostname} && $class->can_client_sni;
586 $arg{SSL_verifycn_scheme} ||= 'pop3';
587 my $ok = $class->SUPER::start_SSL($pop3,%arg);
588 $@ = $ssl_class->errstr if !$ok;
601 Net::POP3 - Post Office Protocol 3 Client class (RFC1939)
608 $pop = Net::POP3->new('pop3host');
609 $pop = Net::POP3->new('pop3host', Timeout => 60);
610 $pop = Net::POP3->new('pop3host', SSL => 1, Timeout => 60);
612 if ($pop->login($username, $password) > 0) {
613 my $msgnums = $pop->list; # hashref of msgnum => size
614 foreach my $msgnum (keys %$msgnums) {
615 my $msg = $pop->get($msgnum);
617 $pop->delete($msgnum);
625 This module implements a client interface to the POP3 protocol, enabling
626 a perl5 application to talk to POP3 servers. This documentation assumes
627 that you are familiar with the POP3 protocol described in RFC1939.
628 With L<IO::Socket::SSL> installed it also provides support for implicit and
629 explicit TLS encryption, i.e. POP3S or POP3+STARTTLS.
631 A new Net::POP3 object must be created with the I<new> method. Once
632 this has been done, all POP3 commands are accessed via method calls
635 The Net::POP3 class is a subclass of Net::Cmd and (depending on avaibility) of
636 IO::Socket::IP, IO::Socket::INET6 or IO::Socket::INET.
642 =item C<new([$host][, %options])>
644 This is the constructor for a new Net::POP3 object. C<$host> is the
645 name of the remote host to which an POP3 connection is required.
647 C<$host> is optional. If C<$host> is not given then it may instead be
648 passed as the C<Host> option described below. If neither is given then
649 the C<POP3_Hosts> specified in C<Net::Config> will be used.
651 C<%options> are passed in a hash like fashion, using key and value pairs.
652 Possible options are:
654 B<Host> - POP3 host to connect to. It may be a single scalar, as defined for
655 the C<PeerAddr> option in L<IO::Socket::INET>, or a reference to
656 an array with hosts to try in turn. The L</host> method will return the value
657 which was used to connect to the host.
659 B<Port> - port to connect to.
660 Default - 110 for plain POP3 and 995 for POP3s (direct SSL).
662 B<SSL> - If the connection should be done from start with SSL, contrary to later
663 upgrade with C<starttls>.
664 You can use SSL arguments as documented in L<IO::Socket::SSL>, but it will
665 usually use the right arguments already.
667 B<LocalAddr> and B<LocalPort> - These parameters are passed directly
668 to IO::Socket to allow binding the socket to a specific local address and port.
669 For compatibility with older versions B<ResvPort> can be used instead of
672 B<Domain> - This parameter is passed directly to IO::Socket and makes it
673 possible to enforce IPv4 connections even if L<IO::Socket::IP> is used as super
674 class. Alternatively B<Family> can be used.
676 B<Timeout> - Maximum time, in seconds, to wait for a response from the
677 POP3 server (default: 120)
679 B<Debug> - Enable debugging information
683 =head2 Object Methods
685 Unless otherwise stated all methods return either a I<true> or I<false>
686 value, with I<true> meaning that the operation was a success. When a method
687 states that it returns a value, failure will be returned as I<undef> or an
690 C<Net::POP3> inherits from C<Net::Cmd> so methods defined in C<Net::Cmd> may
691 be used to send commands to the remote POP3 server in addition to the methods
698 Returns the value used by the constructor, and passed to IO::Socket::INET,
699 to connect to the host.
701 =item C<auth($username, $password)>
703 Attempt SASL authentication.
707 Send the USER command.
711 Send the PASS command. Returns the number of messages in the mailbox.
713 =item C<login([$user[, $pass]])>
715 Send both the USER and PASS commands. If C<$pass> is not given the
716 C<Net::POP3> uses C<Net::Netrc> to lookup the password using the host
717 and username. If the username is not specified then the current user name
720 Returns the number of messages in the mailbox. However if there are no
721 messages on the server the string C<"0E0"> will be returned. This is
722 will give a true value in a boolean context, but zero in a numeric context.
724 If there was an error authenticating the user then I<undef> will be returned.
726 =item C<starttls(%sslargs)>
728 Upgrade existing plain connection to SSL.
729 You can use SSL arguments as documented in L<IO::Socket::SSL>, but it will
730 usually use the right arguments already.
732 =item C<apop([$user[, $pass]])>
734 Authenticate with the server identifying as C<$user> with password C<$pass>.
735 Similar to L</login>, but the password is not sent in clear text.
737 To use this method you must have the Digest::MD5 or the MD5 module installed,
738 otherwise this method will return I<undef>.
742 Return the sever's connection banner
746 Return a reference to a hash of the capabilities of the server. APOP
747 is added as a pseudo capability. Note that I've been unable to
748 find a list of the standard capability values, and some appear to
749 be multi-word and some are not. We make an attempt at intelligently
750 parsing them, but it may not be correct.
752 =item C<capabilities()>
754 Just like capa, but only uses a cache from the last time we asked
755 the server, so as to avoid asking more than once.
757 =item C<top($msgnum[, $numlines])>
759 Get the header and the first C<$numlines> of the body for the message
760 C<$msgnum>. Returns a reference to an array which contains the lines of text
761 read from the server.
763 =item C<list([$msgnum])>
765 If called with an argument the C<list> returns the size of the message
768 If called without arguments a reference to a hash is returned. The
769 keys will be the C<$msgnum>'s of all undeleted messages and the values will
770 be their size in octets.
772 =item C<get($msgnum[, $fh])>
774 Get the message C<$msgnum> from the remote mailbox. If C<$fh> is not given
775 then get returns a reference to an array which contains the lines of
776 text read from the server. If C<$fh> is given then the lines returned
777 from the server are printed to the filehandle C<$fh>.
779 =item C<getfh($msgnum)>
781 As per get(), but returns a tied filehandle. Reading from this
782 filehandle returns the requested message. The filehandle will return
783 EOF at the end of the message and should not be reused.
787 Returns the highest C<$msgnum> of all the messages accessed.
791 Returns a list of two elements. These are the number of undeleted
792 elements and the size of the mbox in octets.
796 Returns a list of two elements. These are the number of new messages
797 and the total number of messages for C<$user>.
799 =item C<uidl([$msgnum])>
801 Returns a unique identifier for C<$msgnum> if given. If C<$msgnum> is not
802 given C<uidl> returns a reference to a hash where the keys are the
803 message numbers and the values are the unique identifiers.
805 =item C<delete($msgnum)>
807 Mark message C<$msgnum> to be deleted from the remote mailbox. All messages
808 that are marked to be deleted will be removed from the remote mailbox
809 when the server connection closed.
813 Reset the status of the remote POP3 server. This includes resetting the
814 status of all messages to not be deleted.
818 Quit and close the connection to the remote POP3 server. Any messages marked
819 as deleted will be deleted from the remote mailbox.
823 Returns whether we can use IPv6.
827 Returns whether we can use SSL.
833 If a C<Net::POP3> object goes out of scope before C<quit> method is called
834 then the C<reset> method will called before the connection is closed. This
835 means that any messages marked to be deleted will not be.
843 See L<https://rt.cpan.org/Dist/Display.html?Status=Active&Queue=libnet>.
853 Graham Barr E<lt>L<gbarr@pobox.com|mailto:gbarr@pobox.com>E<gt>.
855 Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
856 libnet as of version 1.22_02.
860 Copyright (C) 1995-2004 Graham Barr. All rights reserved.
862 Copyright (C) 2013-2016, 2020 Steve Hay. All rights reserved.
866 This module is free software; you can redistribute it and/or modify it under the
867 same terms as Perl itself, i.e. under the terms of either the GNU General Public
868 License or the Artistic License, as specified in the F<LICENCE> file.
880 See the F<Changes> file.