]> git.ipfire.org Git - thirdparty/squid.git/blob - src/auth/basic/DB/basic_db_auth.pl.in
SourceFormat Enforcement
[thirdparty/squid.git] / src / auth / basic / DB / basic_db_auth.pl.in
1 #!@PERL@
2
3 use strict;
4 use Pod::Usage;
5 use Getopt::Long;
6
7 =pod
8
9 =head1 NAME
10
11 basic_db_auth - Database auth helper for Squid
12
13 =head1 SYNOPSIS
14
15 basic_db_auth [options]
16
17 =head1 DESCRIPTOIN
18
19 This program verifies username & password to a database
20
21 =head1 OPTIONS
22
23 =over 12
24
25 =item B<--debug>
26
27 Write debug info to stderr.
28
29 =item B<--dsn>
30
31 Database DSN. Default "DBI:mysql:database=squid"
32
33 =item B<--user>
34
35 Database User
36
37 =item B<--password>
38
39 Database password
40
41 =item B<--table>
42
43 Database table. Default "passwd".
44
45 =item B<--usercol>
46
47 Username column. Default "user".
48
49 =item B<--passwdcol>
50
51 Password column. Default "password".
52
53 =item B<--cond>
54
55 Condition, defaults to enabled=1. Specify 1 or "" for no condition
56 If you use --joomla flag, this condition will be changed to block=0
57
58 =item B<--plaintext>
59
60 Database contains plain-text passwords
61
62 =item B<--md5>
63
64 Database contains unsalted MD5 passwords
65
66 =item B<--sha1>
67
68 Database contains unsalted SHA1 passwords
69
70 =item B<--salt>
71
72 Selects the correct salt to evaluate passwords
73
74 =item B<--persist>
75
76 Keep a persistent database connection open between queries.
77
78 =item B<--joomla>
79
80 Tells helper that user database is Joomla DB. So their unusual salt
81 hashing is understood.
82
83 =back
84
85 =head1 AUTHOR
86
87 This program was written by
88 I<Henrik Nordstrom <henrik@henriknordstrom.net>> and
89 I<Luis Daniel Lucio Quiroz <dlucio@okay.com.mx>>
90
91 This manual was written by I<Henrik Nordstrom <henrik@henriknordstrom.net>>
92
93 =head1 COPYRIGHT
94
95 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
96 *
97 * Squid software is distributed under GPLv2+ license and includes
98 * contributions from numerous individuals and organizations.
99 * Please see the COPYING and CONTRIBUTORS files for details.
100
101 Copyright (C) 2007 Henrik Nordstrom <henrik@henriknordstrom.net>
102 Copyright (C) 2010 Luis Daniel Lucio Quiroz <dlucio@okay.com.mx> (Joomla support)
103 This program is free software. You may redistribute copies of it under the
104 terms of the GNU General Public License version 2, or (at youropinion) any
105 later version.
106
107 =head1 QUESTIONS
108
109 Questions on the usage of this program can be sent to the I<Squid Users mailing list <squid-users@squid-cache.org>>
110
111 =head1 REPORTING BUGS
112
113 Bug reports need to be made in English.
114 See http://wiki.squid-cache.org/SquidFaq/BugReporting for details of what you need to include with your bug report.
115
116 Report bugs or bug fixes using http://bugs.squid-cache.org/
117
118 Report serious security bugs to I<Squid Bugs <squid-bugs@squid-cache.org>>
119
120 Report ideas for new improvements to the I<Squid Developers mailing list <squid-dev@squid-cache.org>>
121
122 =head1 SEE ALSO
123
124 squid (8), GPL (7),
125
126 The Squid FAQ wiki http://wiki.squid-cache.org/SquidFaq
127
128 The Squid Configuration Manual http://www.squid-cache.org/Doc/config/
129
130 =cut
131
132 use DBI;
133 use Digest::MD5 qw(md5 md5_hex md5_base64);
134 use Digest::SHA qw(sha1 sha1_hex sha1_base64);
135
136 my $dsn = "DBI:mysql:database=squid";
137 my $db_user = undef;
138 my $db_passwd = undef;
139 my $db_table = "passwd";
140 my $db_usercol = "user";
141 my $db_passwdcol = "password";
142 my $db_cond = "enabled = 1";
143 my $plaintext = 0;
144 my $md5 = 0;
145 my $sha1 = 0;
146 my $persist = 0;
147 my $isjoomla = 0;
148 my $debug = 0;
149 my $hashsalt = undef;
150
151 GetOptions(
152 'dsn=s' => \$dsn,
153 'user=s' => \$db_user,
154 'password=s' => \$db_passwd,
155 'table=s' => \$db_table,
156 'usercol=s' => \$db_usercol,
157 'passwdcol=s' => \$db_passwdcol,
158 'cond=s' => \$db_cond,
159 'plaintext' => \$plaintext,
160 'md5' => \$md5,
161 'sha1' => \$sha1,
162 'persist' => \$persist,
163 'joomla' => \$isjoomla,
164 'debug' => \$debug,
165 'salt=s' => \$hashsalt,
166 );
167
168 my ($_dbh, $_sth);
169 $db_cond = "block = 0" if $isjoomla;
170
171 sub close_db()
172 {
173 return if !defined($_dbh);
174 undef $_sth;
175 $_dbh->disconnect();
176 undef $_dbh;
177 }
178
179 sub open_db()
180 {
181 return $_sth if defined $_sth;
182 $_dbh = DBI->connect($dsn, $db_user, $db_passwd);
183 if (!defined $_dbh) {
184 warn ("Could not connect to $dsn\n");
185 my @driver_names = DBI->available_drivers();
186 my $msg = "DSN drivers apparently installed, available:\n";
187 foreach my $dn (@driver_names) {
188 $msg .= "\t$dn";
189 }
190 warn($msg."\n");
191 return undef;
192 }
193 my $sql_query;
194 $sql_query = "SELECT $db_passwdcol FROM $db_table WHERE $db_usercol = ?" . ($db_cond ne "" ? " AND $db_cond" : "");
195 $_sth = $_dbh->prepare($sql_query) || die;
196 return $_sth;
197 }
198
199 sub check_password($$)
200 {
201 my ($password, $key) = @_;
202
203 if ($isjoomla){
204 my $salt;
205 my $key2;
206 ($key2,$salt) = split (/:/, $key);
207 return 1 if md5_hex($password.$salt).':'.$salt eq $key;
208 }
209 else{
210 return 1 if defined $hashsalt && crypt($password, $hashsalt) eq $key;
211 return 1 if crypt($password, $key) eq $key;
212 return 1 if $md5 && md5_hex($password) eq $key;
213 return 1 if $sha1 && sha1_hex($password) eq $key;
214 return 1 if $plaintext && $password eq $key;
215 }
216
217 return 0;
218 }
219
220 sub query_db($) {
221 my ($user) = @_;
222 my ($sth) = open_db() || return undef;
223 if (!$sth->execute($user)) {
224 close_db();
225 open_db() || return undef;
226 $sth->execute($user) || return undef;;
227 }
228 return $sth;
229 }
230 my $status;
231
232 $|=1;
233 while (<>) {
234 my ($user, $password) = split;
235 $status = "ERR";
236 $user =~ s/%(..)/pack("H*", $1)/ge;
237 $password =~ s/%(..)/pack("H*", $1)/ge;
238
239 $status = "ERR database error";
240 my $sth = query_db($user) || next;
241 $status = "ERR unknown login";
242 my $row = $sth->fetchrow_arrayref() || next;
243 $status = "ERR login failure";
244 next if (!check_password($password, @$row[0]));
245 $status = "OK";
246 } continue {
247 close_db() if (!$persist);
248 print $status . "\n";
249 }