1 |
slords |
1.1 |
From 0ae24edc55804c4749a9da880ec45050bead629e Mon Sep 17 00:00:00 2001 |
2 |
|
|
From: Matt Simerson <matt@tnpi.net> |
3 |
|
|
Date: Mon, 10 May 2010 19:13:15 -0400 |
4 |
|
|
Subject: updates to auth_vpopmail_sql module |
5 |
|
|
|
6 |
|
|
updates to auth_vpopmail_sql module |
7 |
|
|
- moved vpopmail database parameters into config files |
8 |
|
|
- added LIMITATIONS section to POD, noting no support for alias domains |
9 |
|
|
- renamed sub from authsql (too generic) to auth_vmysql |
10 |
|
|
|
11 |
|
|
Signed-off-by: Robert <rspier@pobox.com> |
12 |
|
|
--- |
13 |
|
|
plugins/auth/auth_vpopmail_sql | 73 +++++++++++++++++++++++---------------- |
14 |
|
|
1 files changed, 43 insertions(+), 30 deletions(-) |
15 |
|
|
|
16 |
|
|
diff --git a/plugins/auth/auth_vpopmail_sql b/plugins/auth/auth_vpopmail_sql |
17 |
|
|
index 7c8626d..fd450d0 100644 |
18 |
|
|
--- a/plugins/auth/auth_vpopmail_sql |
19 |
|
|
+++ b/plugins/auth/auth_vpopmail_sql |
20 |
|
|
@@ -15,18 +15,34 @@ to compare the crypted password. |
21 |
|
|
|
22 |
|
|
=head1 CONFIGURATION |
23 |
|
|
|
24 |
|
|
-Decide which authentication methods you are willing to support and uncomment |
25 |
|
|
+ echo "dbi:mysql:dbname=vpopmail;host=127.0.0.1" > config/vpopmail_mysql_dsn |
26 |
|
|
+ echo "vpopmailuser" > config/vpopmail_mysql_user |
27 |
|
|
+ echo "vpoppasswd" > config/vpopmail_mysql_pass |
28 |
|
|
+ |
29 |
|
|
+This can be a read-only database user since the plugin does not update the |
30 |
|
|
+last accessed time (yet, see below). |
31 |
|
|
+ |
32 |
|
|
+This module supports PLAIN, LOGIN, and CRAM-MD5 authentication methods. You |
33 |
|
|
+can disable undesired methods by editing this module and uncommenting |
34 |
|
|
the lines in the register() sub. See the POD for Qspmtpd::Auth for more |
35 |
|
|
details on the ramifications of supporting various authentication methods. |
36 |
|
|
-Then, change the database information at the top of the authsql() sub so that |
37 |
|
|
-the module can access the database. This can be a read-only account since |
38 |
|
|
-the plugin does not update the last accessed time (yet, see below). |
39 |
|
|
|
40 |
|
|
The remote user must login with a fully qualified e-mail address (i.e. both |
41 |
|
|
-account name and domain), even if they don't normally need to. This is |
42 |
|
|
+account name and domain), even if they don't normally need to. This is |
43 |
|
|
because the vpopmail table has a unique index on pw_name/pw_domain, and this |
44 |
|
|
module requires that only a single record be returned from the database. |
45 |
|
|
|
46 |
|
|
+=head1 LIMITATIONS |
47 |
|
|
+ |
48 |
|
|
+This authentication modules does not recognize domain aliases. So, if you have |
49 |
|
|
+the domain example.com, with domain aliases for example.org and example.net, |
50 |
|
|
+smtp-auth will only work for $user@example.com. If you have domain aliases, |
51 |
|
|
+consider using the auth_checkpassword plugin. |
52 |
|
|
+ |
53 |
|
|
+The checkpassword plugin only supports plain and login authentications, where |
54 |
|
|
+this plugin also supports CRAM-MD5. I use both modules together. I use this one |
55 |
|
|
+for CRAM-MD5 and the checkpassword plugin for plain and login. |
56 |
|
|
+ |
57 |
|
|
=head1 FUTURE DIRECTION |
58 |
|
|
|
59 |
|
|
The default MySQL configuration for vpopmail includes a table to log access, |
60 |
|
|
@@ -50,41 +66,38 @@ Please see the LICENSE file included with qpsmtpd for details. |
61 |
|
|
sub register { |
62 |
|
|
my ( $self, $qp ) = @_; |
63 |
|
|
|
64 |
|
|
- $self->register_hook("auth-plain", "authsql" ); |
65 |
|
|
- $self->register_hook("auth-login", "authsql" ); |
66 |
|
|
- $self->register_hook("auth-cram-md5", "authsql"); |
67 |
|
|
- |
68 |
|
|
+ $self->register_hook("auth-plain", "auth_vmysql" ); |
69 |
|
|
+ $self->register_hook("auth-login", "auth_vmysql" ); |
70 |
|
|
+ $self->register_hook("auth-cram-md5", "auth_vmysql"); |
71 |
|
|
} |
72 |
|
|
|
73 |
|
|
-sub authsql { |
74 |
|
|
+sub auth_vmysql { |
75 |
|
|
+ my ( $self, $transaction, $method, $user, $passClear, $passHash, $ticket ) = @_; |
76 |
|
|
+ |
77 |
|
|
use DBI; |
78 |
|
|
use Qpsmtpd::Constants; |
79 |
|
|
use Digest::HMAC_MD5 qw(hmac_md5_hex); |
80 |
|
|
|
81 |
|
|
# $DB::single = 1; |
82 |
|
|
|
83 |
|
|
- my $connect = "dbi:mysql:dbname=vpopmail"; |
84 |
|
|
- my $dbuser = "vpopmailuser"; |
85 |
|
|
- my $dbpasswd = "vpoppasswd"; |
86 |
|
|
+ my $dsn = $self->qp->config("vpopmail_mysql_dsn") || "dbi:mysql:dbname=vpopmail;host=127.0.0.1"; |
87 |
|
|
+ my $dbuser = $self->qp->config("vpopmail_mysql_user") || "vpopmailuser"; |
88 |
|
|
+ my $dbpass = $self->qp->config("vpopmail_mysql_pass") || "vpoppasswd"; |
89 |
|
|
|
90 |
|
|
- my $dbh = DBI->connect( $connect, $dbuser, $dbpasswd ); |
91 |
|
|
+ my $dbh = DBI->connect( $dsn, $dbuser, $dbpass ); |
92 |
|
|
$dbh->{ShowErrorStatement} = 1; |
93 |
|
|
|
94 |
|
|
- my ( $self, $transaction, $method, $user, $passClear, $passHash, $ticket ) = |
95 |
|
|
- @_; |
96 |
|
|
- my ( $pw_name, $pw_domain ) = split "@", lc($user); |
97 |
|
|
+ my ( $pw_name, $pw_domain ) = split '@', lc($user); |
98 |
|
|
|
99 |
|
|
- unless ( defined $pw_domain ) { |
100 |
|
|
- return DECLINED; |
101 |
|
|
- } |
102 |
|
|
+ return DECLINED if ! defined $pw_domain; |
103 |
|
|
|
104 |
|
|
$self->log(LOGINFO, |
105 |
|
|
"Authentication to vpopmail via mysql: $pw_name\@$pw_domain"); |
106 |
|
|
|
107 |
|
|
my $sth = $dbh->prepare(<<SQL); |
108 |
|
|
-select * |
109 |
|
|
-from vpopmail |
110 |
|
|
-where pw_name = ? and pw_domain = ? |
111 |
|
|
+SELECT * |
112 |
|
|
+FROM vpopmail |
113 |
|
|
+WHERE pw_name = ? AND pw_domain = ? |
114 |
|
|
SQL |
115 |
|
|
|
116 |
|
|
$sth->execute( $pw_name, $pw_domain ); |
117 |
|
|
@@ -96,8 +109,8 @@ SQL |
118 |
|
|
|
119 |
|
|
# if vpopmail was not built with '--enable-clear-passwd=y' |
120 |
|
|
# then pw_clear_passwd may not even exist |
121 |
|
|
- my $pw_clear_passwd = exists $passwd_hash->{'pw_clear_passwd'} |
122 |
|
|
- ? $passwd_hash->{'pw_clear_passwd'} |
123 |
|
|
+ my $pw_clear_passwd = exists $passwd_hash->{'pw_clear_passwd'} |
124 |
|
|
+ ? $passwd_hash->{'pw_clear_passwd'} |
125 |
|
|
: undef; |
126 |
|
|
my $pw_passwd = $passwd_hash->{'pw_passwd'}; # this is always present |
127 |
|
|
|
128 |
|
|
@@ -107,26 +120,26 @@ SQL |
129 |
|
|
# user doesn't exist in this domain |
130 |
|
|
( not defined $pw_passwd ) |
131 |
|
|
) { |
132 |
|
|
- return ( DECLINED, "authsql/$method" ); |
133 |
|
|
+ return ( DECLINED, "auth_vmysql/$method" ); |
134 |
|
|
} |
135 |
|
|
|
136 |
|
|
# at this point we can assume the user name matched |
137 |
|
|
if ( |
138 |
|
|
- ( defined $passClear and |
139 |
|
|
+ ( defined $passClear and |
140 |
|
|
( |
141 |
|
|
($pw_clear_passwd eq $passClear) |
142 |
|
|
or ($pw_passwd eq crypt( $passClear, $pw_passwd ) ) |
143 |
|
|
) |
144 |
|
|
- ) |
145 |
|
|
+ ) |
146 |
|
|
or ( defined $passHash |
147 |
|
|
and $passHash eq hmac_md5_hex( $ticket, $pw_clear_passwd ) ) |
148 |
|
|
) |
149 |
|
|
{ |
150 |
|
|
|
151 |
|
|
- return ( OK, "authsql/$method" ); |
152 |
|
|
+ return ( OK, "auth_vmysql/$method" ); |
153 |
|
|
} |
154 |
|
|
else { |
155 |
|
|
- return ( DENY, "authsql/$method - wrong password" ); |
156 |
|
|
+ return ( DENY, "auth_vmysql/$method - wrong password" ); |
157 |
|
|
} |
158 |
|
|
} |
159 |
|
|
|
160 |
|
|
-- |
161 |
|
|
1.7.2.2 |
162 |
|
|
|