You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

563 lines
30 KiB

<?php
class AIOWPSecurity_User_Login
{
/**
* This will store a URI query string key for passing messages to the login form
* @var string
*/
var $key_login_msg;
function __construct()
{
$this->key_login_msg = 'aiowps_login_msg_id';
// As a first authentication step, check if user's IP is locked.
add_filter('authenticate', array($this, 'block_ip_if_locked'), 1, 0);
// Check whether user needs to be manually approved after default WordPress authenticate hooks (with priority 20).
add_filter('authenticate', array($this, 'check_manual_registration_approval'), 30, 1);
// Check login captcha
add_filter('authenticate', array($this, 'check_captcha'), 30, 1);
// As a last authentication step, perform post authentication steps
add_filter('authenticate', array($this, 'post_authenticate'), 100, 3);
add_action('aiowps_force_logout_check', array($this, 'aiowps_force_logout_action_handler'));
add_action('clear_auth_cookie', array($this, 'wp_logout_action_handler'));
add_filter('login_message', array($this, 'aiowps_login_message')); //WP filter to add or modify messages on the login page
}
/**
* Terminate the execution via wp_die with 503 status code, if current
* user's IP is currently locked.
*
* @global AIO_WP_Security $aio_wp_security
*/
function block_ip_if_locked()
{
global $aio_wp_security;
$user_locked = $this->check_locked_user();
if ( $user_locked != NULL ) {
$aio_wp_security->debug_logger->log_debug("Login attempt from blocked IP range - ".$user_locked['failed_login_ip'],2);
// Allow the error message to be filtered.
$error_msg = apply_filters( 'aiowps_ip_blocked_error_msg', __('<strong>ERROR</strong>: Access from your IP address has been blocked for security reasons. Please contact the administrator.', 'all-in-one-wp-security-and-firewall') );
// If unlock requests are allowed, add the "Request Unlock" button to the message.
if( $aio_wp_security->configs->get_value('aiowps_allow_unlock_requests') == '1' )
{
$error_msg .= $this->get_unlock_request_form();
}
wp_die($error_msg, __('Service Temporarily Unavailable', 'all-in-one-wp-security-and-firewall'), 503);
}
}
/**
* Check login captcha (if enabled).
* @global AIO_WP_Security $aio_wp_security
* @param WP_Error|WP_User $user
* @return WP_Error|WP_User
*/
function check_captcha($user)
{
global $aio_wp_security;
if ( is_wp_error($user) )
{
// Authentication has failed already at some earlier step.
return $user;
}
if ( ! (isset($_POST['log']) && isset($_POST['pwd'])) )
{
// XML-RPC authentication (not via wp-login.php), nothing to do here.
return $user;
}
if ( $aio_wp_security->configs->get_value('aiowps_enable_login_captcha') != '1' )
{
// Captcha not enabled, nothing to do here.
return $user;
}
$captcha_error = new WP_Error('authentication_failed', __('<strong>ERROR</strong>: Your answer was incorrect - please try again.', 'all-in-one-wp-security-and-firewall'));
$captcha_answer = filter_input(INPUT_POST, 'aiowps-captcha-answer', FILTER_VALIDATE_INT);
if ( is_null($captcha_answer) || ($captcha_answer === false) )
{
// null - no post data, false - not an integer
return $captcha_error;
}
$captcha_temp_string = filter_input(INPUT_POST, 'aiowps-captcha-temp-string', FILTER_SANITIZE_STRING);
if ( is_null($captcha_temp_string) )
{
return $captcha_error;
}
$captcha_secret_string = $aio_wp_security->configs->get_value('aiowps_captcha_secret_key');
$submitted_encoded_string = base64_encode($captcha_temp_string.$captcha_secret_string.$captcha_answer);
$trans_handle = sanitize_text_field(filter_input(INPUT_POST, 'aiowps-captcha-string-info', FILTER_SANITIZE_STRING));
$captcha_string_info_trans = (AIOWPSecurity_Utility::is_multisite_install() ? get_site_transient('aiowps_captcha_string_info_'.$trans_handle) : get_transient('aiowps_captcha_string_info_'.$trans_handle));
if ( $submitted_encoded_string !== $captcha_string_info_trans )
{
return $captcha_error;
}
return $user;
}
/**
* Check, whether $user needs to be manually approved by site admin yet.
* @global AIO_WP_Security $aio_wp_security
* @param WP_Error|WP_User $user
* @param string $username
* @param string $password
* @return WP_Error|WP_User
*/
function check_manual_registration_approval($user)
{
global $aio_wp_security;
if ( !($user instanceof WP_User) ) {
// Not a WP_User - nothing to do here.
return $user;
}
//Check if auto pending new account status feature is enabled
if ($aio_wp_security->configs->get_value('aiowps_enable_manual_registration_approval') == '1')
{
$aiowps_account_status = get_user_meta($user->ID, 'aiowps_account_status', TRUE);
if ($aiowps_account_status == 'pending') {
// Account needs to be activated yet
return new WP_Error('account_pending', __('<strong>ACCOUNT PENDING</strong>: Your account is currently not active. An administrator needs to activate your account before you can login.', 'all-in-one-wp-security-and-firewall'));
}
}
return $user;
}
/**
* Handle post authentication steps (in case of failed login):
* - increment number of failed logins for $username
* - (optionally) lock the user
* - (optionally) display a generic error message
* @global AIO_WP_Security $aio_wp_security
* @param WP_Error|WP_User $user
* @param string $username
* @param string $password
* @return WP_Error|WP_User
*/
function post_authenticate($user, $username, $password)
{
global $aio_wp_security;
if ( !is_wp_error($user) ) {
// Authentication has been successful, there's nothing to do here.
return $user;
}
if ( empty($username) || empty($password) ) {
// Neither log nor block login attempts with empty username or password.
return $user;
}
if ( $user->get_error_code() === 'account_pending' ) {
// Neither log nor block users attempting to log in before their registration is approved.
return;
}
// Login failed for non-trivial reason
$this->increment_failed_logins($username);
if ( $aio_wp_security->configs->get_value('aiowps_enable_login_lockdown') == '1' )
{
// Too many failed logins from user's IP?
$login_attempts_permitted = absint($aio_wp_security->configs->get_value('aiowps_max_login_attempts'));
$too_many_failed_logins = $login_attempts_permitted <= $this->get_login_fail_count();
// Is an invalid username or email the reason for login error?
$invalid_username = ($user->get_error_code() === 'invalid_username' || $user->get_error_code() == 'invalid_email');
// Should an invalid username be immediately locked?
$invalid_username_lockdown = $aio_wp_security->configs->get_value('aiowps_enable_invalid_username_lockdown') == '1';
$lock_invalid_username = $invalid_username && $invalid_username_lockdown;
// Should an invalid username be blocked as per blacklist?
$instant_lockout_users_list = $aio_wp_security->configs->get_value('aiowps_instantly_lockout_specific_usernames');
if ( !is_array($instant_lockout_users_list) ) {
$instant_lockout_users_list = array();
}
$username_blacklisted = $invalid_username && in_array($username, $instant_lockout_users_list);
if ( $too_many_failed_logins || $lock_invalid_username || $username_blacklisted )
{
$this->lock_the_user($username, 'login_fail');
}
}
if ( $aio_wp_security->configs->get_value('aiowps_set_generic_login_msg') == '1' )
{
// Return generic error message if configured
return new WP_Error('authentication_failed', __('<strong>ERROR</strong>: Invalid login credentials.', 'all-in-one-wp-security-and-firewall'));
}
return $user;
}
/*
* This function queries the aiowps_login_lockdown table.
* If the release_date has not expired AND the current visitor IP addr matches
* it will return a record
*/
function check_locked_user()
{
global $wpdb;
$login_lockdown_table = AIOWPSEC_TBL_LOGIN_LOCKDOWN;
$ip = AIOWPSecurity_Utility_IP::get_user_ip_address(); //Get the IP address of user
$ip_range = AIOWPSecurity_Utility_IP::get_sanitized_ip_range($ip); //Get the IP range of the current user
if(empty($ip_range)) return false;
$locked_user = $wpdb->get_row("SELECT * FROM $login_lockdown_table " .
"WHERE release_date > now() AND " .
"failed_login_ip LIKE '" . esc_sql($ip_range) . "%'", ARRAY_A);
return $locked_user;
}
/*
* This function queries the aiowps_failed_logins table and returns the number of failures for current IP range within allowed failure period
*/
function get_login_fail_count()
{
global $wpdb, $aio_wp_security;
$failed_logins_table = AIOWPSEC_TBL_FAILED_LOGINS;
$login_retry_interval = $aio_wp_security->configs->get_value('aiowps_retry_time_period');
$ip = AIOWPSecurity_Utility_IP::get_user_ip_address(); //Get the IP address of user
$ip_range = AIOWPSecurity_Utility_IP::get_sanitized_ip_range($ip); //Get the IP range of the current user
if(empty($ip_range)) return false;
$login_failures = $wpdb->get_var("SELECT COUNT(ID) FROM $failed_logins_table " .
"WHERE failed_login_date + INTERVAL " .
$login_retry_interval . " MINUTE > now() AND " .
"login_attempt_ip LIKE '" . esc_sql($ip_range) . "%'");
return $login_failures;
}
/**
* Adds an entry to the `aiowps_login_lockdown` table.
* @param string $username User's username or email
* @param string $lock_reason
*/
function lock_the_user($username, $lock_reason='login_fail')
{
global $wpdb, $aio_wp_security;
$login_lockdown_table = AIOWPSEC_TBL_LOGIN_LOCKDOWN;
$lockout_time_length = $aio_wp_security->configs->get_value('aiowps_lockout_time_length');
$ip = AIOWPSecurity_Utility_IP::get_user_ip_address(); //Get the IP address of user
$ip_range = AIOWPSecurity_Utility_IP::get_sanitized_ip_range($ip); //Get the IP range of the current user
if(empty($ip_range)) return;
$user = is_email($username) ? get_user_by('email', $username) : get_user_by('login', $username); //Returns WP_User object if exists
$ip_range = apply_filters('aiowps_before_lockdown', $ip_range);
if ($user)
{
//If the login attempt was made using a valid user set variables for DB storage later on
$user_id = $user->ID;
} else {
//If the login attempt was made using a non-existent user then let's set user_id to blank and record the attempted user login name for DB storage later on
$user_id = 0;
}
$ip_range_str = esc_sql($ip_range).'.*';
$insert = "INSERT INTO " . $login_lockdown_table . " (user_id, user_login, lockdown_date, release_date, failed_login_IP, lock_reason) " .
"VALUES (' . $user_id . ', '" . $username . "', now(), date_add(now(), INTERVAL " .
$lockout_time_length . " MINUTE), '" . $ip_range_str . "', '" . $lock_reason . "')";
$result = $wpdb->query($insert);
if ($result > 0)
{
do_action('aiowps_lockdown_event', $ip_range, $username);
$this->send_ip_lock_notification_email($username, $ip_range, $ip);
$aio_wp_security->debug_logger->log_debug("The following IP address range has been locked out for exceeding the maximum login attempts: ".$ip_range,2);//Log the lockdown event
}
else if ($result === FALSE)
{
$aio_wp_security->debug_logger->log_debug("Error inserting record into ".$login_lockdown_table,4);//Log the highly unlikely event of DB error
}
}
/**
* Adds an entry to the `aiowps_failed_logins` table.
* @param string $username User's username or email
*/
function increment_failed_logins($username)
{
global $wpdb, $aio_wp_security;
//$login_attempts_permitted = $aio_wp_security->configs->get_value('aiowps_max_login_attempts');
//$lockout_time_length = $aio_wp_security->configs->get_value('aiowps_lockout_time_length');
$login_fails_table = AIOWPSEC_TBL_FAILED_LOGINS;
$ip = AIOWPSecurity_Utility_IP::get_user_ip_address(); //Get the IP address of user
$ip_range = AIOWPSecurity_Utility_IP::get_sanitized_ip_range($ip); //Get the IP range of the current user
if(empty($ip_range)) return;
$user = is_email($username) ? get_user_by('email', $username) : get_user_by('login', $username); //Returns WP_User object if it exists
if ($user)
{
//If the login attempt was made using a valid user set variables for DB storage later on
$user_id = $user->ID;
} else {
//If the login attempt was made using a non-existent user then let's set user_id to blank and record the attempted user login name for DB storage later on
$user_id = 0;
}
$ip_range_str = esc_sql($ip_range).'.*';
$now = date_i18n( 'Y-m-d H:i:s' );
$data = array('user_id' => $user_id, 'user_login' => $username, 'failed_login_date' => $now, 'login_attempt_ip' => $ip_range_str);
$format = array('%d', '%s', '%s', '%s');
$result = $wpdb->insert($login_fails_table, $data, $format);
if ($result === FALSE)
{
$aio_wp_security->debug_logger->log_debug("Error inserting record into ".$login_fails_table,4);//Log the highly unlikely event of DB error
}
}
/**
* @param string $username User's username or email
*/
function send_ip_lock_notification_email($username, $ip_range, $ip)
{
global $aio_wp_security;
$email_notification_enabled = $aio_wp_security->configs->get_value('aiowps_enable_email_notify');
if ($email_notification_enabled == 1)
{
$to_email_address = $aio_wp_security->configs->get_value('aiowps_email_address');
$subject = '['.get_option('home').'] '. __('Site Lockout Notification','all-in-one-wp-security-and-firewall');
$email_msg = __('A lockdown event has occurred due to too many failed login attempts or invalid username:','all-in-one-wp-security-and-firewall')."\n";
$email_msg .= __('Username:', 'all-in-one-wp-security-and-firewall') . ' ' . $username . "\n";
$email_msg .= __('IP Address:', 'all-in-one-wp-security-and-firewall') . ' ' . $ip . "\n\n";
$email_msg .= __('IP Range:', 'all-in-one-wp-security-and-firewall') . ' ' . $ip_range . '.*' . "\n\n";
$email_msg .= __("Log into your site's WordPress administration panel to see the duration of the lockout or to unlock the user.','all-in-one-wp-security-and-firewall") . "\n";
$site_title = get_bloginfo( 'name' );
$from_name = empty($site_title)?'WordPress':$site_title;
$email_header = 'From: '.$from_name.' <'.get_bloginfo('admin_email').'>' . "\r\n\\";
$sendMail = wp_mail($to_email_address, $subject, $email_msg, $email_header);
if(FALSE === $sendMail){
$aio_wp_security->debug_logger->log_debug("Lockout notification email failed to send to ".$to_email_address." for IP ".$ip,4);
}
}
}
/*
* This function generates a special random string and inserts into the lockdown table for the relevant user
* It then generates an unlock request link which will be used to send to the user
*/
static function generate_unlock_request_link($ip_range)
{
//Get the locked user row from lockdown table
global $wpdb, $aio_wp_security;
$unlock_link = '';
$lockdown_table_name = AIOWPSEC_TBL_LOGIN_LOCKDOWN;
$secret_rand_key = (md5(uniqid(rand(), true)));
$sql = $wpdb->prepare("UPDATE $lockdown_table_name SET unlock_key = '$secret_rand_key' WHERE release_date > now() AND failed_login_ip LIKE %s","%".esc_sql($ip_range)."%");
$res = $wpdb->query($sql);
if($res == NULL){
$aio_wp_security->debug_logger->log_debug("No locked user found with IP range ".$ip_range,4);
return false;
}else{
$query_param = array('aiowps_auth_key'=>$secret_rand_key);
$wp_site_url = AIOWPSEC_WP_URL;
$unlock_link = esc_url(add_query_arg($query_param, $wp_site_url));
}
return $unlock_link;
}
/*
* This function will process an unlock request when someone clicks on the special URL
* It will check if the special random code matches that in lockdown table for the relevant user
* If so, it will unlock the user
*/
static function process_unlock_request($unlock_key)
{
global $wpdb, $aio_wp_security;
$lockdown_table_name = AIOWPSEC_TBL_LOGIN_LOCKDOWN;
$unlock_command = $wpdb->prepare( "UPDATE ".$lockdown_table_name." SET release_date = now() WHERE unlock_key = %s", $unlock_key );
$result = $wpdb->query($unlock_command);
if($result === false)
{
$aio_wp_security->debug_logger->log_debug("Error unlocking user with unlock_key ".$unlock_key,4);
}
else
{
if($aio_wp_security->configs->get_value('aiowps_enable_rename_login_page')=='1'){
if (get_option('permalink_structure')){
$home_url = trailingslashit(home_url());
}else{
$home_url = trailingslashit(home_url()) . '?';
}
$login_url = $home_url.$aio_wp_security->configs->get_value('aiowps_login_page_slug');
AIOWPSecurity_Utility::redirect_to_url($login_url);
}else{
AIOWPSecurity_Utility::redirect_to_url(wp_login_url());
}
}
}
/*
* This function sends an unlock request email to a locked out user
*/
static function send_unlock_request_email($email, $unlock_link)
{
global $aio_wp_security;
$subject = '['.get_option('siteurl').'] '. __('Unlock Request Notification','all-in-one-wp-security-and-firewall');
$email_msg
= sprintf(__('You have requested for the account with email address %s to be unlocked. Please click the link below to unlock your account:','all-in-one-wp-security-and-firewall'), $email) . "\n"
. sprintf(__('Unlock link: %s', 'all-in-one-wp-security-and-firewall'), $unlock_link) . "\n\n"
. __('After clicking the above link you will be able to login to the WordPress administration panel.', 'all-in-one-wp-security-and-firewall') . "\n"
;
$site_title = get_bloginfo( 'name' );
$from_name = empty($site_title)?'WordPress':$site_title;
$email_header = 'From: '.$from_name.' <'.get_bloginfo('admin_email').'>' . "\r\n\\";
$sendMail = wp_mail($email, $subject, $email_msg, $email_header);
if ( false === $sendMail ) {
$aio_wp_security->debug_logger->log_debug("Unlock Request Notification email failed to send to " . $email, 4);
}
}
/*
* This function will check the settings and log the user after the configured time period
*/
function aiowps_force_logout_action_handler()
{
global $aio_wp_security;
//$aio_wp_security->debug_logger->log_debug("Force Logout - Checking if any user need to be logged out...");
if($aio_wp_security->configs->get_value('aiowps_enable_forced_logout')=='1') //if this feature is enabled then do something
{
if(is_user_logged_in())
{
$current_user = wp_get_current_user();
$user_id = $current_user->ID;
$current_time = date_i18n( 'Y-m-d H:i:s' );
$login_time = $this->get_wp_user_last_login_time($user_id);
$diff = strtotime($current_time) - strtotime($login_time);
$logout_time_interval_value = $aio_wp_security->configs->get_value('aiowps_logout_time_period');
$logout_time_interval_val_seconds = $logout_time_interval_value * 60;
if($diff > $logout_time_interval_val_seconds)
{
$aio_wp_security->debug_logger->log_debug("Force Logout - This user logged in more than (".$logout_time_interval_value.") minutes ago. Doing a force log out for the user with username: ".$current_user->user_login);
$this->wp_logout_action_handler(); //this will register the logout time/date in the logout_date column
$curr_page_url = AIOWPSecurity_Utility::get_current_page_url();
$after_logout_payload = array('redirect_to'=>$curr_page_url, 'msg'=>$this->key_login_msg.'=session_expired');
//Save some of the logout redirect data to a transient
AIOWPSecurity_Utility::is_multisite_install() ? set_site_transient('aiowps_logout_payload', $after_logout_payload, 30 * 60) : set_transient('aiowps_logout_payload', $after_logout_payload, 30 * 60);
$logout_url = AIOWPSEC_WP_URL.'?aiowpsec_do_log_out=1';
$logout_url = AIOWPSecurity_Utility::add_query_data_to_url($logout_url, 'al_additional_data', '1');
AIOWPSecurity_Utility::redirect_to_url($logout_url);
}
}
}
}
function get_wp_user_last_login_time($user_id)
{
$last_login = get_user_meta($user_id, 'last_login_time', true);
return $last_login;
}
static function wp_login_action_handler($user_login, $user='')
{
global $wpdb, $aio_wp_security;
$login_activity_table = AIOWPSEC_TBL_USER_LOGIN_ACTIVITY;
if ($user == ''){
//Try and get user object
$user = get_user_by('login', $user_login); //This should return WP_User obj
if (!$user){
$aio_wp_security->debug_logger->log_debug("AIOWPSecurity_User_Login::wp_login_action_handler: Unable to get WP_User object for login ".$user_login,4);
return;
}
}
$login_date_time = date_i18n( 'Y-m-d H:i:s' );
update_user_meta($user->ID, 'last_login_time', $login_date_time); //store last login time in meta table
$curr_ip_address = AIOWPSecurity_Utility_IP::get_user_ip_address();
$insert = "INSERT INTO " . $login_activity_table . " (user_id, user_login, login_date, login_ip) " .
"VALUES ('" . $user->ID . "', '" . $user_login . "', '" . $login_date_time . "', '" . $curr_ip_address . "')";
$result = $wpdb->query($insert);
if ($result === FALSE)
{
$aio_wp_security->debug_logger->log_debug("Error inserting record into ".$login_activity_table,4);//Log the highly unlikely event of DB error
}
}
/**
* The handler for logout events, ie, uses the WP "clear_auth_cookies" action.
* Modifies the login activity record for the current user by registering the logout time/date in the logout_date column.
* (NOTE: Because of the way we are doing a force logout, the "clear_auth_cookies" hook does not fire.
* upon auto logout. The current workaround is to call this function directly from the aiowps_force_logout_action_handler() when
* an auto logout occurs due to the "force logout" feature).
*
*/
function wp_logout_action_handler()
{
global $wpdb, $aio_wp_security;
$current_user = wp_get_current_user();
$ip_addr = AIOWPSecurity_Utility_IP::get_user_ip_address();
$user_id = $current_user->ID;
//Clean up transients table
$this->update_user_online_transient($user_id, $ip_addr);
$login_activity_table = AIOWPSEC_TBL_USER_LOGIN_ACTIVITY;
$logout_date_time = date_i18n( 'Y-m-d H:i:s' );
$data = array('logout_date' => $logout_date_time);
$where = array('user_id' => $user_id,
'login_ip' => $ip_addr,
'logout_date' => '0000-00-00 00:00:00');
$result = $wpdb->update($login_activity_table, $data, $where);
if ($result === FALSE)
{
$aio_wp_security->debug_logger->log_debug("Error inserting record into ".$login_activity_table,4);//Log the highly unlikely event of DB error
}
}
/**
* This will clean up the "users_online" transient entry for the current user.
*
*/
function update_user_online_transient($user_id, $ip_addr)
{
global $aio_wp_security;
$logged_in_users = (AIOWPSecurity_Utility::is_multisite_install() ? get_site_transient('users_online') : get_transient('users_online'));
//$logged_in_users = get_transient('users_online');
if ($logged_in_users === false || $logged_in_users == NULL)
{
return;
}
$j = 0;
foreach ($logged_in_users as $value)
{
if ($value['user_id'] == $user_id && strcmp($value['ip_address'], $ip_addr) == 0)
{
unset($logged_in_users[$j]);
break;
}
$j++;
}
//Save the transient
AIOWPSecurity_Utility::is_multisite_install() ? set_site_transient('users_online', $logged_in_users, 30 * 60) : set_transient('users_online', $logged_in_users, 30 * 60);
//set_transient('users_online', $logged_in_users, 30 * 60); //Set transient with the data obtained above and also set the expiry to 30min
return;
}
/**
* The handler for the WP "login_message" filter
* Adds custom messages to the other messages that appear above the login form.
*
* NOTE: This method is automatically called by WordPress for displaying
* text above the login form.
*
* @param string $message the output from earlier login_message filters
* @return string
*
*/
function aiowps_login_message($message = '')
{
global $aio_wp_security;
$msg = '';
if(isset($_GET[$this->key_login_msg]) && !empty($_GET[$this->key_login_msg]))
{
$logout_msg = strip_tags($_GET[$this->key_login_msg]);
}
if (!empty($logout_msg))
{
switch ($logout_msg) {
case 'session_expired':
$msg = sprintf(__('Your session has expired because it has been over %d minutes since your last login.', 'all-in-one-wp-security-and-firewall'), $aio_wp_security->configs->get_value('aiowps_logout_time_period'));
$msg .= ' ' . __('Please log back in to continue.', 'all-in-one-wp-security-and-firewall');
break;
case 'admin_user_changed':
$msg = __('You were logged out because you just changed the "admin" username.', 'all-in-one-wp-security-and-firewall');
$msg .= ' ' . __('Please log back in to continue.', 'all-in-one-wp-security-and-firewall');
break;
default:
}
}
if (!empty($msg))
{
$msg = htmlspecialchars($msg, ENT_QUOTES, 'UTF-8');
$message .= '<p class="login message">'. $msg . '</p>';
}
return $message;
}
/**
* This function will generate an unlock request form to be inserted inside
* error message when user gets locked out.
*
* @return string
*/
function get_unlock_request_form()
{
global $aio_wp_security;
$unlock_request_form = '';
//Let's encode some hidden data and make a form
$unlock_secret_string = $aio_wp_security->configs->get_value('aiowps_unlock_request_secret_key');
$current_time = time();
$enc_result = base64_encode($current_time.$unlock_secret_string);
$unlock_request_form .= '<form method="post" action=""><div style="padding-bottom:10px;"><input type="hidden" name="aiowps-unlock-string-info" id="aiowps-unlock-string-info" value="'.$enc_result.'" />';
$unlock_request_form .= '<input type="hidden" name="aiowps-unlock-temp-string" id="aiowps-unlock-temp-string" value="'.$current_time.'" />';
$unlock_request_form .= '<button type="submit" name="aiowps_unlock_request" id="aiowps_unlock_request" class="button">'.__('Request Unlock', 'all-in-one-wp-security-and-firewall').'</button></div></form>';
return $unlock_request_form;
}
}