Viewing File: /usr/local/cpanel/whostmgr/docroot/cgi/cwaf_sharedlib.pl

use CGI qw(:standard);
use JSON;
use POSIX qw(strftime);
use Template;

BEGIN { require '/etc/cwaf/use_lib.pl' if -f '/etc/cwaf/use_lib.pl'; }
use Comodo::CWAF::ModSecurity;# qw(%msconf set_modsec_cwaf_config);
use Comodo::CWAF::Main;# qw(%conf do_log call_wrapper get_sudo is_cpanel is_plesk is_directadmin is_litespeed);
use Comodo::CWAF::ClientAPI;# qw(test_credentials);
use Comodo::CWAF::cWatch;

use strict;

our ($json_out, %response, $pr_name, %conf, %msconf, %prm);
################################### FUNCTION #####################################
# do_response($req (, $ans))
# Create an answer
# If $ans is defined prepare JSON response from %json_out
sub do_response($;$) {
  my ($req, $ans) = @_;
  my ($coder);
  
  if( defined($ans)) {
    $coder = JSON->new->ascii->pretty;
    $ans = $coder->encode($json_out);
    $response{'mime'} = 'application/json'
    }
  else {
  $ans = $response{'errmsg'};
  $response{'mime'} = 'text/plain';
  }

  print $req->header(
    -type           => $response{'mime'},
    -status         => $response{'status'},
    -Content_length => length($ans),
    -charset        => 'utf-8');

  print $ans;
  exit(0);
  }

# json_decode($str)
# Decode JSON string to object
# RETURN: decoded string
sub json_decode($) {
  my ($data) = @_;
  my $coder = JSON->new->ascii->pretty;
  return $coder->decode($data);
}

# get_params($req, $params_hash)
# get cgi parameters depending of installed web platform (cpanel, plesk etc)
# and store to $params_hash
# RETURN: 0 or 1
sub get_params($$) {
  my ($req, $phash) = @_;

  # pass Plesk parameters
  if(&is_plesk() || &is_directadmin() || &is_webmin()) {
    eval "use URI::Escape";
    die "Can't load URI::Escape" if ($@);

    # Plesk and DirectAdmin will get params from stdin passed by wrapper
    # Webmnin reads params from stdin
    my $line = '';

    $line = <> if &is_plesk();
    $line = $ENV{'POST'} if &is_directadmin();
    $line = webmin_post_arguments() if &is_webmin();

    my @params = split("&", $line);
    foreach my $param (@params) {
        $param =~ s/^\s+|\s+$//g;

        my ($key, $val) = split("=", $param, 2);
        $val = '' unless(defined $val);
        $val =~ s/\+/ /g;
        $phash->{$key} = uri_unescape($val);
    }
    return 1;
  } else {
    # usual CGI parameters
    %{$phash} = $req->Vars;
    return 1;
  }
}

# log some message
# do_log($message [, $debug_level])
sub do_log_stderr($;$) {
  my ($msg, $verb) = @_;
  my ($cdate);
 
  $verb = 10 unless(defined($verb));
  return if($verb > $conf{'debug'});
  $cdate = strftime("%d/%m/%y %H:%M:%S", gmtime);
  print STDERR "$cdate $pr_name\[$$\]  $msg\n";
  }

