xref: /minix3/crypto/external/bsd/heimdal/dist/lib/kadm5/check-cracklib.pl (revision ebfedea0ce5bbe81e252ddf32d732e40fb633fae)
1*ebfedea0SLionel Sambuc#!/usr/pkg/bin/perl
2*ebfedea0SLionel Sambuc#
3*ebfedea0SLionel Sambuc# Sample password verifier for Heimdals external password
4*ebfedea0SLionel Sambuc# verifier, see the chapter "Password changing" in the the info
5*ebfedea0SLionel Sambuc# documentation for more information about the protocol used.
6*ebfedea0SLionel Sambuc#
7*ebfedea0SLionel Sambuc# Three checks
8*ebfedea0SLionel Sambuc#  1. Check that password is not the principal name
9*ebfedea0SLionel Sambuc#  2. Check that the password passes cracklib
10*ebfedea0SLionel Sambuc#  3. Check that password isn't repeated for this principal
11*ebfedea0SLionel Sambuc#
12*ebfedea0SLionel Sambuc# The repeat check must be last because some clients ask
13*ebfedea0SLionel Sambuc# twice when getting "no" back and thus the error message
14*ebfedea0SLionel Sambuc# would be wrong.
15*ebfedea0SLionel Sambuc#
16*ebfedea0SLionel Sambuc# Prereqs (example versions):
17*ebfedea0SLionel Sambuc#
18*ebfedea0SLionel Sambuc# * perl (5.8.5) http://www.perl.org/
19*ebfedea0SLionel Sambuc# * cracklib (2.8.5) http://sourceforge.net/projects/cracklib
20*ebfedea0SLionel Sambuc# * Crypt-Cracklib perlmodule (0.01) http://search.cpan.org/~daniel/
21*ebfedea0SLionel Sambuc#
22*ebfedea0SLionel Sambuc# Sample dictionaries:
23*ebfedea0SLionel Sambuc#     cracklib-words (1.1) http://sourceforge.net/projects/cracklib
24*ebfedea0SLionel Sambuc#     miscfiles (1.4.2) http://directory.fsf.org/miscfiles.html
25*ebfedea0SLionel Sambuc#
26*ebfedea0SLionel Sambuc# Configuration for krb5.conf or kdc.conf
27*ebfedea0SLionel Sambuc#
28*ebfedea0SLionel Sambuc#   [password_quality]
29*ebfedea0SLionel Sambuc#     	policies = builtin:external-check
30*ebfedea0SLionel Sambuc#     	external_program = <your-path>/check-cracklib.pl
31*ebfedea0SLionel Sambuc#
32*ebfedea0SLionel Sambuc# Id
33*ebfedea0SLionel Sambuc
34*ebfedea0SLionel Sambucuse strict;
35*ebfedea0SLionel Sambucuse Crypt::Cracklib;
36*ebfedea0SLionel Sambucuse Digest::MD5;
37*ebfedea0SLionel Sambuc
38*ebfedea0SLionel Sambuc# NEED TO CHANGE THESE TO MATCH YOUR SYSTEM
39*ebfedea0SLionel Sambucmy $database = '/usr/lib/cracklib_dict';
40*ebfedea0SLionel Sambucmy $historydb = '/var/heimdal/historydb';
41*ebfedea0SLionel Sambuc# NEED TO CHANGE THESE TO MATCH YOUR SYSTEM
42*ebfedea0SLionel Sambuc
43*ebfedea0SLionel Sambuc# seconds password reuse allowed (to catch retries from clients)
44*ebfedea0SLionel Sambucmy $reusetime = 60;
45*ebfedea0SLionel Sambuc
46*ebfedea0SLionel Sambucmy %params;
47*ebfedea0SLionel Sambuc
48*ebfedea0SLionel Sambucsub check_basic
49*ebfedea0SLionel Sambuc{
50*ebfedea0SLionel Sambuc    my $principal = shift;
51*ebfedea0SLionel Sambuc    my $passwd = shift;
52*ebfedea0SLionel Sambuc
53*ebfedea0SLionel Sambuc    if ($principal eq $passwd) {
54*ebfedea0SLionel Sambuc	return "Principal name as password is not allowed";
55*ebfedea0SLionel Sambuc    }
56*ebfedea0SLionel Sambuc    return "ok";
57*ebfedea0SLionel Sambuc}
58*ebfedea0SLionel Sambuc
59*ebfedea0SLionel Sambucsub check_repeat
60*ebfedea0SLionel Sambuc{
61*ebfedea0SLionel Sambuc    my $principal = shift;
62*ebfedea0SLionel Sambuc    my $passwd = shift;
63*ebfedea0SLionel Sambuc    my $result  = 'Do not reuse passwords';
64*ebfedea0SLionel Sambuc    my %DB;
65*ebfedea0SLionel Sambuc    my $md5context = new Digest::MD5;
66*ebfedea0SLionel Sambuc    my $timenow = scalar(time());
67*ebfedea0SLionel Sambuc
68*ebfedea0SLionel Sambuc    $md5context->reset();
69*ebfedea0SLionel Sambuc    $md5context->add($principal, ":", $passwd);
70*ebfedea0SLionel Sambuc
71*ebfedea0SLionel Sambuc    my $key=$md5context->hexdigest();
72*ebfedea0SLionel Sambuc
73*ebfedea0SLionel Sambuc    dbmopen(%DB,$historydb,0600) or die "Internal: Could not open $historydb";
74*ebfedea0SLionel Sambuc    if (!$DB{$key} || ($timenow - $DB{$key} < $reusetime)) {
75*ebfedea0SLionel Sambuc	$result = "ok";
76*ebfedea0SLionel Sambuc	$DB{$key}=$timenow;
77*ebfedea0SLionel Sambuc    }
78*ebfedea0SLionel Sambuc    dbmclose(%DB) or die "Internal: Could not close $historydb";
79*ebfedea0SLionel Sambuc    return $result;
80*ebfedea0SLionel Sambuc}
81*ebfedea0SLionel Sambuc
82*ebfedea0SLionel Sambucsub badpassword
83*ebfedea0SLionel Sambuc{
84*ebfedea0SLionel Sambuc    my $reason = shift;
85*ebfedea0SLionel Sambuc    print "$reason\n";
86*ebfedea0SLionel Sambuc    exit 0
87*ebfedea0SLionel Sambuc}
88*ebfedea0SLionel Sambuc
89*ebfedea0SLionel Sambucwhile (<STDIN>) {
90*ebfedea0SLionel Sambuc    last if /^end$/;
91*ebfedea0SLionel Sambuc    if (!/^([^:]+): (.+)$/) {
92*ebfedea0SLionel Sambuc	die "key value pair not correct: $_";
93*ebfedea0SLionel Sambuc    }
94*ebfedea0SLionel Sambuc    $params{$1} = $2;
95*ebfedea0SLionel Sambuc}
96*ebfedea0SLionel Sambuc
97*ebfedea0SLionel Sambucdie "missing principal" if (!defined $params{'principal'});
98*ebfedea0SLionel Sambucdie "missing password" if (!defined $params{'new-password'});
99*ebfedea0SLionel Sambuc
100*ebfedea0SLionel Sambucmy $reason;
101*ebfedea0SLionel Sambuc
102*ebfedea0SLionel Sambuc$reason = check_basic($params{'principal'}, $params{'new-password'});
103*ebfedea0SLionel Sambucbadpassword($reason) if ($reason ne "ok");
104*ebfedea0SLionel Sambuc
105*ebfedea0SLionel Sambuc$reason = fascist_check($params{'new-password'}, $database);
106*ebfedea0SLionel Sambucbadpassword($reason) if ($reason ne "ok");
107*ebfedea0SLionel Sambuc
108*ebfedea0SLionel Sambuc$reason = check_repeat($params{'principal'}, $params{'new-password'});
109*ebfedea0SLionel Sambucbadpassword($reason) if ($reason ne "ok");
110*ebfedea0SLionel Sambuc
111*ebfedea0SLionel Sambucprint "APPROVED\n";
112*ebfedea0SLionel Sambucexit 0
113