<?php
/*
Plugin Name:        Quttera Web Malware Scanner
Plugin URI:         http://quttera.com
Description:        Web malware and vulnerability exploits scanner for WordPress.
Version:            3.5.2.22
Author:             Quttera team
Author URI:         http://quttera.com/
License:            GNU General Public License v2
*/

require_once('qtrUtils.php');
require_once('qtrConfig.php');
require_once('qtrLogger.php');
require_once('qtrAjaxHandler.php');

if(!function_exists('add_action'))
{
    exit(0);
}

/* qtr_wm_scanner */
@ini_set('max_execution_time', 30000 );
@ini_set('max_input_time', 30000 );
@ini_set('memory_limit', '2024M');
@set_time_limit(30000);


define('QUTTERA_WM_SCANNER','quttera_wm_scanner');
define('QUTTERA_WM_SCANNER_VERSION','3.5.2.22');
define('QUTTERA_URL',plugin_dir_url( __FILE__ ));


add_action( 'admin_enqueue_scripts', 'quttera_style', 1 );

add_action( 'admin_menu', 'qtr_setup_scanner_menu' );

/*
 * setup action @scanner-run_scan mapped to callback qtr_wm_scanner_ajax_run_scan
 * wp_ajax_ prefix used only for logged in users
 */ 
add_action( 'wp_ajax_scanner-run_scan', 'CQtrAjaxHandler::RunExternalScan' );

/*
 * setup action @scanner-run_internal_scan mapped to callback qtr_wm_scanner_ajax_run_internal_scan
 * wp_ajax_ prefix used only for logged in users
 */ 
add_action( 'wp_ajax_scanner-run_internal_scan', 'CQtrAjaxHandler::RunInternalScan' );

add_action( 'wp_ajax_scanner-run_heur_internal_scan', 'CQtrAjaxHandler::RunHeurInternalScan' );

add_action( 'wp_ajax_scanner-is_internal_scan_running', 'CQtrAjaxHandler::IsInternalScanNowRunning' );

add_action( 'wp_ajax_scanner-get_log_lines', 'CQtrAjaxHandler::GetLogLines' );

add_action( 'wp_ajax_scanner-clean_log', 'CQtrAjaxHandler::CleanLogLines' );

add_action( 'wp_ajax_scanner-get_stats', 'CQtrAjaxHandler::GetStats' );

add_action( 'wp_ajax_scanner-stop_internal_scan', 'CQtrAjaxHandler::StopInternalScan' );

add_action( 'wp_ajax_scanner-get_detected_threats', 'CQtrAjaxHandler::GetDetectedThreatsReport' );

add_action( 'wp_ajax_scanner-get_ignored_threats', 'CQtrAjaxHandler::GetIgnoredThreatsReport' );

add_action( 'wp_ajax_scanner-ignore_threat', 'CQtrAjaxHandler::IgnoreThreat' );

add_action( 'wp_ajax_scanner-get_file_report', 'CQtrAjaxHandler::ScannerReport' );

add_action( 'wp_ajax_scanner-show_file', 'CQtrAjaxHandler::ShowFile' );

/* 
 * return threat back to report
 */
add_action( 'wp_ajax_scanner-unignore_threat', 'CQtrAjaxHandler::RemoveFromIgnoreList' );

add_action( 'wp_ajax_scanner-clean_ignore_list', 'CQtrAjaxHandler::CleanIgnoreList');

add_action( 'wp_ajax_scanner-whitelist_threat','CQtrAjaxHandler::WhiteListThreat' );

add_action( 'wp_ajax_scanner-clean_threats_whitelist', 'CQtrAjaxHandler::CleanThreatsWhiteList');

add_action( 'wp_ajax_scanner-whitelist_file', 'CQtrAjaxHandler::WhiteListFile');

add_action( 'wp_ajax_scanner-clean_files_whitelist', 'CQtrAjaxHandler::CleanFilesWhiteList');


function quttera_style() 
{
    if(isset($_GET['page']) && is_string($_GET['page']) && preg_match('/quttera_wm_scanner/',$_GET['page']) ) 
    {
	    echo '<link rel="stylesheet" href="'. QUTTERA_URL . DIRECTORY_SEPARATOR . "CSS" . DIRECTORY_SEPARATOR . 'bootstrap.min.css" type="text/css" media="all"/>' . "\n";
    }
}


