# ------------------------------------------------------------------- # Author: Dean Stringer # Description/Purpose: # # !! NOTE: NOT TO BE ACCESSABLE OR RUN AS A CGI SCRIPT !! # # Reads users from an Apache .htpasswd file and allows an # admin to interactivel edit, add and delete user entries to # the file optionally commiting the changes on exit. # Uses the original Unix crypt() function and an arbitrary # seed value to generate the hash'd password. # # Should run fine on a Win32 machine # ------------------------------------------------------------------- use strict; my %users; my $pwdFile = ".htpasswd"; my $changesMade = 0; loadUsers(); my $char = ""; PAUSE: while ($char ne 'q') { print "\n> "; my $inText = lc(); my @switches = split(' ', $inText); $char = $switches[0]; if ($char =~ /h|\?/) { help(); next PAUSE; } if ($char eq 'a') { addEditUser($switches[1], 'Add'); next PAUSE; } if ($char eq 'd') { deleteUser($switches[1]); next PAUSE; } if ($char eq 'e') { addEditUser($switches[1], 'Edit'); next PAUSE; } if ($char eq 'x') { exit; } if ($char eq 'w') { saveUsers(); $changesMade = 0; next PAUSE; } if ($char eq 'l') { listUsers(); next PAUSE; } } saveUsers() if $changesMade; sub help { print "Key Commands\n--------------------------------------- a Add a user d Delete a user e Edit a users password l List users q Quit (and write) w Write changes x eXit (dont write) "; } sub loadUsers { open(DBIN, "<$pwdFile") || die "Read Error: $!\n"; while () { my ($user,$hash) = split(':', $_); chomp($hash); $users{$user} = $hash; } close(DBIN); } sub saveUsers { open(DBOUT, ">$pwdFile") || die "Error: $!\n"; foreach my $user (keys %users) { print DBOUT $user . ":" . $users{$user} . "\n"; } close(DBOUT); } sub listUsers { foreach my $user (keys %users) { print "$user\n"; } } sub userExists { my $userToFind = shift; return 1 if defined $users{$userToFind}; return 0; } sub addEditUser { my $user = shift; my $mode = shift; if (length($user) < 3) { print "\nUsername to $mode? > "; $user = ; chomp($user); } if (($mode eq 'Add') and userExists($user)) { print "User already exists!\n"; return 0; } if ((length($user) < 3) or (length($user) > 8)) { print "Invalid username (must be 3-8 chars)"; return; } print "Password: "; my $pwd = ; chomp($pwd); my $salt = "XX"; my $hash = crypt($pwd, "$salt"); $users{$user} = $hash; $changesMade++; } sub deleteUser { my $user = shift; unless (userExists($user)) { print "User doesnt exist!\n"; return 0; } if (length($user) < 3) { print "\nUsername to Delete? "; $user = ; chomp($user); } if ((length($user) < 3) or (length($user) > 8)) { print "Invalid username (must be 3-8 chars)"; return; } delete $users{$user}; $changesMade++; }