1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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);
|