/**
 * Set up the menu item and register with hooks to print JS and help.
 */
function qtr_setup_scanner_menu() {
    /* 
     * FIXME - this image should be moved to wp.quttera.com 
     */
    $image_path = "http://wp.quttera.com/images/quttera_16x16.png";

    /***********************************************************
     *          External scanner menu and pages
     **********************************************************/
    add_submenu_page(   'quttera_wm_scanner',
                        "Quttera Web Malware Scanner", 
                        "External Scanner", 
                        "activate_plugins", 
                        "quttera_wm_scanner", 
                        "qtr_external_scan_page" );  


    $page_hook  = add_menu_page(    'Quttera Web Malware Scanner', 
                                    'Quttera',
                                    'activate_plugins',
                                    'quttera_wm_scanner', 
                                    'qtr_external_scan_page',
                                    $image_path
                            ); 

    if ( $page_hook ) 
    {
        add_action( "admin_print_styles-$page_hook", 'add_thickbox' );
        add_action( "admin_footer-$page_hook", 'qtr_load_escan_frontend' );
    }


    /***********************************************************
     *          Internal scanner menu and pages
     **********************************************************/
    $page_hook = add_submenu_page(  'quttera_wm_scanner',
                                    "Quttera Web Malware Scanner", 
                                    '<span style = "">Internal Scanner</span>',
                                    "activate_plugins", 
                                    "quttera_wm_scanner_int", 
                                    "qtr_internal_scan_page" );  
    if ( $page_hook ) 
    {
        add_action( "admin_print_styles-$page_hook", 'add_thickbox' );
        add_action( "admin_footer-$page_hook", 'qtr_load_iscan_frontend' );
    }


    /***********************************************************
     *          Heuristic Internal scanner menu and pages
     **********************************************************/
    $page_hook = add_submenu_page(  'quttera_wm_scanner',
                                    "Quttera Web Malware Scanner", 
                                    '<span style = "">Internal Scanner - High Sensitivity</span>',
                                    "activate_plugins", 
                                    "quttera_wm_scanner_heur_int", 
                                    "qtr_heur_internal_scan_page" );  
    if ( $page_hook ) 
    {
        add_action( "admin_print_styles-$page_hook", 'add_thickbox' );
        add_action( "admin_footer-$page_hook", 'qtr_load_heur_iscan_frontend' );
    }

}



/**
 * Print scripts that power paged scanning and diff modal.
 */
function qtr_load_escan_frontend() { 
    require "JS" . DIRECTORY_SEPARATOR . "escan_frontend.php";
}


function qtr_load_iscan_frontend(){
    require "JS" . DIRECTORY_SEPARATOR . "iscan_frontend.php";
}


function qtr_load_heur_iscan_frontend(){
    require "JS" . DIRECTORY_SEPARATOR . "heur_iscan_frontend.php";
}


function qtr_wm_scanner_ajax_run_scan()
{
    if(!current_user_can('manage_options'))
    {
        wp_die(__('You do not have sufficient permissions to access this page.') );
    }
	
    //check_ajax_referer( 'qtr_wm_scanner-scan' );
    $this_url = trim($_POST['_this']);        /* domain name of this server */
    $qtr_url  = trim($_POST['_qtr_url']);     /* quttera investigation server name */
     
    if( empty($this_url) )
    {
        $this_url = CQtrUtils::GetDomainName();
    }
    else if( empty($qtr_url) )
    {
        $qtr_url = "http://wp.quttera.com";
    }

    if( strpos($this_url, "://" ) != false )
    {
        $parse      = parse_url($this_url);
        $this_url   = $parse['host'];
    }
    /* 
     * validate input of host name 
     */
    if(filter_var(gethostbyname($this_url), FILTER_VALIDATE_IP) === FALSE )
    {
        /* send error to frontend */
	    echo json_encode( array( 'content' => array( "state" => "Failed to access local server",
                                                     "age" => time(),
                                                     "url" => "localhost" )));
        exit;

    }
    
    /* validate quttera server address */
    if( filter_var($qtr_url, FILTER_VALIDATE_URL) === FALSE )
    {
        /* send error to fronend */
    	echo json_encode( array( 'content' => array( "state" => "Failed to access remote server",
                                                     "age" => time(),
                                                     "url" => $this_url )));
        exit;
    }

    $investigation_url =  $qtr_url . "/wp_scan/" . $this_url;

    if( filter_var($investigation_url, FILTER_VALIDATE_URL) === FALSE )
    {
	    echo json_encode( array( 'content' => array( "state" => "Remote server address is invalid",
                                                     "age" => time(),
                                                     "url" => "<undefined>" )));
        exit;
    }

    usleep(1000000); //sleep for a second

    //$output = file_get_contents($investigation_url);
    $output = qtr_scanner_query($investigation_url);
    
    if( empty($output) )
    {
        //$output = file_get_contents($investigation_url);
        $output = qtr_scanner_query($investigation_url);
    
        if( $output == false )
        {
            echo json_encode( array( 'content' => array( "state" => "Failed to access investigation server [ " . $qtr_url . " ]",
                                                         "age" => time(),
                                                         "url" => $this_url,
                                                         "img" => plugins_url( 'loader.gif', __FILE__ )) 
                                    ) 
                            );
            exit;
        }
    }
    
    $output = json_decode($output);
    
    //if state is not finished sleep for a second
    echo json_encode( array( 'content' => $output ) );
    exit;
}


