#!/usr/bin/perl -wT
use strict; # Yes you need to make it work with this and Taint
###
# Modules
use CGI;
use Apache::Htpasswd;
###
# Init
$ENV{'PATH'} = '/var/www/cgi-bin/:/bin/:/usr/bin/';
$update = "was created by ";
$query = new CGI;
print $query->header;
$login_used = `id`; # Take a look at perlvar
# specifically $) and $>
$date = `date`; # Take a look at POSIX::strftime
chomp($login_used);
chomp($date);
&heredocs; # This is named ambiguously
# and won't work with strict
# without some serious changes
&script; # very ambiguous
$filepath = $ENV{'DOCUMENT_ROOT'};
$logpath = "$filepath/.secure"; # why would your logs be
# kept under your webroot?
$htp = new Apache::Htpasswd("$logpath/.htpasswd");
$query = CGI->new(); # There is already a CGI object
# in $query.
@names=$query->param; # Do you really care about *all*
# the params?
$count=0;
foreach $name(@names) { # Why look at all the params
# You are only interested in a few of them
@values[$count] = $query->param($name); # This won't do what you want
# it's actually $values[$count]
# and so will only get the first
# value.
if ($name eq "name")
{
$nameofuser = $values[$count];
}
elsif ($name eq "login")
{
$formlogin = $values[$count];
}
elsif ($name eq "pw")
{
$formpw = $values[$count];
if ( ($formlogin =~ /%3A/) # This test doesn't do what you want
|| ($formlogin =~ /%2F/) # CGI handles escaped characters for you
|| ($formlogin =~ /%3B/) # so these will match a literal %2F
|| ($formpw =~ /%3A/)
|| ($formpw =~ /%3B/) # What happens when 'pw' is the first
|| ($formpw =~/%2F/) # Param?
|| ($nameofuser =~ /%3A/)
|| ($nameofuser =~ /%3B/)
| ($nameofuser =~ /%2F/)) # | <- Typo? should be ||
{
print $illegal;
die("Data contained malicious characters");
}
}
elsif ($name eq "logins")
{
$delvalue="yes";
$deluservalue=$values[$count];
}
elsif ($name eq "viewlog")
{
$viewlogvalue=$values[$count];
}
elsif ($name eq "viewdb")
{
$viewdbvalue=$values[$count];
}
elsif ($name eq "chpw")
{
$chpw=$values[$count];
}
elsif ($name eq "oldpw")
{
$oldpw=$values[$count];
}
else
{
$array[$count]=$value; # Where did $value come from?
$count++;
}
$count++; # If the else above is executed $count
# get's incremented twice.
}
$nameofuser =~ /([\w]+)/; # You should probably show a error
$untainted_name = $1; # if any of these fail to match
$formlogin =~ /([\w]+)/;
$untainted_formlogin = $1; # Why not just assign back to the
$formpw =~ /([\w]+)/; # Original since you will show a
$untainted_formpw = $1; # Error if any of them are bad.
$oldpw =~ /([\w]+)/;
$untainted_oldpw = $1; # Passwords can only be letters ?
if ($viewdbvalue eq "on") # Since you can do both this could be
{ # written as
&db_viewer; # db_viewer() if ($viewdbvalue eq 'on');
} # log_view() if ($viewdbvalue eq 'on');
elsif ($viewlogvalue eq "on") # log() if ($viewdbvalue ne 'on' &&
{ # $viewlogvalue ne 'on');
&log_viewer; # contin();
}
else
{
&log;
}
sub log { # And what does this do?
if (-e ($logpath))
{
&eraser;
}
else
{
mkdir("$logpath", 0755);
&eraser;
}
}
sub mainprog { # This isn't the main program
# it just opens a log file
# and calls usercreate
if (-e ("$logpath/.log")){
open(LOG, ">>$logpath/.log") || die("Could not open log file to add entry.");
}
else
{
open(LOG, ">$logpath/.log")|| die("Could not create log file at $logpath/.log");
}
&usercreate;
}
sub contin {
print $footer;
}
sub log_viewer {
$logupdater = $logupdate;
unless ($viewlogvalue eq "off") # The only way you can get
# here is if $viewlogvalue
# eq 'on'
{
# why not a here doc?
print "
Users in database
";
print " ";
print "
";
print "
Login
Added or modified?
by user
Creator logged in as
Date
";
open (DB, "$logpath/.log") || die("Could not open $logpath/.log for tabling");
@dbarray=; # Should use a while ()
foreach $entry(@dbarray) # to avoid reading the whole thing
{ # into memory
($usen, $creatr)=split(/&/, $entry); # Take a look at
($creatir, $loggedinas)=split(/,/, $creatr);# Text::CSV
($loggedas, $day)=split(/-/, $loggedinas); # or a DB module
($daychanged, $action)=split(/¬/, $day); # while simplify
($creatr)=$creatir; # this whole mess
($loggedinas)=$loggedas;
print "
$usen
$action
$creatr
$loggedinas
$daychanged
";
}
print "
";
close(DB);
&contin; # contin? continue to what? (oooh print_footer()
# well why didn't you say so?)
}
}
sub db_viewer {
unless ($viewdbvalue eq "off") # You can't get here if it eq 'off'
# so if you really think it could
# happen die() if it does.
{
print "";
if ($viewlogvalue eq "on") # You shouldn't need to this
{
&log_viewer;
}
else
{
&contin; # aggg contin again..
}
}
sub usercreate{
unless(($viewlogvalue eq "on") || ($viewdbvalue eq "on"))
{
if($chpw eq "off") # All 3 if's and the unless
{ # can be combined and would
&checker; # probably be clearer
}
else
{
$update="'s password was changed by ";
}
if($update eq "'s password was changed by ")
{
$logupdate="Password changed";
}
else
{
$logupdate="Login created";
}
unless ($chpw eq "on")
{
print "Login $untainted_formlogin $update $untainted_name,\nunder the username $login_used,\non $date.\n";
print LOG "$untainted_formlogin&$untainted_name,$login_used-$date¬$logupdate\n";
$htp->htpasswd("$untainted_formlogin", "$untainted_formpw");
print $former;
}
if ($chpw eq "on")
{
&passwordchanger;
}
else
{
&contin;
}
}
}
sub passwordchanger{
$htp->htpasswd("$untainted_formlogin", "$untainted_formpw", "$untainted_oldpw");
if ($htp->error() eq "Apache::Htpasswd::htpasswd - Password not changed.")
{ # Just check the return value from htpasswd
print "$pwr\n$copy\n$footer";
}
else
{
# Try setting the password again? since it succeeded?
$htp->htpasswd("$untainted_formlogin", "$untainted_formpw", "$untainted_oldpw");
print "Password for user $untainted_formlogin was successfully changed. Please update your records.";
print $former;
print $footer;
print LOG "$untainted_formlogin&$untainted_name,$login_used-$date¬$logupdate\n";
}
close(LOG);
}
sub eraser{
if ($delvalue eq "yes")
{
$htp->htDelete($deluservalue);
print "Login $deluservalue been permanently removed from the personnel database by $untainted_name.";
print " ";
print "To undo this action, you must ";
print "go back to the RADB admin page and re-enter the employee mentioned above.";
print " ";
$logupdate="User deleted";
chomp($deluservalue);
chomp($nameofuser);
chomp($logupdate);
open(LOG, ">>$logpath/.log") || die("Could not open log file to add \"delete\" entry.");
print LOG "$deluservalue&$untainted_name,$login_used-$date¬$logupdate\n";
close(LOG);
print $copy;
print $footer;
}
else
{
&mainprog; # is it really the *main* program?
}
}
sub checker{
# Shouldn't this all be handled by Apache::Htpasswd?
open(DB, ">>$logpath/.htpasswd")||die("Could not open DB file for view.");
@checker=;
foreach $checker(@checker)
{
($username, $pws)=split(/:/, $checker);
if ( ($username eq $untainted_formlogin)
|| ("\L\b$username\E" eq "\L\b$untainted_formlogin\E")
|| ("\U\b$username\E" eq "\U\b$untainted_formlogin\E"))
{
print "$rej $former
$footer";
close(DB);
die("User already exists");
}
}
# Need another close here to make sure it gets closed
# because it won't usually get closed above
}
sub script{
print <RADB v1.0 modification results
SCRIPTER
}
sub heredocs{
$illegal=<Illegal login
Some information you submitted, (either your name, the login you want to create, or the password for this login), contains illegal characters, which for security are not accepted. Please Go back to the RADB admin page and try again, using only alphanumeric characters.
The password associated with user $untainted_formlogin could not be changed, as it could not be verified that you possess the authority to perform this action. Perhaps you forgot your password?
PWR
$footer = <