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