/**
 *
 */
function qtr_external_scan_page()
{
    if(!current_user_can('activate_plugins'))
    {
        wp_die(__('You do not have sufficient permissions to access this page.') );
    }

    require ("external_scan_page.php");
}


/**
 *
 */
function qtr_internal_scan_page()
{
    if(!current_user_can('activate_plugins'))
    {
        wp_die(__('You do not have sufficient permissions to access this page.') );
    }

    require("internal_scan_page.php");
}

/**
 *
 */
function qtr_heur_internal_scan_page()
{
    if(!current_user_can('activate_plugins'))
    {
        wp_die(__('You do not have sufficient permissions to access this page.') );
    }

    require("heur_internal_scan_page.php");
}



function qtr_faq_page()
{
    if(!current_user_can('activate_plugins'))
    {
        wp_die(__('You do not have sufficient permissions to access this page.') );
    }

    require "faq_page.php";
}



/**
 * Activation callback.
 *
 * Add database version info. Set up non-autoloaded options as there is no need
 * to load results or clean core files on any page other than the exploit scanner page.
 */
function on_qtr_scanner_activation() {
    register_uninstall_hook( __FILE__, 'on_qtr_scanner_uninstall' );
}

register_activation_hook( __FILE__, 'on_qtr_scanner_activation' );

/**
 * Deactivation callback. Remove transients.
 */
function on_qtr_scanner_deactivate() {
    /* remove cached (runtime) parameters */
    
    /*
     * removes hook registration if exists
     */
    wp_clear_scheduled_hook('qtr_internal_scan_cron_hook');
}

register_deactivation_hook( __FILE__, 'on_qtr_scanner_deactivate' );


/**
 * Uninstall callback. Remove all data stored by the plugin.
 */
function on_qtr_scanner_uninstall()
{
    /* removes all added options */
}

/**
 * Update routine to perform database cleanup and to ensure that newly
 * introduced settings and defaults are enforced.
 */
function on_qtr_scanner_admin_init() 
{
    on_qtr_scanner_activation();
}

/* 
 * admin_init is triggered before any other hook when a user access the admin area 
 */
add_action( 'admin_init', 'on_qtr_scanner_admin_init' );

/* ?????? */
function qtr_wm_scanner_plugin_actions( $links, $file ) 
{
    if( $file == 'quttera/quttera_wm_scanner.php' && function_exists( "admin_url" ) ) 
    {
        $settings_link = '<a href="' . admin_url( 'tools.php?page=quttera_wm_scanner' ) . '">' . __('Scanner Settings') . '</a>';
        array_unshift( $links, $settings_link ); // before other links
    }
    return $links;
}


add_filter( 'plugin_action_links', 'qtr_wm_scanner_plugin_actions', 10, 2 );


/**
 * @brief       sends request to remote scanner 
 * @param[in]   remote_url - URL query 
 * @return      on success returns retireved Json, on failure empty string
 */
function qtr_scanner_query($remote_url)
{
    if( function_exists('curl_init') )
    {
       /* curl library loaded */ 
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $remote_url );
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, false);
        $data = curl_exec($curl);
        curl_close($curl);
        return $data;
    }else{
        return file_get_contents( $remote_url );
    }
}

/* end of file */
?>
