#!/usr/bin/perl
use CGI;
use File::Path qw(mkpath rmtree);
BEGIN {
$SIG{__DIE__} = sub {
my $msg = shift;
print "Status: 500\n";
print "Content-type: text/html\n\n";
$msg =~ s/\n/\0/g;
print "error: $msg\n";
CORE::die $msg;
}
}
$| = 1;
our $q = CGI->new;
print "Content-type: text/html\n\n";
if ($q->param('task') eq 'detect_redirect') {
print '1';
exit;
}
if ($q->param('task') eq 'exists_securelive_max_archive') {
my $username = $q->param('user');
die('No username was provided') unless $username;
die('Username is invalid') unless $username =~ /^[A-Za-z0-9]+$/;
print -e "/home/$username/securelive_max.tar.bz2";
exit;
}
if ($q->param('task') eq 'extract_securelive_max_archive') {
my $username = $q->param('user');
die('No username was provided') unless $username;
die('Username is invalid') unless $username =~ /^[A-Za-z0-9]+$/;
my $cmd = `tar -jxvf ./securelive_max.tar.bz2 -C /home/$username 2>&1`;
print $cmd;
&site_chmod("/home/$username/securelive_max", 1);
exit;
}
if ($q->param('task') eq 'delete_securelive_max_archive') {
my $username = $q->param('user');
die('No username was provided') unless $username;
die('Username is invalid') unless $username =~ /^[A-Za-z0-9]+$/;
my $del = unlink("/home/$username/securelive_max.tar.bz2");
die("Could not delete /home/$username/securelive_max.tar.bz2: $!") unless $del;
exit;
}
if ($q->param('task') eq 'exists_securelive_max_directory') {
my $username = $q->param('user');
die('No username was provided') unless $username;
die('Username is invalid') unless $username =~ /^[A-Za-z0-9]+$/;
print -e "/home/$username/securelive_max";
exit;
}
if ($q->param('task') eq 'delete_securelive_max_directory') {
my $username = $q->param('user');
die('No username was provided') unless $username;
die('Username is invalid') unless $username =~ /^[A-Za-z0-9]+$/;
rmtree("/home/$username/securelive_max", {verbose => 1});
exit;
}
if ($q->param('task') eq 'extract_sl_admin_archive') {
my $username = $q->param('user');
die('No username was provided') unless $username;
die('Username is invalid') unless $username =~ /^[A-Za-z0-9]+$/;
my $directory = $q->param('directory');
die('No directory was provided') unless $directory;
mkpath("/home/$username/$directory", {verbose => 1}) unless -e "/home/$username/$directory";
my $cmd = `tar -jxvf ./sl_admin.tar.bz2 -C /home/$username/$directory 2>&1`;
print $cmd;
&disable_mod_security("/home/$username/$directory/sl_admin");
&site_chmod("/home/$username/$directory/sl_admin", 1);
exit;
}
if ($q->param('task') eq 'delete_sl_admin_archive') {
my $username = $q->param('user');
die('No username was provided') unless $username;
die('Username is invalid') unless $username =~ /^[A-Za-z0-9]+$/;
my $del = unlink("/home/$username/sl_admin.tar.bz2");
die("Could not delete /home/$username/sl_admin.tar.bz2: $!") unless $del;
exit;
}
if ($q->param('task') eq 'delete_sl_admin_directory') {
my $username = $q->param('user');
die('No username was provided') unless $username;
die("Username ($username) is invalid") unless $username =~ /^[A-Za-z0-9]+$/;
my $directory = $q->param('directory');
die('No directory was provided') unless $directory;
die("directory (/home/$username/$directory) is invalid") unless -e "/home/$username/$directory";
rmtree("/home/$username/$directory/sl_admin", {verbose => 1});
exit;
}
if ($q->param('task') eq 'delete_self') {
my $del = unlink($ENV{'SCRIPT_FILENAME'});
die("Could not delete $ENV{'SCRIPT_FILENAME'}: $!") unless $del;
exit;
}
if ($q->param('task') eq 'configure_install') {
my $directory = $q->param('directory');
my $user = $q->param('user');
my $domain = $q->param('domain');
my $unified_directory = "/home/$user/$directory";
$unified_directory =~ s/\/\//\//g;
&create_authenticator($user);
if (-e "$unified_directory/.htaccess") {
&install_htaccess($unified_directory, $user, 1);
}
else {
my $fh;
open ($fh, '>', "$unified_directory/.htaccess") || die($!);
print $fh "<IfModule mod_suphp.c>\n";
print $fh "\tsuPHP_ConfigPath $unified_directory\n";
print $fh "</IfModule>\n";
print $fh "AddHandler application/x-httpd-php5 .php5 .php4 .php .php3 .php2 .phtml\n" unless -e '/opt/hosting/VERSION'; # LPCP servers are all PHP 5
close $fh;
&install_php_ini($unified_directory, $user, "$unified_directory/.htaccess");
}
foreach my $entry (&find_htaccess($unified_directory)) {
next unless $entry;
&install_htaccess($entry, $user, 0);
}
exit;
}
if ($q->param('task') eq 'configure_delete') {
my $directory = $q->param('directory');
my $user = $q->param('user');
my @exclude = $q->param('exclude_path');
my $unified_directory = "/home/$user/$directory";
$unified_directory =~ s/\/\//\//g;
foreach my $entry (&find_htaccess($unified_directory)) {
next unless $entry;
my $safe_path = 1;
foreach my $path (@exclude_path) {
$safe_path = 0 if $entry =~ /$path/;
}
&delete_htaccess($entry, $user) if $safe_path;
}
exit;
}
if ($q->param('task') eq 'enable_domain') {
my $user = $q->param('user');
my $domain = $q->param('domain');
&enable_domain($user, $domain);
exit;
}
if ($q->param('task') eq 'delete_domain') {
my $user = $q->param('user');
my $domain = $q->param('domain');
&delete_domain($user, $domain);
exit;
}
sub disable_mod_security {
my ($dir) = @_;
my $fh;
open ($fh, '>>', "$dir/.htaccess") || die($!);
print $fh "RewriteEngine off\n";
print $fh "<IfModule mod_security.c>\n";
print $fh "\tSecFilterEngine Off\n";
print $fh "\tSecFilterScanPOST Off\n";
print $fh "</IfModule>\n";
close $fh;
}
sub site_chmod {
my ($start_dir, $chmod_start) = @_;
opendir(DIR, $start_dir) || die "$start_dir: $!";
my @files = grep {!-d "$start_dir\/$_"} readdir(DIR);
closedir DIR;
opendir(DIR, $start_dir) || die "$start_dir: $!";
my @folders = grep {-d "$start_dir\/$_"} readdir(DIR);
closedir DIR;
if ($chmod_start) {
chmod 0755, $start_dir;
}
foreach my $file (sort @files) {
$file =~ s/\"/\\\"/i;
$file = "$start_dir\/$file";
if ($file =~ /\.pl$/ || $file =~ /\.cgi$/) {
chmod 0755, $file;
}
else {
chmod 0644, $file;
}
}
foreach my $folder (sort @folders) {
if ($folder !~ /^\.\.?$/) {
$folder =~ s/\"/\\\"/i;
$folder = "$start_dir\/$folder";
chmod 0755, $folder;
&site_chmod($folder, 0);
}
}
}
sub find_htaccess {
my ($start_dir) = @_;
print "information: Scanning for additional .htaccess files\n";
my @htaccess = &dir ($start_dir);
print "information: Scan for additional .htaccess files complete\n";
return @htaccess;
}
sub enable_domain {
my ($user, $domain) = @_;
my $file = "/home/$user/securelive_max/lunarpages.php";
my $fh;
unless (-e $file) {
&create_authenticator($user);
}
chmod 0644, $file;
open($fh, "<$file") || die("Unable to open $file: $!");
my @lines = <$fh>;
close ($fh);
foreach (@lines) {
next unless $_ =~ /\$domains = array\((.*?)\)/;
my @domains = split(/,\s?/, $1);
my $found = 0;
foreach my $entry (@domains) {
$entry =~ s/\"//g;
$found = 1 if $entry eq $domain;
$entry = "\"$entry\"";
last if $found;
}
push (@domains, "\"$domain\"") unless $found;
$_ = '$domains = array(' . join(',', sort(@domains)) . ');' . "\n";
}
open($fh, ">$file") || die("Unable to open $file: $!");
print $fh join('', @lines);
close($fh);
}
sub delete_domain {
my ($user, $domain) = @_;
my $file = "/home/$user/securelive_max/lunarpages.php";
my $fh;
return unless -e $file;
chmod 0644, $file;
open($fh, "<$file") || die("Unable to open $file: $!");
my @lines = <$fh>;
close ($fh);
foreach (@lines) {
next unless $_ =~ /\$domains = array\((.*?)\)/;
my @domains = split(/,\s?/, $1);
my @new_domains;
foreach my $entry (@domains) {
$entry =~ s/\"//g;
if ($entry ne $domain) {
push(@new_domains, "\"$entry\"");
}
}
$_ = '$domains = array(' . join(',', sort(@new_domains)) . ');' . "\n";
}
open($fh, ">$file") || die("Unable to open $file: $!");
print $fh join('', @lines);
close($fh);
}
sub create_authenticator {
my ($user) = @_;
my $file = "/home/$user/securelive_max/lunarpages.php";
my $fh;
return if -e $file;
chmod 0644, $file;
print "information: Creating authentication file\n";
open($fh, ">$file") || die("Unable to open $file: $!");
print $fh '<?php', "\n";
print $fh '$domain = $_SERVER["HTTP_HOST"];', "\n";
print $fh '$domains = array();', "\n";
print $fh "\n";
print $fh 'foreach ($domains as $entry) {', "\n";
print $fh "\t", 'if ($domain === $entry || stristr($domain, $entry)) {', "\n";
print $fh "\t\t", 'include("/home/', $user, '/securelive_max/sl8.php");', "\n";
print $fh "\t", '}', "\n";
print $fh '}', "\n";
print $fh '?>';
close($fh);
}
sub install_htaccess {
my ($directory, $user, $required_php) = @_;
my $file = "$directory/.htaccess";
my $fh;
print "information: Scanning .htaccess file at $file for suPHP_ConfigPath entries and PHP 5 handlers\n";
open($fh, "<$file") || die("Unable to open $file: $!");
my @lines = <$fh>;
close $fh;
my $php5 = 0;
my $php_found = 0;
my $protect_php_ini = 0;
foreach (@lines) {
if (/^suPHP_ConfigPath\s+(.+)/) {
my $phpini = $1;
$phpini =~ s/\s+$//;
print "information: Found suPHP_ConfigPath entry in $file, pointing to $phpini/php.ini\n";
&install_php_ini($phpini, $user, $file);
$required_php = 1 if $phpini eq $directory;
$php_found = 1;
}
if (/^AddHandler application\/x-httpd-php5/) {
print "information: Found PHP 5 handler entry\n";
$php5 = 1;
}
if (/^\<Files php\.ini\>/) {
print "information: Found php.ini protection line";
$protect_php_ini = 1;
}
$_ = "$_\n" unless substr($_,-1) eq "\n"; # Add a newline to the end of a line that doesn't have one
}
$php5 = 1 if -e '/opt/hosting/VERSION'; # LPCP servers are all PHP 5
if ($required_php) {
if (!$php_found) {
print "information: No suPHP_ConfigPath entry found in $file, where required\n";
print "information: Adding suPHP_ConfigPath entry to $file, pointing to $directory/php.ini\n";
unshift(@lines, "</IfModule>\n");
unshift(@lines, "suPHP_ConfigPath $directory\n");
unshift(@lines, "<IfModule mod_suphp.c>\n");
&install_php_ini($directory, $user, $file);
}
if (!$php5) {
print "information: No PHP 5 handler entry found in $file, where required\n";
print "information: Adding PHP 5 handler entry to $file\n";
unshift(@lines, "AddHandler application/x-httpd-php5 .php5 .php4 .php .php3 .php2 .phtml\n");
}
if (!$protect_php_ini) {
print "information: No php.ini protection found in $file, where required\n";
print "information: Adding php.ini protection entries to $file\n";
push(@lines, "<Files php.ini>\n");
push(@lines, " Order allow,deny\n");
push(@lines, " Deny from all\n");
push(@lines, "</Files>\n");
}
chmod 0644, $file;
open ($fh, ">$file") || die("Unable to open $file: $!");
print $fh @lines;
close $fh;
}
print "information: Scan of .htaccess file at $file complete\n";
}
sub install_php_ini {
my ($directory, $user, $ref) = @_;
my $file = "$directory/php.ini";
my $fh;
print "information: Scanning php.ini file at $file for SecureLive auto_prepend entries\n";
my @lines;
if (-e $file) {
open($fh, "<$file") || die("Unable to open $file (from $ref): $!");
@lines = <$fh>;
close $fh;
}
my $auto_append_found = 0;
foreach (@lines) {
if (/auto_prepend_file = \/home\/$user\/securelive_max\/lunarpages.php/) {
print "information: Found SecureLive auto_prepend entry in $file\n";
$auto_append_found = 1;
}
elsif (
/auto_prepend_file = \/home\/$user\/securelive_max/) {
print "information: Found SecureLive auto_prepend entry in $file for a different installation, skipping\n";
$auto_append_found = 1;
}
}
if (!$auto_append_found) {
print "information: No SecureLive auto_prepend entry found in $file, where required\n";
print "information: Adding SecureLive auto_prepend entry to $file\n";
chmod 0644, $file;
open ($fh, ">$file") || die("Unable to open $file (from $ref): $!");
unshift(@lines, "auto_prepend_file = /home/$user/securelive_max/lunarpages.php\n");
print $fh @lines;
close $fh;
}
print "information: Scan of php.ini file at $file complete\n";
}
sub delete_htaccess {
my ($directory, $user) = @_;
my $file = "$directory/.htaccess";
my $fh;
print "information: Scanning .htaccess file at $file for suPHP_ConfigPath entries\n";
chmod 0644, $file;
open($fh, "<$file") || die("Unable to open $file: $!");
my @lines = <$fh>;
close $fh;
open($fh, ">$file") || die("Unable to open $file: $!");
foreach (@lines) {
if (/^suPHP_ConfigPath\s+(.+)/) {
my $directory = $1;
print "information: Found suPHP_ConfigPath entry in $file, pointing to $1/php.ini\n";
&delete_php_ini($directory, $user);
if (!-e "$directory/php.ini") {
#After the edit, a php.ini file can be removed, clean up the .htaccess as well
if (scalar(@lines) == 1) {
print "information: Removing suPHP_ConfigPath entry as php.ini file at $1 has been removed\n";
print "information: Removing empty .htaccess $file\n";
close($fh);
unlink($file);
}
}
else {
print $fh $_;
}
}
else {
print $fh $_;
}
}
close($fh);
print "information: Scan of .htaccess file at $file complete\n";
}
sub delete_php_ini {
my ($directory, $user) = @_;
my $file = "$directory/php.ini";
my $fh;
print "information: Scanning php.ini file at $file for SecureLive auto_prepend entries\n";
my @lines;
if (-e $file) {
open($fh, "<$file") || die($!);
@lines = <$fh>;
close $fh;
}
if (scalar(@lines) == 1 && $lines[0] =~ /auto_prepend_file = \/home\/$user\/securelive_max\/lunarpages.php/) {
print "information: Found SecureLive auto_prepend entry in $file\n";
print "information: Removing SecureLive auto_prepend entry from $file\n";
print "information: Removing empty php.ini $file\n";
my $del = unlink($file);
}
else {
chmod 0644, $file;
open ($fh, ">$file") || die($!);
foreach (@lines) {
next unless $_;
next if /^\s+$/;
if (/auto_prepend_file = \/home\/$user\/securelive_max\/lunarpages.php/) {
print "information: Found SecureLive auto_prepend entry in $file\n";
print "information: Removing SecureLive auto_prepend entry from $file\n";
next;
}
else {
print $fh "$_" if $_;
}
}
close $fh;
}
if ((stat($file))[7] == 0) {
print "information: Removing SecureLive auto_prepend entry from $file\n";
print "information: Removing empty php.ini $file\n";
my $del = unlink($file);
}
print "information: Scan of php.ini file at $file complete\n";
}
sub dir {
my ($start_dir) = @_;
return if -l $start_dir;
my @results;
if (opendir(DIR, $start_dir)) {
my @files = grep {!-d "$start_dir\/$_"} readdir(DIR);
rewinddir DIR;
my @folders = grep {-d "$start_dir\/$_"} readdir(DIR);
foreach my $file (sort @files) {
if ($file eq '.htaccess') {
print "information: Found .htaccess at $start_dir/.htaccess\n";
push(@results, $start_dir);
}
}
foreach my $folder (sort @folders) {
if ($folder !~ /^\.\.?$/) {
$folder =~ s/\"/\\\"/i;
push(@files, dir("$start_dir/$folder"));
}
}
closedir DIR
}
return @results;
}
42;
Comments
0 B
|👍
/👎
0 B
|👍
/👎