function aiowps_user_registration_action_handler($user_id)
 {
     global $wpdb, $aio_wp_security;
     //Check if auto pending new account status feature is enabled
     if ($aio_wp_security->configs->get_value('aiowps_enable_manual_registration_approval') == '1') {
         $res = add_user_meta($user_id, 'aiowps_account_status', 'pending');
         if (!$res) {
             $aio_wp_security->debug_logger->log_debug("aiowps_user_registration_action_handler: Error adding user meta data: aiowps_account_status", 4);
         }
         $user_ip_address = AIOWPSecurity_Utility_IP::get_user_ip_address();
         $res = add_user_meta($user_id, 'aiowps_registrant_ip', $user_ip_address);
         if (!$res) {
             $aio_wp_security->debug_logger->log_debug("aiowps_user_registration_action_handler: Error adding user meta data: aiowps_registrant_ip", 4);
         }
     }
 }
 /**
  * Will check the current visitor IP against the blocked table
  * If IP present will block the visitor from viewing the site
  */
 static function check_visitor_ip_and_perform_blocking()
 {
     global $aio_wp_security, $wpdb;
     $visitor_ip = AIOWPSecurity_Utility_IP::get_user_ip_address();
     $ip_type = WP_Http::is_ip_address($visitor_ip);
     if (empty($ip_type)) {
         $aio_wp_security->debug_logger->log_debug("do_general_ip_blocking_tasks: " . $visitor_ip . " is not a valid IP!", 4);
         return;
     }
     //Check if this IP address is in the block list
     $blocked = AIOWPSecurity_Blocking::is_ip_blocked($visitor_ip);
     //TODO - future feature: add blocking whitelist and check
     if (empty($blocked)) {
         return;
         //Visitor IP is not blocked - allow page to load
     } else {
         //block this visitor!!
         AIOWPSecurity_Utility::redirect_to_url('http://127.0.0.1');
     }
     return;
 }
 static function block_fake_googlebots()
 {
     $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
     if (preg_match('/Googlebot/i', $user_agent, $matches)) {
         //If user agent says it is googlebot start doing checks
         $ip = AIOWPSecurity_Utility_IP::get_user_ip_address();
         $name = gethostbyaddr($ip);
         //let's get the internet hostname using the given IP address
         //TODO - maybe add check if gethostbyaddr() fails
         $host_ip = gethostbyname($name);
         //Reverse lookup - let's get the IP using the name
         if (preg_match('/Googlebot/i', $name, $matches)) {
             if ($host_ip == $ip) {
                 //Genuine googlebot allow it through....
             } else {
                 //fake googlebot - block it!
                 exit;
             }
         } else {
             //fake googlebot - block it!
             exit;
         }
     }
 }
    function render_tab4()
    {
        global $aio_wp_security;
        global $aiowps_feature_mgr;
        $result = 1;
        $your_ip_address = AIOWPSecurity_Utility_IP::get_user_ip_address();
        if (isset($_POST['aiowps_save_whitelist_settings'])) {
            $nonce = $_REQUEST['_wpnonce'];
            if (!wp_verify_nonce($nonce, 'aiowpsec-whitelist-settings-nonce')) {
                $aio_wp_security->debug_logger->log_debug("Nonce check failed for save whitelist settings!", 4);
                die(__('Nonce check failed for save whitelist settings!', 'all-in-one-wp-security-and-firewall'));
            }
            if (isset($_POST["aiowps_enable_whitelisting"]) && empty($_POST['aiowps_allowed_ip_addresses'])) {
                $this->show_msg_error('You must submit at least one IP address!', 'all-in-one-wp-security-and-firewall');
            } else {
                if (!empty($_POST['aiowps_allowed_ip_addresses'])) {
                    $ip_addresses = $_POST['aiowps_allowed_ip_addresses'];
                    $ip_list_array = AIOWPSecurity_Utility_IP::create_ip_list_array_from_string_with_newline($ip_addresses);
                    $payload = AIOWPSecurity_Utility_IP::validate_ip_list($ip_list_array, 'whitelist');
                    if ($payload[0] == 1) {
                        //success case
                        $result = 1;
                        $list = $payload[1];
                        $whitelist_ip_data = implode(PHP_EOL, $list);
                        $aio_wp_security->configs->set_value('aiowps_allowed_ip_addresses', $whitelist_ip_data);
                        $_POST['aiowps_allowed_ip_addresses'] = '';
                        //Clear the post variable for the banned address list
                    } else {
                        $result = -1;
                        $error_msg = htmlspecialchars($payload[1][0]);
                        $this->show_msg_error($error_msg);
                    }
                } else {
                    $aio_wp_security->configs->set_value('aiowps_allowed_ip_addresses', '');
                    //Clear the IP address config value
                }
                if ($result == 1) {
                    $aio_wp_security->configs->set_value('aiowps_enable_whitelisting', isset($_POST["aiowps_enable_whitelisting"]) ? '1' : '');
                    $aio_wp_security->configs->save_config();
                    //Save the configuration
                    //Recalculate points after the feature status/options have been altered
                    $aiowps_feature_mgr->check_feature_status_and_recalculate_points();
                    $this->show_msg_settings_updated();
                    $write_result = AIOWPSecurity_Utility_Htaccess::write_to_htaccess();
                    //now let's write to the .htaccess file
                    if (!$write_result) {
                        $this->show_msg_error(__('The plugin was unable to write to the .htaccess file. Please edit file manually.', 'all-in-one-wp-security-and-firewall'));
                        $aio_wp_security->debug_logger->log_debug("AIOWPSecurity_whitelist_Menu - The plugin was unable to write to the .htaccess file.");
                    }
                }
            }
        }
        ?>
        <h2><?php 
        _e('Login Whitelist', 'all-in-one-wp-security-and-firewall');
        ?>
</h2>
        <div class="aio_blue_box">
            <?php 
        echo '<p>' . __('The All In One WP Security Whitelist feature gives you the option of only allowing certain IP addresses or ranges to have access to your WordPress login page.', 'all-in-one-wp-security-and-firewall') . '
            <br />' . __('This feature will deny login access for all IP addresses which are not in your whitelist as configured in the settings below.', 'all-in-one-wp-security-and-firewall') . '
            <br />' . __('The plugin achieves this by writing the appropriate directives to your .htaccess file.', 'all-in-one-wp-security-and-firewall') . '
            <br />' . __('By allowing/blocking IP addresses via the .htaccess file your are using the most secure first line of defence because login access will only be granted to whitelisted IP addresses and other addresses will be blocked as soon as they try to access your login page.', 'all-in-one-wp-security-and-firewall') . '
            </p>';
        ?>
        </div>
        <div class="aio_yellow_box">
            <?php 
        $brute_force_login_feature_link = '<a href="admin.php?page=' . AIOWPSEC_BRUTE_FORCE_MENU_SLUG . '&tab=tab2" target="_blank">Cookie-Based Brute Force Login Prevention</a>';
        $rename_login_feature_link = '<a href="admin.php?page=' . AIOWPSEC_BRUTE_FORCE_MENU_SLUG . '&tab=tab1" target="_blank">Rename Login Page</a>';
        echo '<p>' . sprintf(__('Attention: If in addition to enabling the white list feature, you also have one of the %s or %s features enabled, <strong>you will still need to use your secret word or special slug in the URL when trying to access your WordPress login page</strong>.', 'all-in-one-wp-security-and-firewall'), $brute_force_login_feature_link, $rename_login_feature_link) . '</p>
            <p>' . __('These features are NOT functionally related. Having both of them enabled on your site means you are creating 2 layers of security.', 'all-in-one-wp-security-and-firewall') . '</p>';
        ?>
        </div>

        <div class="postbox">
        <h3 class="hndle"><label for="title"><?php 
        _e('Login IP Whitelist Settings', 'all-in-one-wp-security-and-firewall');
        ?>
</label></h3>
        <div class="inside">
        <?php 
        //Display security info badge
        global $aiowps_feature_mgr;
        $aiowps_feature_mgr->output_feature_details_badge("whitelist-manager-ip-login-whitelisting");
        ?>
    
        <form action="" method="POST">
        <?php 
        wp_nonce_field('aiowpsec-whitelist-settings-nonce');
        ?>
            
        <table class="form-table">
            <tr valign="top">
                <th scope="row"><?php 
        _e('Enable IP Whitelisting', 'all-in-one-wp-security-and-firewall');
        ?>
:</th>
                <td>
                <input name="aiowps_enable_whitelisting" type="checkbox"<?php 
        if ($aio_wp_security->configs->get_value('aiowps_enable_whitelisting') == '1') {
            echo ' checked="checked"';
        }
        ?>
 value="1"/>
                <span class="description"><?php 
        _e('Check this if you want to enable the whitelisting of selected IP addresses specified in the settings below', 'all-in-one-wp-security-and-firewall');
        ?>
</span>
                </td>
            </tr>            
            <tr valign="top">
                <th scope="row"><?php 
        _e('Your Current IP Address', 'all-in-one-wp-security-and-firewall');
        ?>
:</th>
                <td>
                <input size="20" name="aiowps_user_ip" type="text" value="<?php 
        echo $your_ip_address;
        ?>
" readonly="readonly"/>
                <span class="description"><?php 
        _e('You can copy and paste this address in the text box below if you want to include it in your login whitelist.', 'all-in-one-wp-security-and-firewall');
        ?>
</span>
                </td>
            </tr>            
            <tr valign="top">
                <th scope="row"><?php 
        _e('Enter Whitelisted IP Addresses:', 'all-in-one-wp-security-and-firewall');
        ?>
</th>
                <td>
                    <textarea name="aiowps_allowed_ip_addresses" rows="5" cols="50"><?php 
        echo $result == -1 ? htmlspecialchars($_POST['aiowps_allowed_ip_addresses']) : htmlspecialchars($aio_wp_security->configs->get_value('aiowps_allowed_ip_addresses'));
        ?>
</textarea>
                    <br />
                    <span class="description"><?php 
        _e('Enter one or more IP addresses or IP ranges you wish to include in your whitelist. Only the addresses specified here will have access to the WordPress login page.', 'all-in-one-wp-security-and-firewall');
        ?>
</span>
                    <span class="aiowps_more_info_anchor"><span class="aiowps_more_info_toggle_char">+</span><span class="aiowps_more_info_toggle_text"><?php 
        _e('More Info', 'all-in-one-wp-security-and-firewall');
        ?>
</span></span>
                    <div class="aiowps_more_info_body">
                            <?php 
        echo '<p class="description"><strong>' . __('Each IP address must be on a new line.', 'all-in-one-wp-security-and-firewall') . '</strong></p>';
        echo '<p class="description">' . __('To specify an IPv4 range use a wildcard "*" character. Acceptable ways to use wildcards is shown in the examples below:', 'all-in-one-wp-security-and-firewall') . '</p>';
        echo '<p class="description">' . __('Example 1: 195.47.89.*', 'all-in-one-wp-security-and-firewall') . '</p>';
        echo '<p class="description">' . __('Example 2: 195.47.*.*', 'all-in-one-wp-security-and-firewall') . '</p>';
        echo '<p class="description">' . __('Example 3: 195.*.*.*', 'all-in-one-wp-security-and-firewall') . '</p>';
        echo '<p class="description">' . __('Or you can enter an IPv6 address (NOTE: ranges/wildcards are currently not supported for ipv6)', 'all-in-one-wp-security-and-firewall') . '</p>';
        echo '<p class="description">' . __('Example 4: 4102:0:3ea6:79fd:b:46f8:230f:bb05', 'all-in-one-wp-security-and-firewall') . '</p>';
        echo '<p class="description">' . __('Example 5: 2205:0:1ca2:810d::', 'all-in-one-wp-security-and-firewall') . '</p>';
        ?>
                    </div>

                </td>
            </tr>
        </table>
        <input type="submit" name="aiowps_save_whitelist_settings" value="<?php 
        _e('Save Settings', 'all-in-one-wp-security-and-firewall');
        ?>
" class="button-primary" />
        </form>
        </div></div>
        <?php 
    }
 /**
  * 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 = current_time('mysql');
     $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
     }
 }
 function update_logged_in_user_transient()
 {
     if (is_user_logged_in()) {
         $current_user_ip = AIOWPSecurity_Utility_IP::get_user_ip_address();
         // get the logged in users list from transients entry
         $logged_in_users = AIOWPSecurity_Utility::is_multisite_install() ? get_site_transient('users_online') : get_transient('users_online');
         //            $logged_in_users = get_transient('users_online');
         $current_user = wp_get_current_user();
         $current_user = $current_user->ID;
         $current_time = current_time('timestamp');
         $current_user_info = array("user_id" => $current_user, "last_activity" => $current_time, "ip_address" => $current_user_ip);
         //We will store last activity time and ip address in transient entry
         if ($logged_in_users === false || $logged_in_users == NULL) {
             $logged_in_users = array();
             $logged_in_users[] = $current_user_info;
             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 expire to 30min
         } else {
             $key = 0;
             $do_nothing = false;
             $update_existing = false;
             $item_index = 0;
             foreach ($logged_in_users as $value) {
                 if ($value['user_id'] == $current_user && strcmp($value['ip_address'], $current_user_ip) == 0) {
                     if ($value['last_activity'] < $current_time - 15 * 60) {
                         $update_existing = true;
                         $item_index = $key;
                         break;
                     } else {
                         $do_nothing = true;
                         break;
                     }
                 }
                 $key++;
             }
             if ($update_existing) {
                 //Update transient if the last activity was less than 15 min ago for this user
                 $logged_in_users[$item_index] = $current_user_info;
                 AIOWPSecurity_Utility::is_multisite_install() ? set_site_transient('users_online', $logged_in_users, 30 * 60) : set_transient('users_online', $logged_in_users, 30 * 60);
             } else {
                 if ($do_nothing) {
                     //Do nothing
                 } else {
                     $logged_in_users[] = $current_user_info;
                     AIOWPSecurity_Utility::is_multisite_install() ? set_site_transient('users_online', $logged_in_users, 30 * 60) : set_transient('users_online', $logged_in_users, 30 * 60);
                 }
             }
         }
     }
 }
 }
 if ($errors) {
     $display_form = true;
     echo '<div id="login_error">' . $errors . '</div>';
     $sanitized_email = sanitize_email($email);
     echo display_unlock_form($sanitized_email);
 } else {
     $locked_user = get_user_by('email', $email);
     if (!$locked_user) {
         //user with this email does not exist in the system
         $errors .= '<p>' . __('User account not found!', 'all-in-one-wp-security-and-firewall') . '</p>';
         echo '<div id="login_error">' . $errors . '</div>';
     } else {
         //Process unlock request
         //Generate a special code and unlock url
         $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
         $unlock_url = AIOWPSecurity_User_Login::generate_unlock_request_link($ip_range);
         if (!$unlock_url) {
             //No entry found in lockdown table with this IP range
             $error_msg = '<p>' . __('Error: No locked entry was found in the DB with your IP address range!', 'all-in-one-wp-security-and-firewall') . '</p>';
             echo '<div id="login_error">' . $error_msg . '</div>';
         } else {
             //Send an email to the user
             AIOWPSecurity_User_Login::send_unlock_request_email($email, $unlock_url);
             echo '<p class="message">An email has been sent to you with the unlock instructions.</p>';
         }
     }
     $display_form = false;
 /**
  * Inserts event logs to the database
  * For now we are using for 404 events but in future will expand for other events
  *
  * @param string $event_type: Event type, eg, 404 (see below for list of event types)
  * @param string $username (optional): username
  * 
  * Event types: 404 (...add more as we expand this)
  *
  **/
 static function event_logger($event_type, $username = '')
 {
     global $wpdb, $aio_wp_security;
     //Some initialising
     $url = '';
     $ip_or_host = '';
     $referer_info = '';
     $event_data = '';
     $events_table_name = AIOWPSEC_TBL_EVENTS;
     $ip_or_host = AIOWPSecurity_Utility_IP::get_user_ip_address();
     //Get the IP address of user
     $username = sanitize_user($username);
     $user = get_user_by('login', $username);
     //Returns WP_User object if exists
     if ($user) {
         //If valid user set variables for DB storage later on
         $user_id = absint($user->ID) > 0 ? $user->ID : 0;
     } 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;
     }
     if ($event_type == '404') {
         //if 404 event get some relevant data
         $url = isset($_SERVER['REQUEST_URI']) ? esc_attr($_SERVER['REQUEST_URI']) : '';
         $referer_info = isset($_SERVER['HTTP_REFERER']) ? esc_attr($_SERVER['HTTP_REFERER']) : '';
     }
     $data = array('event_type' => $event_type, 'username' => $username, 'user_id' => $user_id, 'event_date' => current_time('mysql'), 'ip_or_host' => $ip_or_host, 'referer_info' => $referer_info, 'url' => $url, 'event_data' => '');
     //log to database
     $result = $wpdb->insert($events_table_name, $data);
     if ($result == FALSE) {
         $aio_wp_security->debug_logger->log_debug("event_logger: Error inserting record into " . $events_table_name, 4);
         //Log the highly unlikely event of DB error
     }
 }
 static function validate_ip_list($ip_list_array, $list_type = '')
 {
     @ini_set('auto_detect_line_endings', true);
     $errors = '';
     //validate list
     $submitted_ips = $ip_list_array;
     $list = array();
     if (!empty($submitted_ips)) {
         foreach ($submitted_ips as $item) {
             $item = filter_var($item, FILTER_SANITIZE_STRING);
             if (strlen($item) > 0) {
                 $ipParts = explode('.', $item);
                 $isIP = 0;
                 $partcount = 1;
                 $goodip = true;
                 $foundwild = false;
                 if (count($ipParts) < 2) {
                     $errors .= '<p>' . $item . __(' is not a valid ip address format.', 'aiowpsecurity') . '</p>';
                     continue;
                 }
                 foreach ($ipParts as $part) {
                     if ($goodip == true) {
                         if (is_numeric(trim($part)) && trim($part) <= 255 && trim($part) >= 0 || trim($part) == '*') {
                             $isIP++;
                         }
                         switch ($partcount) {
                             case 1:
                                 if (trim($part) == '*') {
                                     $goodip = false;
                                     $errors .= '<p>' . $item . __(' is not a valid ip address format.', 'aiowpsecurity') . '</p>';
                                 }
                                 break;
                             case 2:
                                 if (trim($part) == '*') {
                                     $foundwild = true;
                                 }
                                 break;
                             default:
                                 if (trim($part) != '*') {
                                     if ($foundwild == true) {
                                         $goodip = false;
                                         $errors .= '<p>' . $item . __(' is not a valid ip address format.', 'aiowpsecurity') . '</p>';
                                     }
                                 } else {
                                     $foundwild = true;
                                 }
                                 break;
                         }
                         $partcount++;
                     }
                 }
                 if (ip2long(trim(str_replace('*', '0', $item))) == false) {
                     //invalid ip
                     $errors .= '<p>' . $item . __(' is not a valid ip address format.', 'aiowpsecurity') . '</p>';
                 } elseif (strlen($item) > 4 && !in_array($item, $list)) {
                     $current_user_ip = AIOWPSecurity_Utility_IP::get_user_ip_address();
                     if ($current_user_ip == $item && $list_type == 'blacklist') {
                         //You can't ban your own IP
                         $errors .= '<p>' . __('You cannot ban your own IP address: ', 'aiowpsecurity') . $item . '</p>';
                     } else {
                         $list[] = trim($item);
                     }
                 }
             }
         }
     } else {
         //This function was called with an empty IP address array list
     }
     if (strlen($errors) > 0) {
         $return_payload = array(-1, array($errors));
         return $return_payload;
     }
     if (sizeof($list) >= 1) {
         sort($list);
         $list = array_unique($list, SORT_STRING);
         $return_payload = array(1, $list);
         return $return_payload;
     }
     $return_payload = array(1, array());
     return $return_payload;
 }