<div id="meow-graph-ip" class="meow-graph meow-graph-date" data-graph-content="ip"></div> <p>Unique individuals (IP addresses) attempting log-in. This is probably the most useful metric for determining how big a target you are for nogoodniks.</p> </div> <div class="meow-clear"> </div> </div> </div> <!-- end log-in history graph --> <div class="postbox"> <h3 class="hndle">Data Retention</h3> <div class="inside"> <p><?php //are logs cleaned every so often? $meow_clean_database = meow_get_option('meow_clean_database'); $meow_data_expiration = meow_get_option('meow_data_expiration'); if ($meow_clean_database) { echo "Records older than {$meow_data_expiration} days are automatically purged from the database."; } else { echo "Log-in data is currently retained forever, which is a long time. If you find these stats getting a touch unruly, you can have the system automatically purge records after a certain amount of time."; } ?> Visit the <a href="<?php echo esc_url(admin_url('options-general.php?page=meow-settings')); ?> " title="Apocalypse Meow settings">settings page</a> to change this behavior.</p> </div> </div> </div><!-- /.has-sidebar-content --> </div><!-- /.has-sidebar -->
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 if ($meow_fail_reset_on_success && count($meow_banned)) { //are there any successful logins for these maybe-banned users within the window? $dbResult = $wpdb->get_results("SELECT DISTINCT `ip` FROM `{$wpdb->prefix}meow_log` WHERE UNIX_TIMESTAMP()-`date` <= {$meow_fail_window} AND `success`=0 AND `ip` IN ('" . implode("','", array_keys($meow_banned)) . "') ORDER BY `ip` ASC", ARRAY_A); if ($wpdb->num_rows) {
echo '<div class="error fade"><p>The username "' . esc_html($tmp) . '" is not valid; try again.</p></div>'; } else { $current_user = wp_get_current_user(); echo '<div class="updated fade"><p>Congratulations, the old "admin" user has been successfully changed to "' . esc_html($tmp) . '".' . ($current_user->user_login === 'admin' ? ' Unfortunately you were logged in as that now nonexistent user, so you\'ll have to take a moment to <a href="' . esc_url(admin_url('options-general.php?page=meow-settings')) . '">re-login</a> (as "' . esc_html($tmp) . '" this time). :)' : '') . '</p></div>'; $wpdb->update($wpdb->users, array('user_login' => $tmp), array('user_login' => 'admin'), array('%s'), array('%s')); if ($current_user->user_login === 'admin') { die; } $meow_changed_admin = true; } } } } else { $options = array('meow_protect_login', 'meow_fail_limit', 'meow_fail_window', 'meow_fail_reset_on_success', 'meow_ip_exempt', 'meow_apocalypse_content', 'meow_apocalypse_title', 'meow_store_ua', 'meow_clean_database', 'meow_data_expiration', 'meow_password_alpha', 'meow_password_numeric', 'meow_password_symbol', 'meow_password_length', 'meow_remove_generator_tag', 'meow_disable_editor', 'meow_ip_key'); foreach ($options as $option) { $meowdata[$option] = meow_get_option($option); } } //-------------------------------------------------- //Output the form! ?> <style type="text/css"> .form-table { clear: left!important; } .meow-hidden { display: none; } </style> <div class="wrap">
function meow_password_rules(&$pass1, &$pass2) { global $meow_password_error; //WP can handle password mismatch or empty password errors if ($pass1 !== $pass2 || !strlen($pass1)) { return false; } //needs a letter if (meow_get_option('meow_password_alpha') === 'required' && !preg_match('/[a-z]/i', $pass1)) { $meow_password_error = __('The password must contain at least one letter.'); return false; } elseif (meow_get_option('meow_password_alpha') === 'required-both' && (!preg_match('/[a-z]/', $pass1) || !preg_match('/[A-Z]/', $pass1))) { $meow_password_error = __('The password must contain at least one uppercase and one lowercase letter.'); return false; } //needs a number if (meow_get_option('meow_password_numeric') === 'required' && !preg_match('/\\d/', $pass1)) { $meow_password_error = __('The password must contain at least one number.'); return false; } //needs a symbol if (meow_get_option('meow_password_symbol') === 'required' && !preg_match('/[^a-z0-9]/i', $pass1)) { $meow_password_error = __('The password must contain at least one non-alphanumeric symbol.'); return false; } //check password length $meow_password_length = meow_get_option('meow_password_length'); if (strlen($pass1) < $meow_password_length) { $meow_password_error = __("The password must be at least {$meow_password_length} characters long."); return false; } return true; }