#!/usr/local/bin/suidperl # # squid authenticator module # using shadow password system and aliases map file # # Author: Leo Fellermayr (leosmail@mac.com) # # $Id: squid_auth_shadow.pl,v 1.2 2001/10/23 15:15:21 leo Exp $ # use POSIX qw(strftime); use strict; my $msg_ok = "OK\n"; my $msg_err = "ERR\n"; my $aliases_file = '/etc/auth_shadow_leo/aliases.map'; my $deny_file = '/etc/auth_shadow_leo/deny.map'; my $log_file = '/var/log/squidauth.log'; my $logging = 1; # query /etc/passwd for existing UNIX username sub query_etc_passwd ($) { my $myuser = shift; return 0 if (!$myuser); my ($login,$pass,$uid,$gid) = getpwnam ($myuser) or return 0; return ($login); } # query alias file for mapping alias to existing UNIX username sub query_aliases ($) { my $myuser = shift; return 0 if (!$myuser); open (ALIAS, "<$aliases_file") or die ("FATAL: could not open aliases file"); my ($name, $aliases) = ""; my @aliases = (); while () { next if (!/.*=.*/); ($name, $aliases) = split /=/, $_; $name =~ s/ //g; @aliases = split / /, $aliases; foreach (@aliases) { next if ($_ eq ""); if ($myuser eq $_) { close (ALIAS); return ($name); } } } close (ALIAS); return 0; } # check if this username is specified as denied sub is_denied ($) { my $myuser = shift; my $denied = 0; open (DENY, "<$deny_file"); while () { chomp $_; if ($myuser eq $_) { $denied = 1; } } close (DENY); if ($denied) { plog (" + User explicitly denied: $myuser\n") if ($logging); return 1; } return 0; } sub plog ($) { my $message = shift; my $date = strftime "%d.%m.%y %H:%M:%S", localtime; open (LOGFILE, ">>$log_file"); print LOGFILE $date . " - " . $message; close (LOGFILE); } # ----- main program # flush stdout (important, without this squid ends in an infinite stuck loop... # took me 1,5 hours to find this out ;-) $| = 1; # read in shadow file my @shadow = (); plog ("Reading shadow file...") if ($logging); open (SHADOW, "; close (SHADOW); # status message plog ("ready...\n") if ($logging); # wait for input from stdin while () { chomp; my ($user, $word) = split / /; if ($user eq "") { plog (" + Squid gave me a blank username...\n") if ($logging); print $msg_err; exit (0); } plog ("Squid gave me the username \"$user\", let's see...\n") if ($logging); # perform username validity checks my $username = 0; $username = query_etc_passwd ($user); if ($username eq "0") { $username = query_aliases ($user); plog (" * Yeah, this user is specified in the aliases file. Cool.\n") if ($logging); } else { plog (" * OK, I found this user in /etc/passwd. That's good.\n") if ($logging); } # username doesn't exist in any way -> terminate with error if (!$username) { print $msg_err; plog (" + Username $user does not exist: no passwd entry, no aliases!\n") if ($logging); next; } # query shadow file for the crypted password my ($shadow_line, $shadow_user, $shadow_crypt, $shadow_rest) = ""; foreach (@shadow) { if (/^$username:.*$/) { $shadow_line = $_; ($shadow_user, $shadow_crypt, $shadow_rest) = split /\:/, $shadow_line; } } # check for password correctness if ((crypt($word,$shadow_crypt) eq $shadow_crypt) and (!is_denied ($username))) { print $msg_ok; plog (" * Successfully authenticated: User $username\n") if ($logging); } else { print $msg_err; plog (" + Wrong password for User $username!\n") if ($logging); } } exit (0);