Perl Net :: SMTP强制身份验证方法

时间:2017-07-24 15:18:53

标签: perl email smtp

我尝试使用Perl Net::SMTP使用auth方法发送邮件,而不是默认选择的GSSAPI(例如强制PLAIN)。

我试过了:

my $smtp;
$smtp = Net::SMTP::SSL->new($host, Port => $port);
$smtp->auth($user, $passwd);

并将最后一行替换为:

$smtp->auth('PLAIN', $user, $passwd);

或将具有所选机制的Authen::SASL对象传递给$smtp->auth()。以上工作都没有 - 调试(和邮件服务器日志)说它仍然尝试AUTH GSSAPI

有谁知道如何在Net::SMTP中正确强制使用身份验证方法?

我的Perl版本是来自Debian 8的5.20.2-3 + deb8u8,包版本:

  • Net :: SMTP - 2.33
  • Net :: SMTP :: SSL - 1.01
  • Authen :: SASL - 2.16

2 个答案:

答案 0 :(得分:1)

Net :: SMTP版本高于3.00

Net::SMTP高于第3版:
*不会覆盖Authen::SASL方法的auth参数中的机制 *支持STARTTLS和smtps

use Net::SMTP;
use Authen::SASL;

my($host, $user, $pass) = ('...','...','...'); # fill correct data

my $smtp = Net::SMTP->new( $host, SSL=>1, Debug => 1 ); # SSL=>1 - use smtps
$smtp->auth(
  Authen::SASL->new(
    mechanism => 'PLAIN LOGIN',
    callback  => { user => $user, pass => $passwd }
  )
);

答案 1 :(得分:0)

Net :: SMTP版本低于3.00

Net::SMTP版本2.31_1(libnet中最新的3.00之前)使用Authen::SASL回复中列出的机制覆盖EHLO中的机制。请在下面找到我的 UGLY 修复程序。

use Net::SMTP::SSL;
use Authen::SASL;

my ( $host, $port, $user, $pass ) = ( '...', '...', '...', '...' );    # fill correct data

my $smtp = Net::SMTP::SSL->new( $host, Port => $port, Debug => 1 );
my $auth = Authen::SASL->new(
  mechanism => 'PLAIN LOGIN',
  callback  => { user => $user, pass => $passwd }
);
{
  no warnings 'redefine';
  my $count;
  local *Authen::SASL::mechanism = sub {
    my $self = shift;

    # Fix Begin
    # ignore first setting of mechanism
    if ( !$count++ && @_ && $Net::SMTP::VERSION =~ /^2\./ ) {
      return;
    }

    # Fix End
    @_
      ? $self->{mechanism} = shift
      : $self->{mechanism};
  };
  $smtp->auth($auth);
}

需要修复的代码 - Net::SMTP 2.31_1 from libnet 1.22_01

sub auth {
  my ($self, $username, $password) = @_;

  ...

  my $mechanisms = $self->supports('AUTH', 500, ["Command unknown: 'AUTH'"]);
  return unless defined $mechanisms;

  my $sasl;

  if (ref($username) and UNIVERSAL::isa($username, 'Authen::SASL')) {
    $sasl = $username;
    $sasl->mechanism($mechanisms); # <= HERE Authen::SASL mechanism overwrite 
  }