#!/usr/bin/perl # -*- perl -*- # # Copyright (C) 1996 DJ Delorie All rights reserved # # Permission is granted to copy, use, and distribute this program # provided it is not modified in any way. # # http://www.delorie.com/bin/pwmgr/ # if ($ARGV[0] eq "-printme") { print "Content-type: text/plain\n\n"; open(ME, $0); print while ; close(ME); exit 0; } print "Content-type: text/html\n\n"; print "Delorie Password Manager\n"; print "

Delorie Password Manager

\n"; &ReadParse; $userdir = $ENV{"PATH_TRANSLATED"}; $userdir =~ s@[^/]+$@@; $userwdir = $ENV{"PATH_INFO"}; $userwdir =~ s@[^/]+$@@; $secure = 1; $me = $ENV{"REQUEST_URI"}; open(CONF, $ENV{"PATH_TRANSLATED"}); while () { ($cmd,$val) = split(' '); if ($cmd eq "file") { $file = $val; $file = $userdir.$file unless $file =~ m@^/@; $wfile = $val; $wfile = $userwdir.$wfile unless $wfile =~ m@^/@; } elsif ($cmd eq "admin") { $admin{$val} = 1; } elsif ($cmd eq "unsecure") { $secure = 0; } } &trailer("No file entry") unless $file; #&trailer("No valid file file found") unless -f $file && -w $file; @admins = sort keys %admin; $admins = $#admins + 1; print "
";
if (!$secure || $admin{$user}) {
    print "Password file is $wfile\n";
    print "Secure mode\n" if $secure;

    if ($admins == 0) {
	print "No admins are listed.\n";
    } elsif ($admins == 1) {
	print "Admin is ", join(', ', sort keys %admin), "\n";
    } else {
	print "Admins are ", join(', ', sort keys %admin), "\n";
    }
}

$user = $ENV{"REMOTE_USER"};

open(PW, $file);
while () {
    if (/:/) {
	s/[\r\n]+$//;
	($u,$p) = split(':');
	$users{$u} = $p;
    }
}
close(PW);

if ($user) {
    print "You are $user\n";
    printf "You are an administrator.\n" if $admin{$user};
    print "
\n"; if (!$admin{$user}) { $p1 = $in{'pw1'}; $p2 = $in{'pw2'}; if ($p1 && $p2) { if ($p1 eq $p2) { &validate_oldpw($user, $in{'opw'}); $in{'user'} = $user; $in{'password'} = $p1; &do_add(); } &trailer("Passwords do not match"); } if ($p1 || $p2) { &trailer("You must enter your new password twice"); } print "
";
	print "
\n"; print "Old Password: \n"; print "New Password: \n"; print " Again: \n"; print " \n"; print "
\n"; &trailer(); } } else { print "\n"; if ($secure) { &trailer("Sorry, you must authenticate first."); } print "

Warning: Running in unprotected mode! Give\n"; print "yourself an account and password and install your .htaccess\n"; print "file!

\n"; } @users = sort keys %users; &do_add if $in{'cmd'} eq "add"; &do_del if $in{'cmd'} eq "del"; print "
";
print "
\n"; print "Add a user (or reset an existing user's password)\n"; print " User: \n"; print "Password: "; print "
\n"; if ($#users >= 0) { print "
\n"; print "Delete a user\n"; print " User: "; print "
\n"; print "

List of Users

\n"; print join(' ', sort keys %users); } print "
"; &trailer(""); ############################################################################# sub do_add { if ($in{'user'} =~ /[:\s,]/) { &trailer("User names may not have spaces, tabs, colons, or commas in them."); } unless ($in{'user'} =~ /\S/) { &trailer("No user name given."); } unless ($in{'password'} =~ /\S/) { &trailer("No password given."); } srand (time + $$); $salts = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; $newu = $in{'user'}; $password = $in{'password'}; $salt = substr($salts, int(rand(64)),1) . substr($salts, int(rand(64)),1); $des = crypt($password, $salt); if ($users{$newu}) { print "

Changing password of $newu\n"; print "to $password...

\n"; } else { print "

Adding user $newu\n"; print "with password $password...

\n"; } $prevuser = $users{$newu}; $users{$newu} = $des; &store; if ($prevuser) { &trailer("Password change complete"); } else { &trailer("Add/update complete"); } } sub do_del { $delu = $in{'user'}; &trailer("No such user $delu\n") unless $users{$delu}; print "

Deleting user $delu

\n"; delete $users{$delu}; &store; &trailer("Delete complete"); } sub store { &trailer("I cannot write to $wfile: $!") unless (open(PW, ">$file")); for $u (sort keys %users) { print PW "$u:$users{$u}\n"; } close(PW); } sub validate_oldpw { my ($u, $p) = @_; $salt = substr($users{$u}, 0, 2); $des = crypt($p, $salt); if ($des ne $users{$u}) { &trailer("Old password is not correct."); } } ############################################################################# sub trailer { local($t) = @_; print "

$t

\n"; print while ; exit 0; } sub ReadParse { local (*in) = @_ if @_; local ($i, $key, $val); # Read in text if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN,$in,$ENV{'CONTENT_LENGTH'}); } if ($ENV{'QUERY_STRING'}) { $in .= "&" . $ENV{'QUERY_STRING'}; $in =~ s/^&//; } @in = split(/&/,$in); foreach $i (0 .. $#in) { # Convert plus's to spaces $in[$i] =~ s/\+/ /g; # Split into key and value. ($key, $val) = split(/=/,$in[$i],2); # splits on the first =. # Convert %XX from hex numbers to alphanumeric $key =~ s/%(..)/pack("c",hex($1))/ge; $val =~ s/%(..)/pack("c",hex($1))/ge; # Associate key and value $in{$key} .= "\0" if (defined($in{$key})); # \0 is the multiple separator $in{$key} .= $val; $in[$i] = $key; } return length($in); } __END__


Warning: The Delorie Password Manager makes no claims as to the security of the passwords it manages or the data it protects. This system is to be used for light-weight purposes only! If you need true security, contact your local system administrator or webmaster and ask them to advise you.


The Delorie Password Manager is Copyright © 1996 by DJ Delorie