diff options
Diffstat (limited to 'scripts/checkpassword.pl')
-rwxr-xr-x | scripts/checkpassword.pl | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/scripts/checkpassword.pl b/scripts/checkpassword.pl new file mode 100755 index 0000000..25a88f8 --- /dev/null +++ b/scripts/checkpassword.pl @@ -0,0 +1,117 @@ +#!/usr/bin/perl + +# checkpassword.pl +# +# Larry M. Smith <chains-chkpass@FahQ2.com> +# +# Modified for Binc IMAP by Erwin Hoffmann +# Using multilog, simply comment the calls of err_* and log_*; +# they are not required however could be useful in case of syslog. +# +# Expects tcpserver environmental variables $TCPLOCALPORT and $TCPREMOTEIP. +# See http://cr.yp.to/ucspi-tcp/environment.html +# +# Provided AS IS and free... It works on my system, your's *MAY* be +# different!!! YOU as sysadmin, are expected to TEST everything that +# you bring online!!! Also, you may not like the way I log failed +# passwords. +# +# If you see something that could/should be done differently please let me +# know. +# +# +# You will need these modules installed on your system. +# Please read the respective man pages. +# +use strict qw( vars ); +use User::pwent; +use Unix::Syslog qw(:macros); +use Unix::Syslog qw(:subs); + +#print STDERR "Starting checkpassword.pl\n"; + +# +# Change these to match your system/site polices. +# +my $MINUID = 500; # We don't want brute force attacks against root, etc. +my $EGID = "100 100"; # Don't pass extra groups like wheel, etc. +my $RGID = 100; + +$|=1; + +my $ipaddr = $ENV{'TCPREMOTEIP'}; +my $port = $ENV{'TCPLOCALPORT'}; +%ENV=(); + +my($len,$buf); +open (USER, "<&=3") or exit (2); +$len = read(USER, $buf, 512); +close USER; +exit(2) if $len < 4; + +my($user, $pass) = split /\x00/, $buf; +$user = lc $user; +$buf = "\x00" x $len; + +print STDERR "Reading User $user - Passwd $pass \n"; + +my $pw = getpwnam($user) || err_unknown(); + +my $uid = $pw->uid; +my $phash = $pw->passwd; +my $home = $pw->dir; +my $shell = $pw->shell; + +if ($uid < $MINUID) { + err_minuid(); + } + +if (crypt($pass, $phash) ne $phash) { + err_badpass(); + } + + +$ENV{USER}=$user; +$ENV{UID}=$uid+0; +$ENV{HOME}=$home; +$ENV{SHELL}=$shell; + +exit(-4) unless $ENV{UID}; +chdir $ENV{HOME}; +$) = $EGID; +$( = $RGID; +$> = $ENV{UID}; +$< = $ENV{UID}; +log_imap4(); + +exec @ARGV; + +sub err_unknown { + openlog("checkpassword.pl: ", LOG_PID, LOG_MAIL); + syslog(LOG_INFO, "Attempt to login port %d with unknown user (%s) from [%s]", $port, $user, $ipaddr); + closelog; + exit(1); + } + +sub err_minuid{ + openlog("checkpassword.pl: ", LOG_PID, LOG_MAIL); + syslog(LOG_INFO, "Attempt to login port %d with UID lt %d (%s) from [%s]",$port, $MINUID, $user, $ipaddr); + closelog; + exit(1); + } + +sub err_badpass{ + openlog("checkpassword.pl: ", LOG_PID, LOG_MAIL); + syslog(LOG_INFO, "Attempt to login port %d failed for UID %d (%s - %s) from [%s] ",$port, $uid, $user, $pass, $ipaddr); + closelog(); + exit(1); + } + +sub log_imap4{ + openlog("checkpassword.pl: ", LOG_PID, LOG_MAIL); + syslog(LOG_INFO, "port %d login successful UID %d (%s) from [%s]",$port, $uid, $user, $ipaddr); + closelog(); + } + +# sleep(10); +exit(0); |