#!/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";
&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";
if ($#users >= 0) {
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