################################### MAIN INTERFACE ################################
# output for main interface
# used in cPanel, Plesk etc
# print_main_interface()
sub print_main_interface() {
my ($VERSION,%tt_vars,$var,%userdata,$LS_VERSION);

$VERSION = get_client_version();

$var = get_web_platform();
# check if platform supported by plugin
if($var =~ /Unknown web platform/) {
    print "<div>Sorry, can't load web-platform plugin. Reason: $var</div>";
    exit(1);
}

$tt_vars{'main'}{'cwaf_platform'} = $var;

# get apache virtualhosts(users,domains,ports) & mod_security information(version,path to config)
# and save them to $tt_vars(template hash)
get_modsec_info( \%{ $tt_vars{'main'} } );
# update info with LiteSpeed variables
if(&is_litespeed()) {
  update_litespeed_info( \%{ $tt_vars{'main'} } );
  $LS_VERSION = $tt_vars{'main'}{'httpd_version'};
  $LS_VERSION =~ s/ Enterprise//;
  $tt_vars{'main'}{'ls_support_ctl_removebyid'} = test_version('5.1.13', $LS_VERSION);
}

$tt_vars{'main'}{'cwaf_plugin_version'} = $VERSION;

# save current plugin version
$tt_vars{'main'}{'cwaf_plugin_version'} = $VERSION;
($tt_vars{'main'}{'cwaf_plugin_remote_version'}, $tt_vars{'main'}{'x_error_reason'}) = &get_available_version();
$tt_vars{'main'}{'new_version_available'} = test_version($VERSION, $tt_vars{'main'}{'cwaf_plugin_remote_version'});

# check if cPanel is present
$tt_vars{'main'}{'cpanel'} = &is_cpanel() ? 1 : 0;

# check if DirectAdmin is present
$tt_vars{'main'}{'directadmin'} = &is_directadmin() ? 1 : 0;

# check if virtualmin is present
$tt_vars{'main'}{'virtualmin'} = &is_virtualmin() ? 1 : 0;

# check if this is standalone install
$tt_vars{'main'}{'standalone'} = &is_standalone() ? 1 : 0;

# save all configuration data
$tt_vars{'conf'} = \%conf;
$tt_vars{'conf'}{'tname'} = &get_crontab();

# test if this first run for wizard
$tt_vars{'conf'}{'firstrun'} = (-f "$conf{'cwaf_path'}/$conf{'cwaf_firstrun_flag'}") ? 1 : 0;

# save modsec configuration data
$tt_vars{'msconf'} = \%msconf;
# custom modsec configuration found
$tt_vars{'modsec'}{'custom_config'} = modsec_config_changed();
# modsec family (2, 3 etc)
$tt_vars{'modsec'}{'family'} = $conf{'modsec_family'};
  
# save rules version  
$tt_vars{'rules'}{'local_version'} = get_local_rules_version();
($tt_vars{'rules'}{'remote_version'}, $tt_vars{'rules'}{'x_error_reason'}) = get_remote_rules_version();

# draw button by default
$tt_vars{'feedback'}{'button_enable'} = ( $conf{'cwaf_login'} eq 'nologin' && &is_directadmin() ) ? 0 : 1;

# test if restore of user conf is available
$tt_vars{'user'}{'restore_available'} = (-f "$conf{'cwaf_path'}/$conf{'cwaf_backup_file'}") ? 1 : 0;

# if set local version then use it as feedback version  
$tt_vars{'feedback'}{'version'} = $tt_vars{'rules'}{'local_version'} ? $tt_vars{'rules'}{'local_version'} : $tt_vars{'rules'}{'remote_version'};

# if can't get local and remote rules version - set version to 0
$tt_vars{'feedback'}{'version'} = $tt_vars{'feedback'}{'version'}  ? $tt_vars{'feedback'}{'version'} : 0;

# try to check that remote rules version more then local rules version
#$var = version->parse($tt_vars{'rules'}{'local_version'});
#$tt_vars{'rules'}{'new_version_available'} = ($var < $tt_vars{'rules'}{'remote_version'})  ? '1' : '0';
$tt_vars{'rules'}{'new_version_available'} = test_version($tt_vars{'rules'}{'local_version'}, $tt_vars{'rules'}{'remote_version'});

#check backup directory exists
$var = get_backupdir();
$tt_vars{'rules'}{'restore_available'} = ( -r "$var/rules/rules.dat" ) ? 1 : 0;

# get userdata
&get_userdata_filenames(\%userdata);
$tt_vars{'userdata'} = \%userdata;

# get custom user rules
$var = &get_user_rules();
$tt_vars{'userdata'}{'custom_rules'} = $var ? $var : '';

# proccess template
my $tt = Template->new( { INCLUDE_PATH => $conf{'cgi_dir'} . '/cwaf/tpl'} ) ||  do_log("ERROR: template ". $Template::ERROR,1);
$tt->process('index.html',\%tt_vars)  || die do_log("ERROR: template ". $tt->error(),1);

}

