File Coverage

blib/lib/Net/SMTP_auth.pm
Criterion Covered Total %
statement 33 77 42.8
branch 0 34 0.0
condition n/a
subroutine 11 14 78.5
pod 2 2 100.0
total 46 127 36.2


line stmt bran cond sub pod time code
1             # Net::SMTP_auth.pm
2             #
3             # alex pleiner 2001, 2003, 2006 zeitform Internet Dienste
4             # thanks to Graham Barr for Net::SMTP
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::SMTP_auth is a small extension to G. Barr's Net::SMTP
9             # to authenticate to an SMTP server using one of the AUTH
10             # methods provided by Authen::SASL and Authen::NTLM (see RFC2554 for details).
11             # This module can be expanded and is a very first implementation.
12              
13             package Net::SMTP_auth;
14              
15             require 5.001;
16              
17 1     1   651 use strict;
  1         1  
  1         49  
18 1     1   5 use vars qw($VERSION @ISA);
  1         1  
  1         69  
19 1     1   949 use Socket 1.3;
  1         4901  
  1         634  
20 1     1   13 use Carp;
  1         1  
  1         54  
21 1     1   1101 use IO::Socket;
  1         36577  
  1         5  
22 1     1   2561 use Net::Cmd;
  1         5864  
  1         156  
23 1     1   983 use Net::Config;
  1         2729  
  1         152  
24 1     1   1171 use Net::SMTP;
  1         6013  
  1         61  
25 1     1   1025 use MIME::Base64;
  1         921  
  1         87  
26 1     1   848 use Digest::HMAC_MD5 qw(hmac_md5_hex);
  1         2016  
  1         56  
27 1     1   816 use Authen::SASL;
  1         2078  
  1         9  
28              
29             $VERSION = "0.08";
30              
31             @ISA = qw(Net::SMTP);
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 0 0         if (exists ${*$me}{'net_smtp_esmtp'}) {
  0            
40              
41 0           my $esmtp = ${*$me}{'net_smtp_esmtp'};
  0            
42              
43 0 0         if(exists $esmtp->{AUTH}) {
44 0 0         return wantarray ? split(/\s+/, $esmtp->{AUTH}) : $esmtp->{AUTH};
45             }
46             }
47              
48 0           return;
49             }
50              
51              
52             sub auth {
53 0 0   0 1   @_ == 4 or croak 'usage: $smtp->auth( AUTH, USER, PASS )';
54 0           my ($me, $auth, $user, $pass) = @_;
55              
56             # code by James Fryman
57 0 0         if ($auth eq "NTLM") {
58              
59 0 0         eval "require Authen::NTLM"
60             or croak 'NTLM not supported. Install Authen::NTLM.';
61              
62 0           my $host = ${*$me}{'net_smtp_host'};
  0            
63 0           Authen::NTLM::ntlm_user($user); ## Init NTLM Variables
64 0           Authen::NTLM::ntlm_password($pass);
65 0           my $ntlm_chal = Authen::NTLM::ntlm();
66              
67 0           $me->_AUTH("$auth $ntlm_chal");
68              
69 0 0         if ( $me->code() == 334 ) {
70 0           my $chal = $me->message();
71 0           my $ntlm_chal_resp = Authen::NTLM::ntlm($chal);
72 0           $me->command($ntlm_chal_resp)->response();
73 0           Authen::NTLM::ntlm_reset();
74 0 0         return 1 if $me->code() == 235;
75 0 0         return if $me->code() == 535;
76             }
77 0           return;
78             }
79              
80 0           my $sasl = Authen::SASL->new(
81             mechanism => uc($auth),
82             callback => {
83             authname => $user,
84             user => $user,
85             pass => $pass,
86             },
87             );
88 0 0         return unless $sasl;
89 0           my $host = ${*$me}{'net_smtp_host'};
  0            
90 0           my $conn = $sasl->client_new("smtp", $host);#, "noplaintext noanonymous");
91              
92 0 0         $me->_AUTH($auth) or return;
93              
94 0 0         if ( $me->code() == 334 ) {
95              
96 0 0         if (my $initial = $conn->client_start)
97             {
98 0           $me->command(encode_base64($initial, ''))->response();
99 0 0         return 1 if $me->code() == 235;
100             }
101              
102 0           while ( $me->code() == 334 )
103             {
104 0           my $message = decode_base64($me->message());
105 0           my $return = $conn->client_step($message);
106 0           $me->command(encode_base64($return, ''))->response();
107 0 0         return 1 if $me->code() == 235;
108 0 0         return if $me->code() == 535;
109             }
110              
111             }
112             }
113              
114              
115 0     0     sub _AUTH { shift->command("AUTH", @_)->response() == CMD_MORE }
116              
117             1;
118              
119              
120             __END__