#!/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 ""; 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 ""; } print "
LoginAdded or modified?by userCreator logged in asDate
$usen$action$creatr$loggedinas$daychanged




"; 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 "
"; print ""; print "Your name:  "; $counter=0; open (DB, "$logpath/.htpasswd") || die ("Could not open DB file to view."); @dbarray=; # This should all be handled by foreach $line (@dbarray) # Apache::Htpasswd { # ($htp->fetchUsers()) ($usern, $crypw) = split(/:/, $line); while ($counter == 0) { print ""; print ""; print "
"; 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.

ILLEGAL $copy= <

RADB created by and © Pine Tree Internet Solutions. Unauthorized use is prohibited.

Go back to the RADB admin page. COPY $former=<

Add another user:



Your name:  
Login you want to create/edit:       Desired password for this login:       
If changing an existing user's password, please check the “Change password” box below and enter that user's old password in this box:  
This user already exists, I'm changing the password associated with this login.  



FORMERCHGPW $pwr=<Password rejected!

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 = < Pine Tree Internet Solutions
RADB v1.0 © 2003, Pine Tree Internet Solutions.   No part of the RADB may be reproduced without explicit permission from an authorized Pine Tree Internet Solutions representative.

Powered by Apache, running on Red Hat Linux 7.3 (Valhalla) FOOTER $rej=<Login rejected

Login $untainted_formlogin is already in use, or is too similar to another existing login. Please try again.




Go back to the RADB admin page. $former;

$footer; REJECTED $copy= <

RADB created by and © Pine Tree Internet Solutions. Unauthorized use is prohibited.

Go back to the RADB admin page.

COPY }