[PATCH] fixed failing auths to auth/vpopmaild, added tests

[email protected] (Matt Simerson)
Newsgroups perl.qpsmtpd
Message-ID <[email protected]>
Available on github: https://github.com/msimerson/qpsmtpd/commit/ed8eca0a630be3a100840a247f7a8305bfae15c4


Apparently the format of vpopmaild responses has been expanded and the responses
are conditional.

* Replaced the 'sometimes works' eq comparison with a regexp that always works.
* added tests for all 3 vpopmail plugins
* added cram-md5 auth support to auth_vpopmaild.
---
MANIFEST                              |    3 +++
plugins/auth/auth_vpopmail            |    6 ++++-
plugins/auth/auth_vpopmaild           |   45 ++++++++++++++++++---------------
t/plugin_tests/auth/auth_vpopmail     |   27 ++++++++++++++++++++
t/plugin_tests/auth/auth_vpopmail_sql |   27 ++++++++++++++++++++
t/plugin_tests/auth/auth_vpopmaild    |   27 ++++++++++++++++++++
6 files changed, 113 insertions(+), 22 deletions(-)
create mode 100644 t/plugin_tests/auth/auth_vpopmail
create mode 100644 t/plugin_tests/auth/auth_vpopmail_sql
create mode 100644 t/plugin_tests/auth/auth_vpopmaild

