Add password reuse checking. From Harald Barth.

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@17661 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2006-06-16 14:15:14 +00:00
parent bbf8d9a7e4
commit 1f1949462b

View File

@@ -1,18 +1,83 @@
#!/usr/pkg/bin/perl #!/usr/pkg/bin/perl
# #
# Sample cracklib password verifier for Heimdals external password # Sample password verifier for Heimdals external password
# verifier, see the chapter "Password changing" in the the info # verifier, see the chapter "Password changing" in the the info
# documentation for more information about the protocol used. # documentation for more information about the protocol used.
# #
# Three checks
# 1. Check that password is not the principal name
# 2. Check that the password passes cracklib
# 3. Check that password isn't repeated for this principal
#
# The repeat check must be last because some clients ask
# twice when getting "no" back and thus the error message
# would be wrong.
#
# Prereqs (example versions):
#
# * perl (5.8.5) http://www.perl.org/
# * cracklib (2.8.5) http://sourceforge.net/projects/cracklib
# * Crypt-Cracklib perlmodule (0.01) http://search.cpan.org/~daniel/
#
# Samaple dictionaries:
# cracklib-words (1.1) http://sourceforge.net/projects/cracklib
# miscfiles (1.4.2) http://directory.fsf.org/miscfiles.html
#
# Configuration for krb5.conf or kdc.conf
#
# [password_quality]
# policies = builtin:external-check
# external_program = <your-path>/check-cracklib.pl
#
# $Id$ # $Id$
use strict; use strict;
use Crypt::Cracklib; use Crypt::Cracklib;
use Digest::MD5;
my $database = '/usr/pkg/libdata/pw_dict'; my $database = '/usr/lib/cracklib_dict';
my $repeatdb = '/var/heimdal/repeatdb';
my %params; my %params;
sub check_basic
{
my $principal = shift;
my $passwd = shift;
if ($principal eq $passwd) {
return "Principal name as password is not allowed";
}
return "ok";
}
sub check_repeat
{
my $principal = shift;
my $passwd = shift;
my $result = 'Do not reuse passwords';
my %DB;
my $md5context = new Digest::MD5;
$md5context->reset();
$md5context->add($principal, ":", $passwd);
my $key=$md5context->hexdigest();
dbmopen(%DB,$repeatdb,0600) or die "Internal: Could not open $db";
$result = "ok" if (!$DB{$key});
$DB{$key}=scalar(time());
dbmclose(%DB) or die "Internal: Could not close $db";
return $result;
}
sub badpassword
{
my $reason = shift;
print "$reason\n";
exit 0
}
while (<>) { while (<>) {
last if /^end$/; last if /^end$/;
if (!/^([^:]+): (.+)$/) { if (!/^([^:]+): (.+)$/) {
@@ -21,15 +86,19 @@ while (<>) {
$params{$1} = $2; $params{$1} = $2;
} }
die "missing principal" if (!defined $params{'principal'});
die "missing password" if (!defined $params{'new-password'}); die "missing password" if (!defined $params{'new-password'});
my $reason = fascist_check($params{'new-password'}, $database); my $reason;
if ($reason eq "ok") { $reason = check_basic($params{'principal'}, $params{'new-password'});
print "APPROVED\n"; badpassword($reason) if ($reason ne "ok");
} else {
print "$reason\n";
}
$reason = fascist_check($params{'new-password'}, $database);
badpassword($reason) if ($reason ne "ok");
$reason = check_repeat($params{'principal'}, $params{'new-password'});
badpassword($reason) if ($reason ne "ok");
print "APPROVED\n";
exit 0 exit 0