Skip Menu |

This queue is for tickets about the libnet CPAN distribution.

Report information
The Basics
Id: 99415
Status: resolved
Priority: 0/
Queue: libnet

People
Owner: Nobody in particular
Requestors: potatogim [...] potatogim.net
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 3.01
Fixed in: (no value)



Subject: Authenticate with Authen::SASL
Name and Version : Net-SMTP-3.01 Perl Version : 5.10.1 OS : CentOS 6.5 Hi, I'm using Net-SMTP with Authen::SASL to send a mail. but I have met one is a strange result. <code> my $smtp = Net::SMTP->new ( Host => 'mail.host.com', Port => 25, Debug => 1, ); my $user = 'potatogim@host.com'; my $pass = 'password'; my $sasl = Authen::SASL->new ( mechanism => 'LOGIN', callback => { user => $user, pass => $pass, authname => $user, } ); $smtp->auth ($sasl) or die "Failed to authenticate."; $smtp->mail ($user); if ($smtp->recipient ($user)) { $smtp->data (); $smtp->datasend ("To: potatogim\@host.com\n"); $smtp->datasend ("Subject: SMTP Test"); $smtp->datasend ("\n"); $smtp->datasend ("A simple test message\n"); $smtp->dataend (); } $smtp->quit(); </code> the code above works as below... <console> Net::SMTP>>> Net::SMTP(3.01) Net::SMTP>>> Net::Cmd(3.01) Net::SMTP>>> Exporter(5.70) Net::SMTP>>> IO::Socket::INET(1.31) Net::SMTP>>> IO::Socket(1.31) Net::SMTP>>> IO::Handle(1.28) Net::SMTP=GLOB(0x164d498)<<< 220 MailHost (mail.host.com) ESMTP Net::SMTP=GLOB(0x164d498)>>> EHLO localhost.localdomain Net::SMTP=GLOB(0x164d498)<<< 250-MailHost (mail.host.com) Net::SMTP=GLOB(0x164d498)<<< 250-STARTTLS Net::SMTP=GLOB(0x164d498)<<< 250-AUTH LOGIN CRAM-MD5 PLAIN Net::SMTP=GLOB(0x164d498)<<< 250-AUTH=LOGIN CRAM-MD5 PLAIN Net::SMTP=GLOB(0x164d498)<<< 250-PIPELINING Net::SMTP=GLOB(0x164d498)<<< 250 8BITMIME Net::SMTP=GLOB(0x164d498)>>> AUTH CRAM-MD5 Net::SMTP=GLOB(0x164d498)<<< 334 MjA1OS4xNDEyOTQzMTI4QHNwYAS4aWx01XI09m1hZWxuYXJhLmNvLmtyClo+ Net::SMTP=GLOB(0x164d498)>>> cG90YXRvZ2ltQGdsdWVzeXMuY2atID7kZWajNWWlNGNiNWY2MzZkNWIwNzYxNDBmMDlmZTM4 Net::SMTP=GLOB(0x164d498)<<< 535 authorization failed (#5.7.0) </console> I thought perhaps this code will try to authenticate with "AUTH LOGIN" method. but, my Authen::SASL instance's->mechanism is overwritten by below code. <code> 186 my $client; 187 my $str; 188 189 do { 190 if ($client) { 191 # $client mechanism failed, so we need to exclude this mechanism from list 192 my $failed_mechanism = $client->mechanism; 193 $self->debug_text("Auth mechanism failed: $failed_mechanism") 194 if $self->debug; 195 $mechanisms =~ s/\b\Q$failed_mechanism\E\b//; 196 last unless $mechanisms =~ /\S/; 197 } 198 199 $sasl->mechanism($mechanisms); 200 201 # We should probably allow the user to pass the host, but I don't 202 # currently know and SASL mechanisms that are used by smtp that need it 203 204 $client = $sasl->client_new('smtp', ${*$self}{'net_smtp_host'}, 0); 205 $str = $client->client_start; 206 } while (!defined $str); </code> hmm.... If this result is correct, could you tell me what am I doing wrong?
On Fri Oct 10 08:25:30 2014, potatogim@potatogim.net wrote: [...] Show quoted text
> > I thought perhaps this code will try to authenticate with "AUTH LOGIN" > method.
Yes, I think it should. Show quoted text
> > but, my Authen::SASL instance's->mechanism is overwritten by below > code. > > <code> > 186 my $client; > 187 my $str; > 188 > 189 do { > 190 if ($client) { > 191 # $client mechanism failed, so we need to exclude this > mechanism from list > 192 my $failed_mechanism = $client->mechanism; > 193 $self->debug_text("Auth mechanism failed: > $failed_mechanism") > 194 if $self->debug; > 195 $mechanisms =~ s/\b\Q$failed_mechanism\E\b//; > 196 last unless $mechanisms =~ /\S/; > 197 } > 198 > 199 $sasl->mechanism($mechanisms); > 200 > 201 # We should probably allow the user to pass the host, but I > don't > 202 # currently know and SASL mechanisms that are used by smtp > that need it > 203 > 204 $client = $sasl->client_new('smtp', > ${*$self}{'net_smtp_host'}, 0); > 205 $str = $client->client_start; > 206 } while (!defined $str); > </code> > > hmm.... > > If this result is correct, could you tell me what am I doing wrong?
I think there's a bug in the code above. If you move the overwriting of the mechanisms *inside* the if-block which modifies the list of remaining mechanisms to try when the previous attempt has failed, does it work then? I.e.: my $client; my $str; do { if ($client) { # $client mechanism failed, so we need to exclude this mechanism from list my $failed_mechanism = $client->mechanism; $self->debug_text("Auth mechanism failed: $failed_mechanism") if $self->debug; $mechanisms =~ s/\b\Q$failed_mechanism\E\b//; last unless $mechanisms =~ /\S/; $sasl->mechanism($mechanisms); } # We should probably allow the user to pass the host, but I don't # currently know and SASL mechanisms that are used by smtp that need it $client = $sasl->client_new('smtp', ${*$self}{'net_smtp_host'}, 0); $str = $client->client_start; } while (!defined $str); (In the original, the list of mechanisms is *always* overwritten, even on the first attempt--before the chosen one specified in the given Authen::SASL object has been tried!)
From: potatogim [...] potatogim.net
On Fri Oct 10 13:19:25 2014, SHAY wrote: Show quoted text
> On Fri Oct 10 08:25:30 2014, potatogim@potatogim.net wrote: > [...]
> > > > I thought perhaps this code will try to authenticate with "AUTH > > LOGIN" > > method.
> > Yes, I think it should. > >
> > > > but, my Authen::SASL instance's->mechanism is overwritten by below > > code. > > > > <code> > > 186 my $client; > > 187 my $str; > > 188 > > 189 do { > > 190 if ($client) { > > 191 # $client mechanism failed, so we need to exclude this > > mechanism from list > > 192 my $failed_mechanism = $client->mechanism; > > 193 $self->debug_text("Auth mechanism failed: > > $failed_mechanism") > > 194 if $self->debug; > > 195 $mechanisms =~ s/\b\Q$failed_mechanism\E\b//; > > 196 last unless $mechanisms =~ /\S/; > > 197 } > > 198 > > 199 $sasl->mechanism($mechanisms); > > 200 > > 201 # We should probably allow the user to pass the host, but I > > don't > > 202 # currently know and SASL mechanisms that are used by smtp > > that need it > > 203 > > 204 $client = $sasl->client_new('smtp', > > ${*$self}{'net_smtp_host'}, 0); > > 205 $str = $client->client_start; > > 206 } while (!defined $str); > > </code> > > > > hmm.... > > > > If this result is correct, could you tell me what am I doing wrong?
> > I think there's a bug in the code above. If you move the overwriting > of the mechanisms *inside* the if-block which modifies the list of > remaining mechanisms to try when the previous attempt has failed, does > it work then? I.e.: > > my $client; > my $str; > do { > if ($client) { > # $client mechanism failed, so we need to exclude this mechanism > from list > my $failed_mechanism = $client->mechanism; > $self->debug_text("Auth mechanism failed: $failed_mechanism") > if $self->debug; > $mechanisms =~ s/\b\Q$failed_mechanism\E\b//; > last unless $mechanisms =~ /\S/; > $sasl->mechanism($mechanisms); > } > > # We should probably allow the user to pass the host, but I don't > # currently know and SASL mechanisms that are used by smtp that need > it > > $client = $sasl->client_new('smtp', ${*$self}{'net_smtp_host'}, 0); > $str = $client->client_start; > } while (!defined $str); > > (In the original, the list of mechanisms is *always* overwritten, even > on the first attempt--before the chosen one specified in the given > Authen::SASL object has been tried!)
As you had predicated, my test code is working correctly after edit!
On Fri Oct 10 14:20:28 2014, potatogim@potatogim.net wrote: Show quoted text
> On Fri Oct 10 13:19:25 2014, SHAY wrote:
> > On Fri Oct 10 08:25:30 2014, potatogim@potatogim.net wrote: > > [...]
> > > > > > I thought perhaps this code will try to authenticate with "AUTH > > > LOGIN" > > > method.
> > > > Yes, I think it should. > > > >
> > > > > > but, my Authen::SASL instance's->mechanism is overwritten by below > > > code. > > > > > > <code> > > > 186 my $client; > > > 187 my $str; > > > 188 > > > 189 do { > > > 190 if ($client) { > > > 191 # $client mechanism failed, so we need to exclude this > > > mechanism from list > > > 192 my $failed_mechanism = $client->mechanism; > > > 193 $self->debug_text("Auth mechanism failed: > > > $failed_mechanism") > > > 194 if $self->debug; > > > 195 $mechanisms =~ s/\b\Q$failed_mechanism\E\b//; > > > 196 last unless $mechanisms =~ /\S/; > > > 197 } > > > 198 > > > 199 $sasl->mechanism($mechanisms); > > > 200 > > > 201 # We should probably allow the user to pass the host, but I > > > don't > > > 202 # currently know and SASL mechanisms that are used by smtp > > > that need it > > > 203 > > > 204 $client = $sasl->client_new('smtp', > > > ${*$self}{'net_smtp_host'}, 0); > > > 205 $str = $client->client_start; > > > 206 } while (!defined $str); > > > </code> > > > > > > hmm.... > > > > > > If this result is correct, could you tell me what am I doing wrong?
> > > > I think there's a bug in the code above. If you move the overwriting > > of the mechanisms *inside* the if-block which modifies the list of > > remaining mechanisms to try when the previous attempt has failed, does > > it work then? I.e.: > > > > my $client; > > my $str; > > do { > > if ($client) { > > # $client mechanism failed, so we need to exclude this mechanism > > from list > > my $failed_mechanism = $client->mechanism; > > $self->debug_text("Auth mechanism failed: $failed_mechanism") > > if $self->debug; > > $mechanisms =~ s/\b\Q$failed_mechanism\E\b//; > > last unless $mechanisms =~ /\S/; > > $sasl->mechanism($mechanisms); > > } > > > > # We should probably allow the user to pass the host, but I don't > > # currently know and SASL mechanisms that are used by smtp that need > > it > > > > $client = $sasl->client_new('smtp', ${*$self}{'net_smtp_host'}, 0); > > $str = $client->client_start; > > } while (!defined $str); > > > > (In the original, the list of mechanisms is *always* overwritten, even > > on the first attempt--before the chosen one specified in the given > > Authen::SASL object has been tried!)
> > > As you had predicated, my test code is working correctly after edit!
Thanks for testing (and for the bug report). This is now fixed in my repo: https://github.com/steve-m-hay/perl-libnet/commit/2c160b441ccc609bf4397ad7dd783c68b8cac4c2 and will be released soon in v3.02.