File Coverage

blib/lib/Net/POP3_auth.pm
Criterion Covered Total %
statement 33 79 41.7
branch 0 38 0.0
condition 0 2 0.0
subroutine 11 16 68.7
pod 3 3 100.0
total 47 138 34.0


line stmt bran cond sub pod time code
1             # Net::POP3_auth.pm
2             #
3             # alex pleiner 2003, zeitform Internet Dienste
4             # thanks to Graham Barr for Net::POP3
5             # This program is free software; you can redistribute it and/or
6             # modify it under the same terms as Perl itself.
7              
8             # Net::POP3_auth is a small extension to G. Barr's Net::POP3
9             # to authenticate to an POP3 server using one of the AUTH methods
10             # APOP and SASL (Authen::SASL). This module can be expanded and is a
11             # very first implementation.
12              
13             package Net::POP3_auth;
14              
15             require 5.001;
16              
17 1     1   1828 use strict;
  1         2  
  1         44  
18 1     1   7 use vars qw($VERSION @ISA);
  1         2  
  1         219  
19 1     1   2178 use Socket 1.3;
  1         9574  
  1         1363  
20 1     1   13 use Carp;
  1         1  
  1         60  
21 1     1   2992 use IO::Socket;
  1         48204  
  1         6  
22 1     1   2309 use Net::Cmd;
  1         6221  
  1         108  
23 1     1   1065 use Net::Config;
  1         3086  
  1         146  
24 1     1   908 use Net::POP3;
  1         3778  
  1         44  
25 1     1   799 use MIME::Base64;
  1         797  
  1         64  
26 1     1   735 use Digest::HMAC_MD5 qw(hmac_md5_hex);
  1         1802  
  1         58  
27 1     1   829 use Authen::SASL;
  1         2202  
  1         8  
28              
29             $VERSION = "0.04";
30              
31             @ISA = qw(Net::POP3);
32              
33             # all other method taken from Net::SMTP
34              
35             sub auth_types {
36 0 0   0 1   @_ == 1 or croak 'usage: $pop3->auth_types()';
37 0           my $me = shift;
38              
39             return undef
40 0 0         unless $me->_CAPA;
41              
42 0           my @auth;
43 0           foreach (@{$me->read_until_dot}) {
  0            
44 0 0         push @auth, "APOP" if /^APOP/;
45 0 0         push @auth, split(/\s+/, $1) if /^SASL (.+)$/;
46             }
47 0 0         return undef unless @auth;
48 0 0         return wantarray ? @auth : join " ", @auth;
49             }
50              
51              
52             sub auth {
53 0 0   0 1   @_ == 4 or croak 'usage: $pop3->auth( AUTH, USER, PASS )';
54 0           my ($me, $auth, $user, $pass) = @_;
55              
56             ## conventional (rfc1939)
57 0 0         if (uc($auth) eq "APOP") {
    0          
58 0           return $me->apop($user, $pass);
59             }
60              
61             elsif (uc($auth) eq "PLAIN") { # standard authentication (user/pass)
62 0           return $me->login($user, $pass);
63             }
64              
65             ## sasl (rfc1734)
66             else {
67              
68 0           my $sasl = Authen::SASL->new(
69             mechanism => uc($auth),
70             callback => {
71             authname => $user,
72             user => $user,
73             pass => $pass,
74             },
75             );
76 0 0         return unless $sasl;
77 0           my $host = ${*$me}{'net_pop3_host'};
  0            
78 0           my $conn = $sasl->client_new("pop", $host);#, "noplaintext noanonymous");
79              
80 0 0         $me->_AUTH($auth) or return;
81              
82 0 0         if ( $me->code() == 201 ) {
83              
84 0 0         if (my $initial = $conn->client_start)
85             {
86 0           $me->command(encode_base64($initial, ''))->response();
87 0 0         return 1 if $me->code() == 200;
88             }
89              
90 0           while ( $me->code() == 201 )
91             {
92 0           my $message = decode_base64($me->message());
93 0           my $return = $conn->client_step($message);
94 0           $me->command(encode_base64($return, ''))->response();
95 0 0         return 1 if $me->code() == 200;
96 0 0         return if $me->code() == 500;
97             }
98             }
99             }
100             }
101              
102              
103 0     0     sub _AUTH { shift->command("AUTH", @_)->response() == CMD_OK }
104 0     0     sub _CAPA { shift->command("CAPA")->response() == CMD_OK }
105              
106              
107             sub response
108             {
109 0     0 1   my $cmd = shift;
110 0   0       my $str = $cmd->getline() || return undef;
111 0           my $code = "500";
112              
113 0 0         $cmd->debug_print(0,$str)
114             if ($cmd->debug);
115              
116 0 0         if ($str =~ s/^\+OK\s+//io) { $code = "200" }
  0 0          
117 0           elsif ($str =~ s/^\+\s+//io) { $code = "201" } ## for auth
118 0           else { $str =~ s/^-ERR\s+//io; }
119              
120 0           ${*$cmd}{'net_cmd_resp'} = [ $str ];
  0            
121 0           ${*$cmd}{'net_cmd_code'} = $code;
  0            
122              
123 0           substr($code,0,1);
124             }
125              
126             1;
127              
128              
129             __END__