php authentication via /etc/passwd
Om niet alle users door apache/php uit te laten lezen maak ik gebruik van een perl script dat deze bestanden uit leest. Via de cron wordt om de zo veel tijd alles uitgelezen en op de server in een map geplaatst.
Perl Script:
#!/usr/bin/perl
#
open(PASSWD,"/etc/passwd");
open(SHADOW,"/etc/shadow");
open(FLATFILE,">/etc/passwd.httpd");
while(<SHADOW>){
chop;
($uname,$temppass)=split(/:/);
$pass{$uname}=$temppass;
}
while(<PASSWD>){
chop;
($uname,$temppass,$uid,$gid,$fn,$homedir,$shell)=split(/:/);
if ($temppass ne 'x'){ $pass{$uname}=$temppass; }
if ($uid>=500) {
print FLATFILE
"$uname:$pass{$uname}:$uid:$gid:$fn:$homedir:$shell\n";
}
}
close(PASSWD);
close(SHADOW);
close(FLATFILE);
chmod(0400,"/etc/passwd.httpd");
chown(65534,65534,"/etc/passwd.httpd");
Via een php script probeer ik vervolgens de users en de hashes, zoals ze in het bestand staan, te laten matchen. Daarvoor gebruik ik dit script:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
$user = ($_POST['username']);
$password = ($_POST['password']);
$autharray = file("/home/httpd/vhosts/domein.nl/httpdocs/passwd.httpd");
for ($x = 0; $x < count($autharray); $x++)
{
if (eregi("^$user:", $autharray[$x]))
{
$passwd = explode(":", $autharray[$x]);
$salt = substr($passwd[1],0,2);
$cryptpw = crypt($pass,$salt);
if ($cryptpw == $passwd[1]) {
print "succes";
} else {
print "fout";
}
}
}
?>
$user = ($_POST['username']);
$password = ($_POST['password']);
$autharray = file("/home/httpd/vhosts/domein.nl/httpdocs/passwd.httpd");
for ($x = 0; $x < count($autharray); $x++)
{
if (eregi("^$user:", $autharray[$x]))
{
$passwd = explode(":", $autharray[$x]);
$salt = substr($passwd[1],0,2);
$cryptpw = crypt($pass,$salt);
if ($cryptpw == $passwd[1]) {
print "succes";
} else {
print "fout";
}
}
}
?>
Echter als ik deze waardes via echo laat uitlezen komen deze totaal niet overeen met de hashes zoals ze in het perl gemaakte script staan. Misschien zit er ergens een fout in het script of moet ik nog een extra waarde meegeven. Ik hoop dat hier iemand is die mij verder op weg kan helpen. De uiteindelijke code zal ik hier publiceren.
Wat je eigenlijk gewoon zoekt is een PAM libary voor php:
http://www.math.ohio-state.edu/~ccunning/pam_auth/
of voor perl:
http://www.cs.kuleuven.ac.be/~pelov/pam/Authen/PAM.html
http://search.cpan.org/~hdaniel/Apache-AuthPAM-0.01/AuthPAM.pm
http://search.cpan.org/~rsd/Authen-SimplePam-0.1.24/SimplePam.pm
Verder voor mod_perl: http://search.cpan.org/~rsd/Authen-SimplePam-0.1.24/SimplePam.pm
Ik ben weer iets verder. Wat blijkt is dat het script random hashes creert en dus niet een enkele hash ter vergelijking met de perl gegenereerde file. Weet er iemand wat er mis kan zijn?
Apache leest dus niet, en kan dus niet, de shadow file lezen
Wanneer je een kopie maakt is deze voor jouw opzet WEL geheel leesbaar en is het bijvoorbeeld mogelijk (veel gemakkelijker) om een aparte kopie te maken, doordat apache leesrechten moet hebben over je shadow file. PAM is er juist voor om dit te voorkomen.
Een oplossing met een Authen::SimplePAM en ExecCGI lijkt mij de veiligste oplossing.