diff --git a/MANIFEST b/MANIFEST
index 59c9260..e4a9e0b 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -145,6 +145,9 @@ t/helo.t
t/misc.t
t/plugin_tests.t
t/plugin_tests/auth/auth_flat_file
+t/plugin_tests/auth/auth_vpopmail
+t/plugin_tests/auth/auth_vpopmail_sql
+t/plugin_tests/auth/auth_vpopmaild
t/plugin_tests/auth/authdeny
t/plugin_tests/auth/authnull
t/plugin_tests/check_badrcptto
diff --git a/plugins/auth/auth_vpopmail b/plugins/auth/auth_vpopmail
index 973d230..91cf863 100644
--- a/plugins/auth/auth_vpopmail
+++ b/plugins/auth/auth_vpopmail
@@ -105,7 +105,11 @@ sub test_vpopmail {

# vpopmail will not allow vauth_getpw to succeed unless the requesting user is vpopmail or root.
# by default, qpsmtpd runs as the user 'qpsmtpd' and does not have permission.
-    use vpopmail;
+    eval "use vpopmail";
+    if ( $@ ) {
+        warn "vpopmail perl module not installed.\n";
+        return;
+    };
    my ($domain) = vpopmail::vlistdomains();
    my $r = vauth_getpw('postmaster', $domain);
    return if !$r;
diff --git a/plugins/auth/auth_vpopmaild b/plugins/auth/auth_vpopmaild
index d30eaed..b25b35b 100644
--- a/plugins/auth/auth_vpopmaild
+++ b/plugins/auth/auth_vpopmaild
@@ -1,30 +1,26 @@
-#!/usr/bin/env perl
+#!/usr/bin/perl

use strict;
use warnings;
use IO::Socket;
-use version; my $VERSION = qv('1.0.0');
+use version; 
+my $VERSION = qv('1.0.1');

sub register {
    my ($self, $qp, %args) = @_;

-    my %DEFAULT = (
-                   host => q{localhost},
-                   port => 89,
-                  );
-
-    $self->{_vpopmaild_host} =
-      defined $args{host} ? $args{host} : $DEFAULT{host};
-    $self->{_vpopmaild_port} =
-      defined $args{port} ? $args{port} : $DEFAULT{port};
+    $self->{_vpopmaild_host} = $args{host} || 'localhost';
+    $self->{_vpopmaild_port} = $args{port} || '89';

    $self->register_hook('auth-plain', 'auth_vpopmaild');
    $self->register_hook('auth-login', 'auth_vpopmaild');
+    $self->register_hook('auth-cram-md5', 'auth_vpopmaild');
}

sub auth_vpopmaild {
-    my ($self, $transaction, $method, $user, $passClear, $passHash, $ticket) =
-      @_;
+    my ($self, $transaction, $method, $user, $passClear, $passHash, $ticket) = @_;
+
+    use Qpsmtpd::Constants;

    # create socket
    my $vpopmaild_socket =
@@ -35,9 +31,15 @@ sub auth_vpopmaild {
                            Type     => SOCK_STREAM
                           ) or return DECLINED;

+    #$self->log(LOGINFO, "Attempting $method auth via vpopmaild");
+
    # Get server greeting (+OK)
    my $connect_response = <$vpopmaild_socket>;
-    return DECLINED unless $connect_response eq '+OK \r\n';
+    if ( $connect_response !~ /^\+OK/ ) {
+        $self->log(LOGINFO, "Failed to receive vpopmaild connection response: $connect_response");
+        close($vpopmaild_socket);
+        return DECLINED;
+    };

    # send login details
    print $vpopmaild_socket "login $user $passClear\n\r";
@@ -47,13 +49,12 @@ sub auth_vpopmaild {

    close($vpopmaild_socket);

-    # check for successful login
-    if ($login_response eq '+OK+\r\n') {
-        return (OK, 'authcheckpassword');
-    }
-    else {
-        return DECLINED;
-    }
+    # check for successful login (single line (+OK) or multiline (+OK+))
+    return (OK, 'auth_vpopmaild') if $login_response =~ /^\+OK/;
+
+    $self->log(LOGINFO, "Failed vpopmaild authentication response: $login_response");
+
+    return DECLINED;
}

__END__
@@ -90,6 +91,8 @@ please read the VPOPMAIL section in doc/authentication.pod

Robin Bowes <[email protected]>

+Matt Simerson (4/2012: added CRAM-MD5 support, updated response parsing)
+
=head1 COPYRIGHT AND LICENSE

Copyright (c) 2010 Robin Bowes
diff --git a/t/plugin_tests/auth/auth_vpopmail b/t/plugin_tests/auth/auth_vpopmail
new file mode 100644
index 0000000..aefa3fd
--- /dev/null
+++ b/t/plugin_tests/auth/auth_vpopmail
@@ -0,0 +1,27 @@
+# -*-perl-*- [emacs]
+
+sub register_tests {
+    my $self = shift;
+    $self->register_test("test_auth_vpopmail", 3);
+}
+
+my @u_list = qw ( good bad none );
+my %u_data = (
+	      good => [ '[email protected]', OK, 'Good Strong Passphrase' ],
+	      bad => [ '[email protected]', DENY, 'not_bad_pass' ],
+	      none => [ '[email protected]', DECLINED, '' ],
+	      );
+
+sub test_auth_vpopmail {
+    my $self = shift;
+    my ($tran, $ret, $note, $u, $r, $p, $a );
+    $tran = $self->qp->transaction;
+    for $u ( @u_list ) {
+	( $a,$r,$p ) = @{$u_data{$u}};
+	($ret, $note) = $self->auth_vpopmail($tran,'CRAMMD5',$a,$p);
+	defined $note or $note='auth_vpopmail: No-Message';
+	is ($ret, $r, $note);
+	# - for debugging.
+	# warn "$note\n";
+    }
+}
diff --git a/t/plugin_tests/auth/auth_vpopmail_sql b/t/plugin_tests/auth/auth_vpopmail_sql
new file mode 100644
index 0000000..a95523a
--- /dev/null
+++ b/t/plugin_tests/auth/auth_vpopmail_sql
@@ -0,0 +1,27 @@
+# -*-perl-*- [emacs]
+
+sub register_tests {
+    my $self = shift;
+    $self->register_test("auth_vpopmail_sql", 3);
+}
+
+my @u_list = qw ( good bad none );
+my %u_data = (
+	      good => [ '[email protected]', OK, 'Good Strong Passphrase' ],
+	      bad  => [ '[email protected]',   DENY, 'not_bad_pass' ],
+	      none => [ '[email protected]', DECLINED, '' ],
+	      );
+
+sub auth_vpopmail_sql {
+    my $self = shift;
+    my ($tran, $ret, $note, $u, $r, $p, $a );
+    $tran = $self->qp->transaction;
+    for $u ( @u_list ) {
+	( $a,$r,$p ) = @{$u_data{$u}};
+	eval { ($ret, $note) = $self->auth_vmysql($tran,'PLAIN',$a,$p); };
+	defined $note or $note='auth_vpopmail_sql: No-Message';
+	is ($ret, $r, $note);
+	# - for debugging.
+	# warn "$note\n";
+    }
+}
diff --git a/t/plugin_tests/auth/auth_vpopmaild b/t/plugin_tests/auth/auth_vpopmaild
new file mode 100644
index 0000000..e36e9a4
--- /dev/null
+++ b/t/plugin_tests/auth/auth_vpopmaild
@@ -0,0 +1,27 @@
+# -*-perl-*- [emacs]
+
+warn "loaded test auth_vpopmaild\n";
+
+sub register_tests {
+    my $self = shift;
+    $self->register_test("test_auth_vpopmaild", 3);
+}
+
+my @u_list = qw ( good bad none );
+my %u_data = (
+	      good => [ '[email protected]', OK, 'Good Strong Passphrase' ],
+	      bad => [ '[email protected]', DENY, 'not_bad_pass' ],
+	      none => [ '[email protected]', DECLINED, '' ],
+	      );
+
+sub test_auth_vpopmaild {
+    my $self = shift;
+    my ($tran, $ret, $note, $u, $r, $p, $a );
+    $tran = $self->qp->transaction;
+    for $u ( @u_list ) {
+	( $a,$r,$p ) = @{$u_data{$u}};
+	($ret, $note) = $self->auth_vpopmaild($tran,'LOGIN',$a,$p);
+	defined $note or $note='No-Message';
+	is ($ret, $r, $note);
+    }
+}
-- 
1.7.9.4
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.