summaryrefslogtreecommitdiff
path: root/scripts/checkpassword.pl
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/checkpassword.pl')
-rwxr-xr-xscripts/checkpassword.pl117
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);