#!/usr/bin/perl # # Create/modify password file for httpd # # http://hostwick.com/PasswordManager.html # $rcs = 1; $rcslog = '/dev/null'; $parent=(caller)[1]; if(!$parent){ print "Content-type: text/html\n\n"; print "\n"; # print $ENV{QUERY_STRING}."
\n"; &form_decode(); print <<"__HEAD__";

Easy Password Manager




Password file:   Username:   Password:
__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) = ; #print "
".@pwf."
"; seek(FHPF,0,0); @pwf = grep { !/^$u:/; } @pwf; @pwf = grep { !/^\n*$/; } @pwf; push(@pwf, "$u:".enc_crypt($p)."\n" ); #print join("
",@pwf)."
\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) = ; 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) = ; close(FHPF); $u = escex($u); local(@rl) = grep { s/^$u://s; } @pwf; local($pw) = @rl[0]; chomp($pw); #print "
$user=$u, pw=$p, enc=".$pw."
\n"; return check_crypt($p, $pw); } sub list_userpass{ local($pf) = @_; open(FHPF, "$pf") || return (3,"Could not open file: $pf"); local(@pwf) = ; close(FHPF); print join("
",@pwf)."
\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
\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
\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;