Features:It's a small fast pure Perl CGI (other than rcs feature).It can add/delete/check/list/clear user:password combo in the password file of Apache.It should work on any Linux host (other than the rcs feature).When turned on, rcs feature will keep all records of modification tot he password file, allowing you to recover from accidental changes.Disclaimer:Keep the backup of your password file.This is a freebie/DonationWare and you are agreeing to use it at your own risks by installing it.Instruction:Upload the script and set executable permission (often 755).You may need to change the path for Perl (the first line of the script)Downlodable code PasswordManagerCode:
#!/usr/bin/perl # # Create/modify password file for httpd # # http://hostwick.com/PasswordManager.html # # Set $rcs to 1 if you want to use rcs to save different version of password file. $rcs = 0; $rcslog = '/dev/null'; $parent=(caller)[1]; if(!$parent){ print "Content-type: text/html\n\n"; print "<HTML><BODY bgcolor=#406060 text=#dFcFbF link=#fbe731 vlink=#fbe731 alink=#FFFF80>\n"; # print $ENV{QUERY_STRING}."<br>\n"; &form_decode(); print <<"__HEAD__"; <center> <h1>Easy Password Manager</h1><hr> </center> <ul><ul> __HEAD__ $pf = ".htpf" if ! $pf; if($submit eq 'Add'){ print "Adding $u:$pw to the $pf<br><br>\n"; $r = add_userpass($pf,$u,$pw); if($r == 1){ print "Done!" ; }else{ print "result=$r<br>" ; } }elsif($submit eq 'Del'){ print "Deleting $u:$pw from $pf<br><br>\n"; $r = del_userpass($pf,$u); if($r == 1){ print "Done!" ; }else{ print "result=$r<br>" ; } }elsif($submit eq 'Change'){ print "Cahnging $u:$pw in $pf<br><br>\n"; $r =change_userpass($pf,$u,$pw); if($r == 1){ print "Done!" ; }else{ print "result=$r<br>" ; } }elsif($submit eq 'Check'){ print "Checking $u:$pw in $pf<br><br>\n"; $r = check_userpass($pf,$u,$pw); if($r == 1){ print "<b><font color=lightblue>User name and Password matched!</font></b>" ; }else{ print "<b><font color=red>User name and Password mismatch!</font></b>" ; } }elsif($submit eq 'List'){ print "Listing users in $pf<br><br>\n"; $r = list_userpass($pf,$u,$pw); print "result=$r<br>" if $r > 1; }elsif($submit eq 'Clear'){ print "Clearing $pf<br><br>\n"; $r = clear_userpass($pf,$u,$pw); print "result=$r<br>" if $r > 1; } print <<"__END__"; </ul></ul><hr> <BR><center><Form action=\"\" method=POST> <table><tr><td> Password file: <input type=text name=pf size=20 value=\"$pf\"> Username: <input type=text name=u size=20 value=\"$u\"> Password: <input type=text name=pw size=20 value=\"$pw\"></td></tr> <tr><td align=right> <input type=submit name=submit value=\"Check\"> <input type=submit name=submit value=\"Add\"> <input type=submit name=submit value=\"Del\"> <input type=submit name=submit value=\"Change\"> <input type=submit name=submit value=\"List\"></td></tr></table> </FORM></cente> __END__ exit; } #escape string for regex sub escex{ local($s) = shift; $s =~s/[\[\]\/\$\(\)\{\}.*!?:]/\\$1/g; return $s; } sub add_userpass { local($pf, $u, $p) = @_; open(FHPF, "+<$pf") || return (3,"Could not open file: $pf"); local(@pwf) = <FHPF>; #print "<pre>".@pwf."</pre>"; seek(FHPF,0,0); @pwf = grep { !/^$u:/; } @pwf; @pwf = grep { !/^\n*$/; } @pwf; push(@pwf, "$u:".enc_crypt($p)."\n" ); #print join("<br>",@pwf)."<br>\n"; print FHPF join("",@pwf); close(FHPF); `(date;exec 2>&1;rcs -U -u $pf;ci -w$ru -M -u $pf;chmod 644 $pf) >>$rcslog 2>&1` if $rcs; } sub del_userpass { local($pf, $u) = @_; open(FHPF, "+<$pf") || return (3,"Could not open file: $pf"); local(@pwf) = <FHPF>; close(FHPF); $u = escex($u); @pwf = grep { !/^$u:/; } @pwf; open(FHPF, ">$pf") || return (3,"Could not open file: $pf"); print FHPF join("",@pwf); close(FHPF); `(date;exec 2>&1;rcs -U -u $pf;ci -w$ru -M -u $pf;chmod 644 $pf) >>$rcslog 2>&1` if $rcs; } sub change_userpass{ #del_userpass($pf,$u) || return 0; return add_userpass($pf,$u,$p); } # check if the user exists and the password matches # check(pf, u, p) sub check_userpass{ local($pf, $u, $p) = @_; open(FHPF, "$pf") || return (3,"Could not open file: $pf"); local(@pwf) = <FHPF>; close(FHPF); $u = escex($u); local(@rl) = grep { s/^$u://s; } @pwf; local($pw) = @rl[0]; chomp($pw); #print "<hr>$user=$u, pw=$p, enc=".$pw."<hr>\n"; return check_crypt($p, $pw); } sub list_userpass{ local($pf) = @_; open(FHPF, "$pf") || return (3,"Could not open file: $pf"); local(@pwf) = <FHPF>; close(FHPF); print join("<br>",@pwf)."<br>\n"; return 1; } sub clear_userpass { local($pf) = @_; open(FHPF, ">$pf") || return (3,"Could not open file: $pf"); close(FHPF) || return (3,"Could not close file: $pf"); return 1; } # crypting # arg: password # return: crypted # ex: $pass = &enc_crypt('PassWord'); sub enc_crypt { local($plain) = @_; local($s) = ''; local(@salt) = ('0'..'9','A'..'Z','a'..'z','.','/'); srand; 1 while (length($s .= $salt[rand(@salt)]) < 8); crypt($plain,index(crypt('a','$1$a$'),'$1$a$') == 0 ? '$1$'.$s.'$' : $s); } # check # arg: password, crypted # return: True=OK, false=NG # ex:&check_crypt('PassWord',$pass) ? 'OK' : 'NG' sub check_crypt { local($plain,$crypt) = @_; ($plain ne '' && $crypt ne '' && crypt($plain,$crypt) eq $crypt); } sub form_decode { local( $pair, $name, $value, $buffer, @pairs); $maxbyte = 4000000; if ($ENV{'REQUEST_METHOD'} eq "POST") { if ($ENV{'CONTENT_LENGTH'} > $maxbyte) { read(STDIN, $buffer, $maxbyte); $error .= "CONTENT_LENGTH exceeds $maxbyte\n"; } else { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } } else { $buffer = $ENV{'QUERY_STRING'}; } $cl = $ENV{'CONTENT_LENGTH'}; $bl = length($buffer); $error .= "buffer length exceeds $maxbyte\n" if $bl > $maxbyte; @pairs = split(/&/, $buffer); foreach $pair (@pairs) { # print "$pair<BR>\n"; ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%u([0-9a-fA-F]{4})/pack('H4', $1)/eg; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; eval("\$"."$name = \$value;"); # print "$name, $value<BR>\n"; } } sub logdata{ local(@t)= gmtime(time + $offset); local($wday)= ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')[$t[6]] ; $mdate = sprintf("%04d/%02d/%02d(%s)%02d:%02d:%02d", $t[5]+1900, $t[4], $t[3],$wday, $t[2], $t[1], $t[0] ) ; $rh = $ENV{REMOTE_HOST}; $addr = $ENV{REMOTE_ADDR}; $rh = gethostbyaddr(pack("C4",split(/\./, $addr)),2) if $rh eq "" || $host eq $addr; $host = "$rh:$addr:$ENV{HTTP_USER_AGENT}"; return "$mdate, $0,$ldatpre $host, $ENV{HTTP_REFERER}, $ENV{REQUEST_URI}, $ldat\n"; } 1; Hostwick.com --- Generated on 2007-01-24_07:52:52