# wt-security/2.3.24/library/App.php

WebTotem Security, version 2.3.24. 215 lines.

- Page: https://pluginprobe.com/plugins/wt-security/2.3.24/code/library/App.php
- Raw: https://pluginprobe.com/plugins/wt-security/2.3.24/raw/library/App.php
- Modified: 2021-03-01T06:04:42+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/wt-security/2.3.24/code/library/App.php#L10-L20`.

```php
<?php defined('ABSPATH') or die("Protected By WT!");


class WTSEC_LIBRARY_App
{

    public function __construct()
    {
        $this->auth();
    }

    public function auth(){
        if(self::getOption('authorized') === false && (defined('WTSEC_DEACTIVATED') && !WTSEC_DEACTIVATED)){
            wp_safe_redirect(admin_url('admin.php?page=' . WTSEC_PAGE_PREFIX . 'login'));
            exit;
        }
    }

    public static function authorized(){
        return (boolean) self::getOption('authorized');
    }

    public static function login($token){
        define("WTSEC_DEACTIVATED", false);
        self::_set('authorized', true);
        self::_set('authToken', $token);
    }

    public static function logout(){
        self::_delete(['authToken','authorized','api_key']);
        //self::_set('am_installed', false);
    }

    public static function clearDB(){
        $options = ['api_key','authorized','authToken',
            'waf_installed_file','am_installed_file','am_installed',
            'color_scheme','check_login_attempt','time_zone',
            'token_expired','deactivated', 'antivirus_event',
            'antivirus_endCursor', 'antivirus_hasNextPage',
            'firewall_endCursor', 'firewall_hasNextPage',
            'reports_endCursor', 'reports_hasNextPage'];
        self::_delete($options);
    }

    public function getLocalDomains(){
        return [];
    }

    public static function _set($name,$value){
        return update_option(WTSEC_PLUGIN_PREFIX.$name,$value);
    }

    public static function _get($name){
        return get_option(WTSEC_PLUGIN_PREFIX.$name);
    }

    public static function _delete($options){
        if(is_array($options)){
            foreach ($options as $option) {
                if ( ! delete_option(WTSEC_PLUGIN_PREFIX.$option))
                    return false;
            }
        } else{
            delete_option(WTSEC_PLUGIN_PREFIX.$options);
        }
        return true;
    }

    public function set($name,$value){
        return update_option(WTSEC_PLUGIN_PREFIX.$name,$value);
    }

    public function get($name){
        return get_option(WTSEC_PLUGIN_PREFIX.$name);
    }

    public static function getOption($name){
        return get_option(WTSEC_PLUGIN_PREFIX.$name);
    }

    public static function deleteOption($name){
        return delete_option(WTSEC_PLUGIN_PREFIX.$name);
    }

    public static function getToken(){
        return self::getOption('authToken');
    }

    public static function getName(){
        return self::getOption('username');
    }


    // Limit login attempt
    public function wtsec_login_check($user, $username, $password){

        if( ! $this->wtsec_is_need_check() ){
            return $user;
        }

        require_once WTSEC_PLUGIN_PATH . 'library/Localization.php';

        function wtsec_locale($lmsg, $args = [])
        {
            return WTSEC_LIBRARY_Localization::lmsg($lmsg, $args);
        }

        $massage = wtsec_locale('login_attempt_message');
        global $msg;

        $options = (object) [
            // время снятия блокировки в секудах
            'lock_time' => 1800, // 1800
            // Количество попыток авторизоваться
            'lock_num' => 5,
            // Сообщение о блокировке
            'massage'  => $massage,
            // время полной очистки файла - 4 дня
            'expire_time' => 3600 * 24 * 4,
            // добавить в названия файлов запрос REQUEST_URI - может пригодится для дебага
            'add_uri' => false,
            // использовать ли мякгий метод получения IP?
            'soft_get_ip' => false,
        ];

        // чтобы установить имя файла
        $action = @ $_GET['action'];
        if( ! in_array( $action, array( 'postpass', 'logout', 'lostpassword', 'retrievepassword', 'resetpass', 'rp', 'register', 'login' ), true ) )
            $action = 'login';

        // создаем директорию кэша если надо
        $cache_dir = plugin_dir_path(__FILE__) . 'cache';
        if( ! file_exists($cache_dir) )
            mkdir( $cache_dir, 0777 );

        // оперделим название файла
        $REQUEST_URI = $options->add_uri ? ( '___'. preg_replace('/[^a-zA-Z0-9:=?_-]/', '-', $_SERVER['REQUEST_URI'] ) /*все на -*/ ) : '';
        $domen       = str_replace('www.', '', $_SERVER['HTTP_HOST'] );
        $file_path   = $cache_dir . "/{$domen}___{$action}{$REQUEST_URI}.ini";

        // оперделим ip
        if( ! $ip = $this->wtsec_get_ip( $options->soft_get_ip ) )
            die( 'No IP...' );

        // парсим данные
        $data = @ parse_ini_file( $file_path );
        $data = (!$data) ? [] : $data;
        $attempts = array_key_exists($ip,$data) ? count($data[$ip]) + 1 : 1;
        $last_access_time = array_key_exists($ip,$data) ? max( $data[$ip] ) : 0;
        $blocked_time = $last_access_time + ($options->lock_time * floor( $attempts / $options->lock_num) );

        if ( $data['status'][$ip] == 'blocked' &&  $blocked_time > time() ){
            $blocked_time = ($blocked_time - time()) / 60;

            // Вывод ошибки и блокировка
            $msg = sprintf($options->massage, $options->lock_num, $blocked_time);
            $error = new WP_Error();
            $error->add('wp_to_many_try', $msg);
            return $error;
        } else{
            file_put_contents( $file_path, sprintf("{$ip}[] = %d\n", time()), FILE_APPEND ); // добавляем ip и время

            if ($data['status'][$ip] == 'blocked'){
                $new_content = preg_replace("~status\[" . $ip . "\] = [a-z]+\n~", '', file_get_contents($file_path) );
                file_put_contents( $file_path, $new_content ); // снимает блокировку
            }

            if($attempts >= $options->lock_num && ( $attempts % $options->lock_num ) == 0)
                file_put_contents( $file_path, "status[{$ip}] = blocked\n", FILE_APPEND); // добавляем блокировку
        }

        // полная очистка файла
        if( empty($data['expire']) ){
            file_put_contents( $file_path, 'expire = ' . time() . "\n", FILE_APPEND );
        }
        elseif( $data['expire'] + $options->expire_time < time() ){
            $content = 'expire = '. time() . "\n";
            file_put_contents( $file_path, $content ); // очищаем файл полностью
        }
        return $user;
    }

    protected function wtsec_is_need_check(){

        // работает только для POST запросов.
        if( empty($_POST) )
            return false;

        $need_check = false;
        $settings_value = self::_get('check_login_attempt');

        // для страницы '/wp-login.php'
        if( false !== strpos($_SERVER['REQUEST_URI'], '/wp-login.php') && $settings_value )
            $need_check = true;


        return $need_check;
    }

    protected function wtsec_get_ip( $soft = false ){

        if( $soft ){
            $ip = isset($_SERVER['HTTP_CF_CONNECTING_IP']) ? $_SERVER['HTTP_CF_CONNECTING_IP'] : ''; // cloudflare IP support
            if( ! filter_var($ip, FILTER_VALIDATE_IP) ) $ip = isset($_SERVER['HTTP_CLIENT_IP'])       ? $_SERVER['HTTP_CLIENT_IP']       : '';
            if( ! filter_var($ip, FILTER_VALIDATE_IP) ) $ip = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : '';
            if( ! filter_var($ip, FILTER_VALIDATE_IP) )	$ip = isset($_SERVER['REMOTE_ADDR'])          ? $_SERVER['REMOTE_ADDR']          : '';
        }
        else {
            $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
        }

        return $ip;
    }

}
```