################################### CGI INTERFACE ################################
# handling of main cgi
# used in cPanel, Plesk etc
# print_cgi_main()
sub print_cgi_main() {
my (@content, $filename, $var, $ext, $fname);

#default response
%response = (
            'mime'      => 'text/plain',
            'status'    => '200 OK',
            'errmsg'    => 'unknown'
            );

$json_out = {'status' => 1, 'errmsg' => 'OK'};


# create empty CGI object for webmin or read data for other webpanels
my $req = &is_webmin() ? CGI->new("") : CGI->new;
&get_params($req, \%prm);

# no action. why?
unless(defined($prm{'action'})) {
  $response{'status'} = '412 Precondition Failed';
  $response{'errmsg'} = 'action is undefined';
  do_response($req);
  exit;
  }

# update configuration file main.conf 
############################################
if( $prm{'action'} eq "update_config" ) {
  
  if ($prm{'tname'}) {
    &set_crontab($prm{'tname'});
  }
  
  # old password if password was not changed
  $prm{'cwaf_passwd'} = $conf{'cwaf_passwd'} if( (!defined($prm{'cwaf_passwd'})) || ($prm{'cwaf_passwd'} eq '') );
  
  my $creds_changed = 0;
  # delete cookie if password was changed
  if (defined ($prm{'cwaf_passwd'}) && ($conf{'cwaf_passwd'} ne $prm{'cwaf_passwd'})) {
    unlink $conf{'http_cookie_file'};
    $creds_changed = 1;
  }
  if (defined ($prm{'cwaf_login'}) && ($conf{'cwaf_login'} ne $prm{'cwaf_login'})) {
    unlink $conf{'http_cookie_file'};
    $creds_changed = 1;
  }
  if($creds_changed) {
     my ($var, $msg) = test_credentials($prm{'cwaf_login'}, $prm{'cwaf_passwd'});

    unless($var) {
      $json_out = {'status' => 0, 'errmsg' => "Wrong credentials. <br>Server return: $msg"};
      do_response($req, 1);
    }
  }
  
  # check logs directory
  if( defined($prm{'log_dir'}) && $prm{'log_dir'} ne $conf{'log_dir'} ) {
      unlink "$conf{'cwaf_path'}/logs";
      &call_wrapper("create_logdir $prm{'log_dir'}");
      symlink "$prm{'log_dir'}", "$conf{'cwaf_path'}/logs";
  }

  # modify etc/main.conf
  if( set_main_cwaf_config(\%prm) ) {
    $json_out->{'data'} = "successful update";
    }
	else {
		$json_out = {'status' => 0, 'errmsg' => "can't save configuration, check permissions"};
		}

  do_response($req, 1);
}

# run updater
############################################
elsif( $prm{'action'} eq "run_updater" ) {

  # directadmin rules update
  if(&is_directadmin()) {
    call_wrapper('da_update_rules');
    do_response($req, 1);
  }

    # for other platform run updater
    unless ( -x "$conf{'cwaf_path'}/$conf{'updater_bin'}" ) {
        $json_out = {'status' => 0, 'errmsg' => "updater script not found or not executable"};
        do_response($req, 1);    
    } else {
        system($conf{'cwaf_path'} . '/' . $conf{'updater_bin'} . " --wpanel >/dev/null &");
    }

    if($?) {
      $json_out = {'status' => 0, 'errmsg' => "can't execute updater"};
      do_response($req, 1);    
      }

  do_response($req, 1);
  }

# run user config backup
############################################
elsif( $prm{'action'} eq "user_conf_backup" ) {
  system("mv $conf{'cwaf_path'}/etc/yml $conf{'cwaf_path'}/etc/excludes >/dev/null 2>&1");
  $var = `cd $conf{'cwaf_path'} && \
tar -zchf $conf{'cwaf_path'}/$conf{'cwaf_backup_file'} --exclude='*.backup' --exclude='*.conf-bak' --exclude='scheme.yml' --exclude='version.dat' etc 2>&1`;
  system("mv $conf{'cwaf_path'}/etc/excludes $conf{'cwaf_path'}/etc/yml >/dev/null 2>&1");
  if($var ne '') {
    system("rm -rf $conf{'cwaf_path'}/$conf{'cwaf_backup_file'} >/dev/null 2>&1");
    $var =~ s/\n/<br>\n/g;
    $json_out = {'status' => 0, 'errmsg' => "Can't backup user configuration: $var"};
  }
  do_response($req, 1);
}
# run user config restore
############################################
elsif( $prm{'action'} eq "user_conf_restore" ) {
  $var = `cd $conf{'cwaf_path'} && \
tar -zxf $conf{'cwaf_path'}/$conf{'cwaf_backup_file'} 2>&1 && \
cp -f $conf{'cwaf_path'}/etc/excludes/* $conf{'cwaf_path'}/etc/yml 2>&1 && \
rm -rf $conf{'cwaf_path'}/etc/excludes`;
# delete backup file (rm -f $conf{'cwaf_backup_file'})
  if($var ne '') {
    $var =~ s/\n/<br>\n/g;
    $json_out = {'status' => 0, 'errmsg' => "Can't restore user configuration: $var"};
  }
  do_response($req, 1);
}

# run client updater
############################################
elsif( $prm{'action'} eq "run_client_updater" ) {

  if(&is_cpanel() || &is_webmin()) {
    $filename = $conf{'cwaf_path'} . '/' . $conf{'client_updater_bin'};
  } else {
    $filename = $conf{'cwaf_path'} . '/'. $conf{'cwaf_wrapper_bin'};
  }

  unless( -x $filename ) {
      $json_out = {'status' => 0, 'errmsg' => "client updater script not found or not executable"};
      do_response($req, 1);    
  } else {
      if(&is_cpanel() || &is_webmin()) {
          $var = $filename . ' --wpanel >/dev/null &';
      } else {
          $var = &get_sudo()." $filename" . ' update_client >/dev/null &';
      }
      do_log("Executing: $var");
      system("$var");
  }

  if($?) {
    $json_out = {'status' => 0, 'errmsg' => "can't execute client updater"};
    do_response($req, 1);    
    }
  
  do_response($req, 1);    
  }

# get updater log
############################################
elsif( $prm{'action'} eq "get_updater_log") {
  $var = $conf{'log_dir'} . '/' . $conf{'updater_log'};
  
  if(get_filecontent($var, \@content,1) ) {
    $json_out->{'data'} = \@content;
    do_response($req, 1);    
    }
  
  $json_out = {'status' => 0, 'errmsg' => "can't read updater log"};
  do_response($req, 1);    
  }

# restore rules, copy from tmp to rules directory
############################################
elsif( $prm{'action'} eq "run_rules_restore" ) {
  if( make_restore_rules() ) {
		# re-create exclude configuration files
		my ($status,$errmsg) = create_exclude_list(undef,1);
		
		if($status) {
			$json_out->{'data'} = "Previous version of rules has been restored";
			}
		else	{
			$json_out = {'status' => 0, 'errmsg' => $errmsg};
			}
    do_response($req, 1);   
    }
  
  $json_out = {'status' => 0, 'errmsg' => "can't restore previous version of rules"};
  do_response($req, 1);
  }

# send feedback
############################################
elsif( $prm{'action'} eq "run_feedbacksend" ) {
  # TODO: check for $req AND %jreq issues
  my (%jreq, %jresp);

  # collect errors 
  $var = [];

  push(@$var, "feedback type is undefined") unless($prm{'fb_short'});
  push(@$var, "empty feedback message") unless($prm{'fb_msg'});

  # if rules version doesn't set -> prepare return message   
  unless($prm{'fb_rules_version'}) {
    push(@$var, "rules version is undefined");
    }
  # if version entered, check it
  else {
    push(@$var, "invalid version format") unless($prm{'fb_rules_version'} =~ /^\d+\.\d+$/);
    }

  # if prepared messages exists -> print it & exit      
  if(@$var) {
    $json_out = {'status' => 0, 'errmsg' => join(',<br>', @$var)};
    do_response($req, 1);
    }
    
  %jreq = (
    'version'           =>    $prm{'fb_rules_version'},
    'client_version'    =>    $prm{'fb_client_version'},
    'short'             =>    $prm{'fb_short'},
    'msg'               =>    $prm{'fb_msg'},
    );

  $jreq{'rid'} = $prm{'fb_rule_id'} if($prm{'fb_rule_id'});
  $jreq{'act'} = 'feedback';
  
  if(get_cwafapi_json(\%jreq,\%jresp)) {
    $json_out = {'status' => $jresp{'status'}, 'errmsg' => $jresp{'emsg'}};
    do_response($req, 1);   
    }

  $json_out = {'status' => 0, 'errmsg' => "feedback hasn't been sent"};
  do_response($req, 1);
  }

# set userdata
############################################
elsif( $prm{'action'} eq "set_userdata" ) { 

  # remove action to not to mess with filename
  delete $prm{'action'};

  # save custom user rules
    if ( defined($prm{'userdata_custom_rules'}) && ($prm{'userdata_custom_rules'} ne "") ) {
        unless(open (OUT,">$conf{'cwaf_path'}/etc/httpd/custom_user.conf")) {
          $json_out = {'status' => 0, 'errmsg' => "can't save changes in custom rules file"};
          do_response($req, 1);
        }

      $prm{'userdata_custom_rules'} =~ s/\r//g;
      print  OUT $prm{'userdata_custom_rules'};
      close(OUT);
    }
  delete $prm{'userdata_custom_rules'};

  # save userdata
  foreach my $file (keys %prm) {
    if ( ( -e "$conf{'cwaf_path'}/etc/userdata/$file" ) && ($prm{$file} ne "") ) {
        unless(open (OUT,">$conf{'cwaf_path'}/etc/userdata/$file")) {
          $json_out = {'status' => 0, 'errmsg' => "can't save changes in userdata file $file"};
          do_response($req, 1);
        }

      $prm{$file} =~ s/\r//g;
      print  OUT $prm{$file};
      close(OUT);
    }
  }


  do_response($req, 1);
  }

# update mod_security configuration file
############################################
elsif( $prm{'action'} eq "update_msconfig" ) {
	# modify etc/main.conf
  if( &set_modsec_cwaf_config(\%prm) ) {
     $json_out->{'data'} = "successful update";
     &call_wrapper("create_logdir $prm{'SecAuditLogStorageDir'}") if (lc($prm{'SecAuditLogType'}) eq 'concurrent');
    }
	else {
		$json_out = {'status' => 0, 'errmsg' => "can not apply configuration, check permissions or mod_security syntax"};
		}

  do_response($req, 1);    
}

# get list of disabled domains
############################################
elsif($prm{'action'} eq "disabled_domains") {
  # get list for all and disabled domain
  $json_out->{'list'} = &get_domainlist;
  $json_out->{'disabled'} = &get_disabled_domainlist;

  # success
  do_response($req, 1);
  }

# update list of disabled domains
############################################
elsif($prm{'action'} eq "update_disabled_domains") {

  if(defined($prm{'disabled'})) {
      my $data = json_decode($prm{'disabled'});
      my ($status, $errmsg) = &set_disabled_domainlist($data);

      if($status) {
         # success, try to restart apache httpd      
        for my $i (1..3) {
          # success restart
           last if( run_restart_apache() );

          # broken 1st restart
          $json_out = {'status' => 0, 'errmsg' => 'can not restart httpd, delete domain exclude list'};
          # delete all exclude config files
          map {
                ($ext) = $_ =~ /(\.[^.]+)$/;
                ($fname) = $_ =~ m{([^/]+)$};
                do_log("try to delete file $_, extension $ext", 10);
                #skip backup files
                unlink($_) unless (($ext eq ".backup")||($fname eq "00_blank.conf"));
              } <$conf{'cwaf_path'}/etc/httpd/domains/*>;
          }
      } else {
         $json_out = {'status' => 0, 'errmsg' => "can't save disabled domains: $errmsg"};
      }
  } else {
      $json_out = {'status' => 0, 'errmsg' => "no domains provided"};
      }
  do_response($req, 1);
}

else {
  $response{'errmsg'} = 'bad action';
  $response{'status'} = '400 Bad Request';
  do_response($req);
  }   

}

################################### CATALOG INTERFACE ################################
# handling of catalog cgi
# used in cPanel, Plesk etc
# print_catalog_main()
sub print_catalog_main() {
my ($data, $catalog);

%response = ('mime' => 'text/plain',
            'status' => '200 OK',
            'errmsg' => 'unknown');

$json_out = {'status' => 1, 'errmsg' => 'OK'};


# create empty CGI object for webmin or read data for other webpanels
my $req = &is_webmin() ? CGI->new("") : CGI->new;
#%prm = $req->Vars;
&get_params($req, \%prm);

# no action. why?
unless(defined($prm{'action'})) {
  $response{'status'} = '412 Precondition Failed';
  $response{'errmsg'} = 'action is undefined';
  do_response($req);
  exit;
  }

# init object
$catalog = Comodo::CWAF::CatalogUpdate->new('yml_path' => $conf{'cwaf_path'}.'/etc/yml',
                                            'cache_path' => $conf{'cwaf_path'}.'/tmp/CACHE',
                                            'verbose' => ( $conf{'debug'} eq 11 ) ? 1 : 0,
                                            'cpanel_log' => &is_cpanel() );

# process request
if($prm{'action'} eq "get_category_list") {
  $data = $catalog->list_category_by('domain' => $prm{'domain'});

  unless(defined($data)) {
    $json_out = {'status' => 0, 'errmsg' => $catalog->error};
    do_response($req, 1);
    }
    
  $json_out->{'data'} = $data;
  $json_out->{'sort'} = [ sort(keys %{$data->{'list'}}) ];
  do_response($req, 1);
  }

elsif($prm{'action'} eq "get_group_list") {
  $data = $catalog->list_group_by('category' => $prm{'category'}, 'domain' => $prm{'domain'});

  unless(defined($data)) {
    $json_out = {'status' => 0, 'errmsg' => $catalog->error};
    do_response($req, 1);
    }

  $json_out->{'data'} = $data;
  $json_out->{'sort'} = [ sort(keys %{$data->{'list'}}) ];
  do_response($req, 1);
  }

elsif($prm{'action'} eq "get_rule_list") {
  $data = $catalog->list_rule_by('category' => $prm{'category'}, 'group' => $prm{'group'}, 'domain' => $prm{'domain'});

  unless(defined($data)) {
    $json_out = {'status' => 0, 'errmsg' => $catalog->error};
    do_response($req, 1);
    }
    
  $json_out->{'data'} = $data;
  $json_out->{'sort'} = [ sort(keys %{$data->{'list'}}) ];
  do_response($req, 1);
  }

elsif($prm{'action'} eq "get_rule_by_id") {
  $data = $catalog->find_rule_by('id' => $prm{'ruleid'});
  my $parent = $data->{'parent'};

  if(defined($data->{'category'}) && defined($data->{'group'})) {
    $data = $catalog->list_rule_by('category' => $data->{'category'}, 'group' => $data->{'group'}, 'domain' => $prm{'domain'});
    } else {
      $json_out->{'not_found'} = 1;
    }

  unless(defined($data)) {
    $json_out = {'status' => 0, 'errmsg' => $catalog->error};
    do_response($req, 1);
    }

  $json_out->{'data'} = $data;
  $json_out->{'parent'} = $parent;
  $json_out->{'sort'} = [ sort(keys %{$data->{'list'}}) ];
  do_response($req, 1);
  }
elsif($prm{'action'} eq "update_list") {
  # update exclude list for some domain
  my $var;
  my $ext;
  my $fname;
  my $data = json_decode($prm{'updates'});
  
  # update yaml exclude list for some domain
  $var = $catalog->update_exclude_list_by(%{$data});
  unless($var) {
    $json_out = {'status' => 0, 'errmsg' => $catalog->error};
    do_response($req, 1);
    }


  my ($status, $errmsg) = create_exclude_list(undef, 1);
  
  unless($status) {
    $json_out = {'status' => 0, 'errmsg' => $errmsg};
    do_response($req, 1);
    }

    # try to restart apache httpd
    for my $i (1..3) {
      # success restart
      if( run_restart_apache() ) { last; } 

      # broken 1st restart
      else {
          if($i eq 1) {

            $json_out = {'status' => 0, 'errmsg' => 'can not restart httpd, fixing exclude cache. reload page and try again'};
            # trying to fix exclude cache
            &fix_exclude_cache();
        } else {

        $json_out = {'status' => 0, 'errmsg' => 'can not restart httpd, delete domain exclude list'};
        # delete all exclude config files
        map {
              ($ext) = $_ =~ /(\.[^.]+)$/;
              ($fname) = $_ =~ m{([^/]+)$};
              do_log("try to delete file $_, extension $ext", 10);
              #skip backup files
              unlink($_) unless (($ext eq ".backup")||($fname eq "00_blank.conf"));
            } <$conf{'cwaf_path'}/etc/httpd/domains/*>;
        map {
              ($ext) = $_ =~ /(\.[^.]+)$/;
              ($fname) = $_ =~ m{([^/]+)$};
              do_log("try to delete file $_, extension $ext", 10);
              #skip backup files
              unlink($_) unless (($ext eq ".backup")||($fname eq "00_blank.conf"));
            } <$conf{'cwaf_path'}/etc/httpd/global/*>;
        }
      }
    }

  # success
  do_response($req, 1);
  }
elsif($prm{'action'} eq "domain_list") {
  # update exclude list for some domain
  $json_out->{'list'} = &get_domainlist;
  $json_out->{'disabled'} = &get_disabled_domainlist;

  # success
  do_response($req, 1);
  }
elsif($prm{'action'} eq "wizard_scheme_list") {
  # update exclude list for some domain
  $data = &wizard_scheme_list;
  unless($data) {
    $json_out = {'status' => 0, 'errmsg' => "Can't get rules scheme list"};
    do_response($req, 1);
  } 

  # success
  $json_out->{'list'} = $data;
  my %exs = &read_excludes;
  my @aex = keys (%exs);
  $json_out->{'excludes'} = \@aex;
  do_response($req, 1);
  }
elsif($prm{'action'} eq "update_firstrun") {
  unlink $conf{'cwaf_path'}.'/'.$conf{'cwaf_firstrun_flag'} if (-f $conf{'cwaf_path'}.'/'.$conf{'cwaf_firstrun_flag'});
  do_response($req, 1);
}
else {
  $response{'errmsg'} = 'bad action';
  $response{'status'} = '400 Bad Request';
  do_response($req);
  }
}

################################### CWATCH INTERFACE ################################
# handling of cwatch cgi
# used in cPanel, Plesk etc
# print_cwatch_main()
sub print_cwatch_main() {
my ($data);

%response = ('mime' => 'text/plain',
            'status' => '200 OK',
            'errmsg' => 'unknown');

$json_out = {'status' => 1, 'errmsg' => 'OK'};


# create empty CGI object for webmin or read data for other webpanels
my $req = &is_webmin() ? CGI->new("") : CGI->new;
#%prm = $req->Vars;
&get_params($req, \%prm);

# no action. why?
unless(defined($prm{'action'})) {
  $response{'status'} = '412 Precondition Failed';
  $response{'errmsg'} = 'action is undefined';
  do_response($req);
  exit;
  }

# process request
if($prm{'action'} eq "mssp_info") {
  my ($code, $content) = get_mssp_info('https://service.mssp.comodo.com/customers/createCWAFCustomer', $prm{'reginfo'});
  if($code eq 200) {
    my $data = json_decode($content);
    $json_out->{'data'} = $data;
    do_response($req, 1);
  } else {
    $json_out = {'status' => 0, 'errmsg' => $content};
    do_response($req, 1);
  }
}
elsif($prm{'action'} eq "get_mssp_info") {
  my $data = retrieve_mssp_info();
  unless ( $data ) {
    $json_out = {'status' => 1, 'errmsg' => "Network token not found"};
  } else {
      $data->{'modsec_log'} = $msconf{'SecAuditLog'};
      $json_out->{'data'} = $data;
  }
    do_response($req, 1);
}
elsif($prm{'action'} eq "save_mssp_info") {
  unless ($prm{'data'}) {
    $json_out = {'status' => 0, 'errmsg' => "MSSP data is empty"};
    do_response($req, 1);
  }
  # save mssp data
  my $data = json_decode($prm{'data'});
  unless (save_mssp_info($data) ) {
    $json_out = {'status' => 0, 'errmsg' => "Can't get MSSP info"};
  }
    do_response($req, 1);
}
elsif($prm{'action'} eq "append_mssp_info") {
  unless ($prm{'data'}) {
    $json_out = {'status' => 0, 'errmsg' => "MSSP data is empty"};
    do_response($req, 1);
  }
  # save mssp data
  my $data = json_decode($prm{'data'});
  my ($code, $msg) = prepare_mssp_logger($data);
  unless ($code ) {
    $json_out = {'status' => 0, 'errmsg' => $msg};
  }
  if($code == 2) {
    $json_out = {'status' => 2, 'warning' => $msg};
    do_log("Rsyslog problem: $msg", 1);
  }
    do_response($req, 1);
}
elsif($prm{'action'} eq "get_hostname") {
    my $data = get_hostname();
    $json_out->{'data'} = $data;
    do_response($req, 1);
}
else {
  $response{'errmsg'} = 'bad action';
  $response{'status'} = '400 Bad Request';
  do_response($req);
  }
}

################################### END FUNCTION ################################
1;
Back to Directory File Manager