//let's make sure this page is being accessed through WP if (!function_exists('current_user_can')) { die('Sorry'); } elseif (!current_user_can('manage_options')) { wp_die(__('You do not have sufficient permissions to access this page.')); } elseif (!meow_get_option('meow_protect_login')) { echo '<div class="wrap"><div class="error fade"><p>Log-in protection is disabled.</p></div>' . meow_get_header() . '</div>'; exit; } //-------------------------------------------------- //Build data global $wpdb; //first let's figure out who we're supposed to ignore $meow_ip_pardoned = meow_get_option('meow_ip_pardoned'); $meow_ip_exempt = meow_get_option('meow_ip_exempt'); $meow_ip_ignore = meow_sanitize_ips(array_merge($meow_ip_pardoned, $meow_ip_exempt)); //find the log-in protection settings $meow_fail_limit = meow_get_option('meow_fail_limit'); $meow_fail_window = meow_get_option('meow_fail_window'); $meow_fail_reset_on_success = meow_get_option('meow_fail_reset_on_success'); //first pass: find probably banned people $dbResult = $wpdb->get_results("SELECT `ip`, UNIX_TIMESTAMP() - MIN(`date`) AS `first_fail` FROM `{$wpdb->prefix}meow_log` WHERE UNIX_TIMESTAMP()-`date` <= {$meow_fail_window} AND `success`=0 " . (count($meow_ip_ignore) ? "AND NOT `ip` IN ('" . implode("','", $meow_ip_ignore) . "') " : '') . "GROUP BY `ip` ORDER BY `first_fail` ASC", ARRAY_A); $meow_banned = array(); if ($wpdb->num_rows) { //save as IP=>(seconds since first failure) foreach ($dbResult as $Row) { $meow_banned[$Row['ip']] = (int) $Row['first_fail']; } } //if the fail count resets on success, we have another pass to do (but only if the first yielded results) //I'm sorry, I can't think of an efficient way to do this in a single pass
//validate form data... $meowdata['meow_protect_login'] = intval($_POST['meow_protect_login']) === 1; $meowdata['meow_fail_limit'] = (int) $_POST['meow_fail_limit']; //silently correct invalid choice if ($meowdata['meow_fail_limit'] < 1) { $meow['meow_fail_limit'] = 5; } $meowdata['meow_fail_window'] = 60 * intval($_POST['meow_fail_window']); //silently correct invalid choice if ($meowdata['meow_fail_window'] < 60) { $meow['meow_fail_window'] = 43200; } elseif ($meowdata['meow_fail_window'] > 86400) { $meow['meow_fail_window'] = 43200; } $meowdata['meow_fail_reset_on_success'] = intval($_POST['meow_fail_reset_on_success']) === 1; $meowdata['meow_ip_exempt'] = meow_sanitize_ips(explode("\n", meow_newlines($_POST['meow_ip_exempt']))); $meowdata['meow_apocalypse_title'] = trim(strip_tags($_POST["meow_apocalypse_title"])); $meowdata['meow_apocalypse_content'] = trim(strip_tags($_POST['meow_apocalypse_content'])); $meowdata['meow_clean_database'] = intval($_POST['meow_clean_database']) === 1; $meowdata['meow_data_expiration'] = (int) $_POST['meow_data_expiration']; //silently correct bad data if ($meowdata['meow_data_expiration'] < 10) { $meowdata['meow_data_expiration'] = 90; } $meowdata['meow_store_ua'] = intval($_POST['meow_store_ua']) === 1; $meowdata['meow_password_alpha'] = in_array($_POST['meow_password_alpha'], array('optional', 'required', 'required-both')) ? $_POST['meow_password_alpha'] : 'optional'; $meowdata['meow_password_numeric'] = in_array($_POST['meow_password_numeric'], array('optional', 'required')) ? $_POST['meow_password_numeric'] : 'optional'; $meowdata['meow_password_symbol'] = in_array($_POST['meow_password_symbol'], array('optional', 'required')) ? $_POST['meow_password_symbol'] : 'optional'; $meowdata['meow_password_length'] = (double) $_POST['meow_password_length']; //silently correct bad data if ($meowdata['meow_password_length'] < 1) {
function meow_get_option($option) { switch ($option) { //is log-in protection enabled? case 'meow_protect_login': return (bool) get_option('meow_protect_login', true); //the maximum number of log-in failures allowed //the maximum number of log-in failures allowed case 'meow_fail_limit': $tmp = (int) get_option('meow_fail_limit', 5); //silently correct bad entries if ($tmp < 1) { $tmp = 5; update_option('meow_fail_limit', 5); } return $tmp; //the window in which to look for log-in failures //the window in which to look for log-in failures case 'meow_fail_window': $tmp = (int) get_option('meow_fail_window', 43200); if ($tmp < 60 || $tmp > 86400) { $tmp = 43200; update_option('meow_fail_window', 43200); } return $tmp; //whether or not a successful log-in resets the fail count //whether or not a successful log-in resets the fail count case 'meow_fail_reset_on_success': return (bool) get_option('meow_fail_reset_on_success', true); //an array of IP addresses to ignore //an array of IP addresses to ignore case 'meow_ip_exempt': return meow_sanitize_ips(get_option('meow_ip_exempt', array())); //a list of IPs that have been temporarily pardoned //a list of IPs that have been temporarily pardoned case 'meow_ip_pardoned': return meow_sanitize_ips(get_option('meow_ip_pardoned', array())); //the apocalypse page title //the apocalypse page title case 'meow_apocalypse_title': return trim(strip_tags(get_option('meow_apocalypse_title', 'Oops...'))); //the apocalypse page content //the apocalypse page content case 'meow_apocalypse_content': return strip_tags(get_option('meow_apocalypse_content', "You have exceeded the maximum number of log-in attempts.\nSorry.")); //whether or not to store the UA string //whether or not to store the UA string case 'meow_store_ua': return (bool) get_option('meow_store_ua', false); //whether or not to remove old log-in entries from the database //whether or not to remove old log-in entries from the database case 'meow_clean_database': return (bool) get_option('meow_clean_database', true); //weather to use a custom client ip header //weather to use a custom client ip header case 'meow_ip_key': $tmp = get_option('meow_ip_key', 'REMOTE_ADDR'); //make sure this is a valid index before returning it if (array_key_exists($tmp, $_SERVER) && filter_var($_SERVER[$tmp], FILTER_VALIDATE_IP)) { return $tmp; } else { return 'REMOTE_ADDR'; } //how long to keep old log-in entries in the database //how long to keep old log-in entries in the database case 'meow_data_expiration': $tmp = (int) get_option('meow_data_expiration', 90); if ($tmp < 10) { $tmp = 90; update_option('meow_data_expiration', 90); } return $tmp; //do passwords require letters? //do passwords require letters? case 'meow_password_alpha': $tmp = get_option('meow_password_alpha', 'required'); if (!in_array($tmp, array('optional', 'required', 'required-both'))) { $tmp = 'required'; update_option('meow_password_alpha', 'required'); } return $tmp; //do passwords require numbers? //do passwords require numbers? case 'meow_password_numeric': $tmp = get_option('meow_password_numeric', 'required'); if (!in_array($tmp, array('optional', 'required'))) { $tmp = 'required'; update_option('meow_password_numeric', 'required'); } return $tmp; //do passwords require symbols? //do passwords require symbols? case 'meow_password_symbol': $tmp = get_option('meow_password_symbol', 'optional'); if (!in_array($tmp, array('optional', 'required'))) { $tmp = 'optional'; update_option('meow_password_symbol', 'optional'); } return $tmp; //minimum password length //minimum password length case 'meow_password_length': $tmp = (int) get_option('meow_password_length', 10); if ($tmp < 1) { $tmp = 10; update_option('meow_password_length', 10); } return $tmp; //whether or not to remove the generator tag from <head> //whether or not to remove the generator tag from <head> case 'meow_remove_generator_tag': return (bool) get_option('meow_remove_generator_tag', true); //are we disabling the theme/plugin editor? //are we disabling the theme/plugin editor? case 'meow_disable_editor': return (bool) get_option('meow_disable_editor', false); } return get_option($option, false); }