perl, exim and smtp auth (directadmin)

Discussion in 'Installation/Configuration' started by Reptile, Apr 10, 2008.

  1. Reptile

    Reptile New Member

    I run the following command in a perl script to SMPT auth and send an email. It works perfectly on a server I have with postfix but not Exim.
    $smtp = Net::SMTP->new('domain', Hello=>'', Debug=>1)
    	 or	die "Couldn't connect to server" unless $smtp;
       	if (!$smtp->auth($user, $pass)) {
      		print "authentication failed\n";
    This the debug from the Exim server

    Net::SMTP=GLOB(0x864a2c8)<<< 250-SIZE 20971520
    Net::SMTP=GLOB(0x864a2c8)<<< 250-PIPELINING
    Net::SMTP=GLOB(0x864a2c8)<<< 250-AUTH PLAIN LOGIN
    Net::SMTP=GLOB(0x864a2c8)<<< 250-STARTTLS
    Net::SMTP=GLOB(0x864a2c8)<<< 250 HELP
    Net::SMTP=GLOB(0x864a2c8)>>> AUTH PLAIN c210cEByZXB0aWxpYW5zaGFwZXNoaWZ0ZXIuY28udWsAc210cEByZXB0aWxpYW5zaGFwZXNoaWZ0ZXIuY28udWsAc210cDUwMzM=
    Net::SMTP=GLOB(0x864a2c8)<<< 535 Incorrect authentication data 
    It seems that it is maybe sending the user/pass encrypted but I cannot figure out how to solve this in the perl script. The auth method is supposed to figure it out for me?

    I tried add 'PLAIN' in the first parameter of the auth method but no go at all!

    Here is the debug for the working postfix server

    Net::SMTP=GLOB(0x864a388)<<< 250-PIPELINING
    Net::SMTP=GLOB(0x864a388)<<< 250-SIZE 10240000
    Net::SMTP=GLOB(0x864a388)<<< 250-VRFY
    Net::SMTP=GLOB(0x864a388)<<< 250-ETRN
    Net::SMTP=GLOB(0x864a388)<<< 250-AUTH LOGIN PLAIN
    Net::SMTP=GLOB(0x864a388)<<< 250-AUTH=LOGIN PLAIN
    Net::SMTP=GLOB(0x864a388)<<< 250 8BITMIME
    Net::SMTP=GLOB(0x864a388)>>> AUTH LOGIN
    Net::SMTP=GLOB(0x864a388)<<< 334 VXNlcm5hbWU6
    Net::SMTP=GLOB(0x864a388)>>> c210cEByZXB0aWxpYW5zaGFwZXNoaWZ0ZXIuY28udWs=
    Net::SMTP=GLOB(0x864a388)<<< 334 UGFzc3dvcmQ6
    Net::SMTP=GLOB(0x864a388)>>> c210cDUwMzM=
    Net::SMTP=GLOB(0x864a388)<<< 235 Authentication successful 
    I tried, very unsuccessfully, to use PAM in exim to authenticate but it just kept bouncing the password box back.
    Last edited: Apr 10, 2008
  2. topdog

    topdog Active Member HowtoForge Supporter

  3. Reptile

    Reptile New Member

    It is set like this

        driver = plaintext
        public_name = PLAIN
        server_prompts = :
        server_condition = "${perl{smtpauth}}"
        server_set_id = $2
        driver = plaintext
        public_name = LOGIN
        server_prompts = "Username:: : Password::"
        server_condition = "${perl{smtpauth}}"
        server_set_id = $1
    The default DirectAdmin config.
  4. topdog

    topdog Active Member HowtoForge Supporter

    Provide the perl script called smtpauth lets see what it does.
  5. Reptile

    Reptile New Member

    I cannot locate "smtpauth" on the server. I presume you are referencing this from the exim config? The SMTP works in thunderbird so i can, at least , confirm that it works.

    Here is perl module for the smtp auth in my script-


    # alex pleiner 2001, 2003, 2006 zeitform Internet Dienste
    # thanks to Graham Barr <[email protected]> for Net::SMTP
    # This program is free software; you can redistribute it and/or
    # modify it under the same terms as Perl itself.
    # Net::SMTP_auth is a small extension to G. Barr's Net::SMTP
    # to authenticate to an SMTP server using one of the AUTH
    # methods provided by Authen::SASL and Authen::NTLM (see RFC2554 for details).
    # This module can be expanded and is a very first implementation.
    package Net::SMTP_auth;
    require 5.001;
    use strict;
    use vars qw($VERSION @ISA);
    use Socket 1.3;
    use Carp;
    use IO::Socket;
    use Net::Cmd;
    use Net::Config;
    use Net::SMTP;
    use MIME::Base64;
    use Digest::HMAC_MD5 qw(hmac_md5_hex);
    use Authen::SASL;
    $VERSION = "0.08";
    @ISA = qw(Net::SMTP);
    # all other method taken from Net::SMTP
    sub auth_types {
      @_ == 1 or croak 'usage: $pop3->auth_types()';
      my $me = shift;
      if (exists ${*$me}{'net_smtp_esmtp'}) {
        my $esmtp = ${*$me}{'net_smtp_esmtp'};
        if(exists $esmtp->{AUTH}) {
          return wantarray ? split(/\s+/, $esmtp->{AUTH}) : $esmtp->{AUTH};
    sub auth {
      @_ == 4 or croak 'usage: $smtp->auth( AUTH, USER, PASS )';
      my ($me, $auth, $user, $pass) = @_;
      # code by James Fryman
      if ($auth eq "NTLM") {
        eval "require Authen::NTLM"
          or croak 'NTLM not supported. Install Authen::NTLM.';
        my $host = ${*$me}{'net_smtp_host'};
        Authen::NTLM::ntlm_user($user);    ## Init NTLM Variables
        my $ntlm_chal = Authen::NTLM::ntlm();
        $me->_AUTH("$auth $ntlm_chal");
        if ( $me->code() == 334 ) {
          my $chal = $me->message();
          my $ntlm_chal_resp = Authen::NTLM::ntlm($chal);
          return 1 if $me->code() == 235;
          return   if $me->code() == 535;
      my $sasl = Authen::SASL->new(
    			       mechanism => uc($auth),
    			       callback => {
    					    authname => $user,
    					    user     => $user,
    					    pass     => $pass,
      return unless $sasl;
      my $host = ${*$me}{'net_smtp_host'};
      my $conn = $sasl->client_new("smtp", $host);#, "noplaintext noanonymous");
      $me->_AUTH($auth) or return;
      if ( $me->code() == 334 ) {
        if (my $initial = $conn->client_start)
    	$me->command(encode_base64($initial, ''))->response();
    	return 1 if $me->code() == 235;
        while ( $me->code() == 334 )
    	my $message = decode_base64($me->message());
    	my $return = $conn->client_step($message);
    	$me->command(encode_base64($return, ''))->response();
    	return 1 if $me->code() == 235;
    	return   if $me->code() == 535;
    sub _AUTH { shift->command("AUTH", @_)->response()  == CMD_MORE }
    =head1 NAME
    Net::SMTP_auth - Simple Mail Transfer Protocol Client with AUTHentication
    =head1 SYNOPSIS
        use Net::SMTP_auth;
        # Constructors
        $smtp = Net::SMTP_auth->new('mailhost');
        $smtp = Net::SMTP_auth->new('mailhost', Timeout => 60);
    =head1 DESCRIPTION
    This module implements a client interface to the SMTP and ESMTP
    protocol AUTH service extension, enabling a perl5 application to talk
    to and authenticate against SMTP servers. This documentation assumes
    that you are familiar with the concepts of the SMTP protocol described
    in RFC821 and with the AUTH service extension described in RFC2554.
    A new Net::SMTP_auth object must be created with the I<new> method. Once
    this has been done, all SMTP commands are accessed through this object.
    The Net::SMTP_auth class is a subclass of Net::SMTP, which itself is
    a subclass of Net::Cmd and IO::Socket::INET.
    =head1 EXAMPLES
    This example authenticates via CRAM-MD5 and sends a small message to
    the postmaster at the SMTP server known as mailhost:
        #!/usr/bin/perl -w
        use Net::SMTP_auth;
        $smtp = Net::SMTP_auth->new('mailhost');
        $smtp->auth('CRAM-MD5', 'user', 'password');
        $smtp->datasend("To: postmaster\n");
        $smtp->datasend("A simple test message\n");
    =head1 CONSTRUCTOR
    =over 4
    =item new Net::SMTP_auth [ HOST, ] [ OPTIONS ]
    This is the constructor for a new Net::SMTP_auth object. It is
    taken from Net::SMTP as all other methods (except I<auth> and
    I<auth_types>) are, too.
    =head1 METHODS
    Unless otherwise stated all methods return either a I<true> or I<false>
    value, with I<true> meaning that the operation was a success. When a method
    states that it returns a value, failure will be returned as I<undef> or an
    empty list.
    =over 4
    =item auth_types ()
    Returns the AUTH methods supported by the server as an array or in a
    space separated string. This string is exacly the line given by the SMTP
    server after the C<EHLO> command containing the keyword C<AUTH>.
    =item auth ( AUTH, USER, PASSWORD )
    Authenticates the user C<USER> via the authentication method C<AUTH>
    and the password C<PASSWORD>. Returns I<true> if successful and I<false>
    if the authentication failed. Remember that the connection is not closed
    if the authentication fails. You may issue a different authentication
    attempt. If you once are successfully authenticated, you cannot send
    the C<AUTH> command again. 
    The C<AUTH> method C<NTLM> is supported via Authen::NTLM (thanks to James Fryman).
    =head1 SEE ALSO
    L<Net::SMTP> and L<Net::Cmd>
    =head1 AUTHOR
    Alex Pleiner <[email protected]>, zeitform Internet Dienste.
    Thanks to Graham Barr <[email protected]> for Net::SMTP.
    NTLM authentication code provided by James Fryman <[email protected]>
    =head1 COPYRIGHT
    Copyright (c) 2001, 2003, 2006 zeitform Internet Dienste. All rights reserved.
    This program is free software; you can redistribute it and/or modify
    it under the same terms as Perl itself.
    Last edited: Apr 10, 2008
  6. topdog

    topdog Active Member HowtoForge Supporter

    I am talking about the one that is being referenced from the exim configuration.

    If it does not exist then that could be the problem, what does exim log when you make the connection to it to authenticate.

    Anyway why don't you through away that configuration and use one of those that i posted which we know work.

    Otherwise by best bet is you talking to the directadmin guys and ask them how their perl setup works
  7. Reptile

    Reptile New Member

    Well, like I said, thunderbird sends mail through it no problem. I can try one of those configs as long as it's not going to break my virtual mailboxes. I already tried replacing those lines in exim with the saslauth and it doesn't work. It doesn't even try to authenticate.

    It is trying to authenticate now but the login looks scrambled to me , which is why it rejects it. My perl script doesnt appear to be sending the user/pass in plain text.

    I have already contacted them and they cannot help and said that the perl script stuff is out of his area of expertise.

    To be honest, ever since I went to DA to "save time", and stopped configuring my servers manually i've had nothing but extra work to solve.

  8. topdog

    topdog Active Member HowtoForge Supporter

    Sorry i did not see the part why thunderbird works. So it means your smtp auth actually works
  9. Reptile

    Reptile New Member

    Yeah, but something in smtp->auth is not happening properly, so it's refusing to authenticate on this server.

    I think it's crypting the user/pass somehow.
  10. topdog

    topdog Active Member HowtoForge Supporter

    Okay i think this will work

    $smtp = Net::SMTP->new('domain', Hello=>'', Debug=>1)
    	 or	die "Couldn't connect to server" unless $smtp;
       	if (!$smtp->auth('LOGIN',$user, $pass)) {
      		print "authentication failed\n";
  11. Reptile

    Reptile New Member

    unfortunately, not.

    I already tried that plus "PLAIN". And even the other ones just to be sure.
  12. topdog

    topdog Active Member HowtoForge Supporter

  13. Reptile

    Reptile New Member

    I tried that library but it didn't work either.

    Do i have to enable something in the exim conf to enable TLS?
  14. topdog

    topdog Active Member HowtoForge Supporter

    You already have it thats why you can see START-TLS it worked for me
  15. Reptile

    Reptile New Member

    well I played with it yesterday, and unfortunately it didn't work and it has no debug method either, so I couldn't trouble shoot it.

    Did you try it with a DA server?
  16. weldan

    weldan New Member

    have you checked /etc/

Share This Page