Exemple #1
0
function itsec_network_brute_force_dismiss_notice()
{
    if (wp_verify_nonce($_REQUEST['notice_nonce'], 'dismiss-brute-force-network-notice')) {
        ITSEC_Modules::set_setting('network-brute-force', 'api_nag', false);
        wp_send_json_success();
    }
    wp_send_json_error();
}
Exemple #2
0
 public function dismiss_file_change_warning()
 {
     ini_set('display_errors', 1);
     if (!wp_verify_nonce($_REQUEST['nonce'], 'itsec-file-change-dismiss-warning')) {
         die('Security check');
     }
     ITSEC_Modules::set_setting('file-change', 'show_warning', false);
 }
Exemple #3
0
 /**
  * Execute module upgrade
  *
  * @return void
  */
 public function execute_upgrade($itsec_old_version)
 {
     if ($itsec_old_version < 4041) {
         $last_generated = get_site_option('itsec_salts');
         if (is_int($last_generated) && $last_generated >= 0) {
             ITSEC_Modules::set_setting('wordpress-salts', 'last_generated', $last_generated);
         }
     }
 }
Exemple #4
0
function itsec_ban_users_handle_new_blacklisted_ip($ip)
{
    $host_list = ITSEC_Modules::get_setting('ban-users', 'host_list', array());
    if (!is_array($host_list)) {
        $host_list = array();
    }
    $host_list[] = $ip;
    ITSEC_Modules::set_setting('ban-users', 'host_list', $host_list);
}
 public function add_scripts()
 {
     foreach ($this->modules as $id => $module) {
         $module->enqueue_scripts_and_styles();
     }
     foreach ($this->widgets as $id => $widget) {
         $widget->enqueue_scripts_and_styles();
     }
     $vars = array('ajax_action' => 'itsec_settings_page', 'ajax_nonce' => wp_create_nonce('itsec-settings-nonce'), 'show_security_check' => ITSEC_Modules::get_setting('global', 'show_security_check'), 'translations' => $this->translations);
     if ($vars['show_security_check']) {
         ITSEC_Modules::set_setting('global', 'show_security_check', false);
         if (!empty($_GET['module']) && 'security-check' === $_GET['module']) {
             $vars['show_security_check'] = false;
         }
     }
     wp_enqueue_script('itsec-settings-page-script', plugins_url('js/script.js', __FILE__), array(), $this->version, true);
     wp_localize_script('itsec-settings-page-script', 'itsec_page', $vars);
 }
Exemple #6
0
 public function execute_file_check($scheduled_call = true, $return_data = false)
 {
     global $itsec_logger, $itsec_globals;
     if (false === $this->running) {
         $this->running = true;
         $send_email = true;
         ITSEC_Lib::set_minimum_memory_limit('256M');
         $itsec_files = ITSEC_Core::get_itsec_files();
         if ($itsec_files->get_file_lock('file_change', 300)) {
             //make sure it isn't already running
             define('ITSEC_DOING_FILE_CHECK', true);
             //figure out what chunk we're on
             if (isset($this->settings['split']) && true === $this->settings['split']) {
                 if (isset($this->settings['last_chunk']) && false !== $this->settings['last_chunk'] && $this->settings['last_chunk'] < 6) {
                     $chunk = $this->settings['last_chunk'] + 1;
                 } else {
                     $chunk = 0;
                 }
             } else {
                 $chunk = false;
             }
             if (false !== $chunk) {
                 $db_field = 'itsec_local_file_list_' . $chunk;
             } else {
                 $db_field = 'itsec_local_file_list';
             }
             //set base memory
             $memory_used = @memory_get_peak_usage();
             $logged_files = get_site_option($db_field);
             //if there are no old files old file list is an empty array
             if (false === $logged_files) {
                 $send_email = false;
                 $logged_files = array();
                 if (is_multisite()) {
                     add_site_option($db_field, $logged_files);
                 } else {
                     add_option($db_field, $logged_files, '', 'no');
                 }
             }
             do_action('itsec-file-change-start-scan');
             $current_files = $this->scan_files('', $scheduled_call, $chunk);
             //scan current files
             do_action('itsec-file-change-end-scan');
             $files_added = @array_diff_assoc($current_files, $logged_files);
             //files added
             $files_removed = @array_diff_assoc($logged_files, $current_files);
             //files deleted
             $current_minus_added = @array_diff_key($current_files, $files_added);
             //remove all added files from current filelist
             $logged_minus_deleted = @array_diff_key($logged_files, $files_removed);
             //remove all deleted files from old file list
             $files_changed = array();
             //array of changed files
             do_action('itsec-file-change-start-hash-comparisons');
             //compare file hashes and mod dates
             foreach ($current_minus_added as $current_file => $current_attr) {
                 if (array_key_exists($current_file, $logged_minus_deleted)) {
                     //if attributes differ added to changed files array
                     if (isset($current_attr['mod_date']) && 0 != strcmp($current_attr['mod_date'], $logged_minus_deleted[$current_file]['mod_date']) || 0 != strcmp($current_attr['d'], $logged_minus_deleted[$current_file]['d']) || (isset($current_attr['hash']) && 0 != strcmp($current_attr['hash'], $logged_minus_deleted[$current_file]['hash']) || 0 != strcmp($current_attr['h'], $logged_minus_deleted[$current_file]['h']))) {
                         $remote_check = apply_filters('itsec_process_changed_file', true, $current_file, $current_attr['h']);
                         //hook to run actions on a changed file at time of discovery
                         if (true === $remote_check) {
                             //don't list the file if it matches the WordPress.org hash
                             $files_changed[$current_file]['h'] = isset($current_attr['hash']) ? $current_attr['hash'] : $current_attr['h'];
                             $files_changed[$current_file]['d'] = isset($current_attr['mod_date']) ? $current_attr['mod_date'] : $current_attr['d'];
                         }
                     }
                 }
             }
             //get count of changes
             $files_added_count = sizeof($files_added);
             $files_deleted_count = sizeof($files_removed);
             $files_changed_count = sizeof($files_changed);
             if (0 < $files_added_count) {
                 $files_added = apply_filters('itsec_process_added_files', $files_added);
                 //hook to run actions on all files added
                 $files_added_count = sizeof($files_added);
             }
             if (0 < $files_deleted_count) {
                 do_action('itsec_process_removed_files', $files_removed);
                 //hook to run actions on all files removed
             }
             do_action('itsec-file-change-end-hash-comparisons');
             //create single array of all changes
             $full_change_list = array('added' => $files_added, 'removed' => $files_removed, 'changed' => $files_changed);
             $this->settings['latest_changes'] = array('added' => count($files_added), 'removed' => count($files_removed), 'changed' => count($files_changed));
             update_site_option($db_field, $current_files);
             //Cleanup variables when we're done with them
             unset($files_added);
             unset($files_removed);
             unset($files_changed);
             unset($current_files);
             $this->settings['last_run'] = $itsec_globals['current_time'];
             $this->settings['last_chunk'] = $chunk;
             ITSEC_Modules::set_settings('file-change', $this->settings);
             //get new max memory
             $check_memory = @memory_get_peak_usage();
             if ($check_memory > $memory_used) {
                 $memory_used = $check_memory - $memory_used;
             }
             $full_change_list['memory'] = round($memory_used / 1000000, 2);
             $itsec_logger->log_event('file_change', 8, $full_change_list);
             if (true === $send_email && false !== $scheduled_call && isset($this->settings['email']) && true === $this->settings['email'] && (0 < $files_added_count || 0 < $files_changed_count || 0 < $files_deleted_count)) {
                 $email_details = array($files_added_count, $files_deleted_count, $files_changed_count, $full_change_list);
                 $this->send_notification_email($email_details);
             }
             if (function_exists('get_current_screen') && (!isset(get_current_screen()->id) || false === strpos(get_current_screen()->id, 'security_page_toplevel_page_itsec_logs')) && isset($this->settings['notify_admin']) && true === $this->settings['notify_admin']) {
                 ITSEC_Modules::set_setting('file-change', 'show_warning', true);
             }
             $itsec_files->release_file_lock('file_change');
             if ($files_added_count > 0 || $files_changed_count > 0 || $files_deleted_count > 0) {
                 $this->running = false;
                 //There were changes found
                 if ($return_data) {
                     return $full_change_list;
                 } else {
                     return true;
                 }
             } else {
                 $this->running = false;
                 return false;
                 //No changes were found
             }
         }
         $this->running = false;
         return -1;
         //An error occured
     }
     return -1;
 }
 /**
  * Executes backup function.
  *
  * Handles the execution of database backups.
  *
  * @since 4.0.0
  *
  * @param bool $one_time whether this is a one-time backup
  *
  * @return void
  */
 private function execute_backup($one_time = false)
 {
     global $wpdb, $itsec_globals, $itsec_logger;
     //get all of the tables
     if (isset($this->settings['all_sites']) && true === $this->settings['all_sites']) {
         $tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
         //retrieve a list of all tables in the DB
     } else {
         $tables = $wpdb->get_results('SHOW TABLES LIKE "' . $wpdb->base_prefix . '%"', ARRAY_N);
         //retrieve a list of all tables for this WordPress installation
     }
     $return = '';
     //cycle through each table
     foreach ($tables as $table) {
         $num_fields = sizeof($wpdb->get_results('DESCRIBE `' . $table[0] . '`;'));
         $return .= 'DROP TABLE IF EXISTS `' . $table[0] . '`;';
         $row2 = $wpdb->get_row('SHOW CREATE TABLE `' . $table[0] . '`;', ARRAY_N);
         $return .= PHP_EOL . PHP_EOL . $row2[1] . ";" . PHP_EOL . PHP_EOL;
         if (!in_array(substr($table[0], strlen($wpdb->prefix)), $this->settings['exclude'])) {
             $result = $wpdb->get_results('SELECT * FROM `' . $table[0] . '`;', ARRAY_N);
             foreach ($result as $row) {
                 $return .= 'INSERT INTO `' . $table[0] . '` VALUES(';
                 for ($j = 0; $j < $num_fields; $j++) {
                     $row[$j] = addslashes($row[$j]);
                     $row[$j] = preg_replace('#' . PHP_EOL . '#', "\n", $row[$j]);
                     if (isset($row[$j])) {
                         $return .= '"' . $row[$j] . '"';
                     } else {
                         $return .= '""';
                     }
                     if ($j < $num_fields - 1) {
                         $return .= ',';
                     }
                 }
                 $return .= ");" . PHP_EOL;
             }
         }
         $return .= PHP_EOL . PHP_EOL;
     }
     $return .= PHP_EOL . PHP_EOL;
     //save file
     $file = 'backup-' . substr(sanitize_title(get_bloginfo('name')), 0, 20) . '-' . current_time('Ymd-His') . '-' . wp_generate_password(30, false);
     require_once ITSEC_Core::get_core_dir() . 'lib/class-itsec-lib-directory.php';
     $dir = $this->settings['location'];
     ITSEC_Lib_Directory::create($dir);
     $fileext = '.sql';
     $handle = @fopen($dir . '/' . $file . '.sql', 'w+');
     @fwrite($handle, $return);
     @fclose($handle);
     //zip the file
     if (true === $this->settings['zip']) {
         if (!class_exists('PclZip')) {
             require ABSPATH . 'wp-admin/includes/class-pclzip.php';
         }
         $zip = new PclZip($dir . '/' . $file . '.zip');
         if (0 != $zip->create($dir . '/' . $file . '.sql', PCLZIP_OPT_REMOVE_PATH, $dir)) {
             //delete .sql and keep zip
             @unlink($dir . '/' . $file . '.sql');
             $fileext = '.zip';
         }
     }
     if (2 !== $this->settings['method'] || true === $one_time) {
         require_once ITSEC_Core::get_core_dir() . 'lib/class-itsec-mailer.php';
         $mail = new ITSEC_Mail();
         $mail->add_header(esc_html__('Database Backup', 'better-wp-security'), sprintf(wp_kses(__('Site Database Backup for <b>%s</b>', 'better-wp-security'), array('b' => array())), date_i18n(get_option('date_format'))));
         $mail->add_info_box(esc_html__('Attached is the database backup file for your site.', 'better-wp-security'), 'attachment');
         $mail->add_section_heading(esc_html__('Website', 'better-wp-security'));
         $mail->add_text(esc_html(network_home_url()));
         $mail->add_section_heading(esc_html__('Date', 'better-wp-security'));
         $mail->add_text(esc_html(date_i18n(get_option('date_format'))));
         $mail->add_footer();
         $raw_recipients = ITSEC_Modules::get_setting('global', 'backup_email');
         $recipients = array();
         foreach ($raw_recipients as $recipient) {
             $recipient = trim($recipient);
             if (is_email($recipient)) {
                 $recipients[] = $recipient;
             }
         }
         $subject = sprintf(esc_html__('[%s] Database Backup', 'better-wp-security'), esc_url(network_home_url()));
         $subject = apply_filters('itsec_backup_email_subject', $subject);
         $attachment = array("{$dir}/{$file}{$fileext}");
         $mail_success = $mail->send($recipients, $subject, $attachment);
     }
     if (1 === $this->settings['method']) {
         @unlink($dir . '/' . $file . $fileext);
     } else {
         $retain = isset($this->settings['retain']) ? absint($this->settings['retain']) : 0;
         //delete extra files
         if (0 < $retain) {
             $files = scandir($dir, 1);
             $count = 0;
             if (is_array($files) && 0 < count($files)) {
                 foreach ($files as $file) {
                     if (strstr($file, 'backup')) {
                         if ($count >= $retain) {
                             @unlink(trailingslashit($dir) . $file);
                         }
                         $count++;
                     }
                 }
             }
         }
     }
     if (false === $one_time) {
         ITSEC_Modules::set_setting('backup', 'last_run', ITSEC_Core::get_current_time_gmt());
     }
     switch ($this->settings['method']) {
         case 0:
             if (false === $mail_success) {
                 $status = array('status' => __('Error', 'better-wp-security'), 'details' => __('saved locally but email to backup recipients could not be sent.', 'better-wp-security'));
             } else {
                 $status = array('status' => __('Success', 'better-wp-security'), 'details' => __('emailed to backup recipients and saved locally', 'better-wp-security'));
             }
             break;
         case 1:
             if (false === $mail_success) {
                 $status = array('status' => __('Error', 'better-wp-security'), 'details' => __('email to backup recipients could not be sent.', 'better-wp-security'));
             } else {
                 $status = array('status' => __('Success', 'better-wp-security'), 'details' => __('emailed to backup recipients', 'better-wp-security'));
             }
             break;
         default:
             $status = array('status' => __('Success', 'better-wp-security'), 'details' => __('saved locally', 'better-wp-security'));
             break;
     }
     $itsec_logger->log_event('backup', 3, array($status));
 }
 private function get_log_file()
 {
     if (isset($this->log_file)) {
         return $this->log_file;
         $this->rotate_log();
     }
     $log_location = ITSEC_Modules::get_setting('global', 'log_location');
     $log_info = ITSEC_Modules::get_setting('global', 'log_info');
     if (empty($log_info)) {
         // We need wp_generate_password() to create a cryptographically secure file name
         if (!function_exists('wp_generate_password')) {
             $this->log_file = false;
             return false;
         }
         $log_info = substr(sanitize_title(get_bloginfo('name')), 0, 20) . '-' . wp_generate_password(30, false);
         ITSEC_Modules::set_setting('global', 'log_info', $log_info);
     }
     $this->log_file = "{$log_location}/event-log-{$log_info}.log";
     return $this->log_file;
 }
 /**
  * Gets the version of jQuery enqueued
  */
 function store_jquery_version()
 {
     global $wp_scripts;
     if ((is_home() || is_front_page()) && is_user_logged_in()) {
         $stored_jquery_version = ITSEC_Modules::get_setting('wordpress-tweaks', 'jquery_version');
         $current_jquery_version = $wp_scripts->registered['jquery']->ver;
         if ($current_jquery_version !== $stored_jquery_version) {
             ITSEC_Modules::set_setting('wordpress-tweaks', 'jquery_version', $current_jquery_version);
         }
     }
 }
Exemple #10
0
 public static function change_content_directory($dir_name)
 {
     $dir_name = sanitize_file_name($dir_name);
     if (empty($dir_name)) {
         return new WP_Error('itsec-content-directory-utility-change-content-directory-empty-directory-name', __('The content directory cannot be changed to a blank directory name.', 'better-wp-security'));
     }
     if (preg_match('{^(?:/|\\|[a-z]:)}i', $dir_name)) {
         return new WP_Error('itsec-content-diraectory-utility-change-content-directory-received-absolute-path', sprintf(__('The new directory name cannot be an absolute path. Please supply a path that is relative to <code>ABSPATH</code> (<code>%s</code>).', 'better-wp-security'), esc_html(ABSPATH)));
     }
     if (0 === strpos(WP_CONTENT_DIR, ABSPATH)) {
         $old_name = substr(WP_CONTENT_DIR, strlen(ABSPATH));
         $new_name = $dir_name;
     } else {
         $old_name = WP_CONTENT_DIR;
         $new_name = ABSPATH . $dir_name;
     }
     $old_dir = WP_CONTENT_DIR;
     $new_dir = ABSPATH . $dir_name;
     if ($old_dir === $new_dir) {
         return new WP_Error('itsec-content-directory-utility-change-content-directory-received-same-directory', __('The new directory name cannot be the same as the current directory name. Please supply a new directory name.', 'better-wp-security'));
     }
     if (file_exists($new_dir)) {
         return new WP_Error('itsec-content-directory-utility-change-content-directory-path-already-exists', sprintf(__('A file or directory already exists at <code>%s</code>. No Directory Name changes have been made. Please choose a new Directory Name or remove the existing file or directory and try again.', 'better-wp-security'), esc_html($new_dir)));
     }
     require_once ITSEC_Core::get_core_dir() . '/lib/class-itsec-lib-config-file.php';
     $old_permissions = ITSEC_Lib_Directory::get_permissions($old_dir);
     $result = rename($old_dir, $new_dir);
     if (!$result) {
         /* translators: 1: Old directory path, 2: New directory path */
         return new WP_Error('itsec-content-directory-utility-change-content-directory-cannot-rename-directory', sprintf(__('Unable to rename the <code>%1$s</code> directory to <code>%2$s</code>. This could indicate a file permission issue or that your server does not support the supplied name as a valid directory name. No config file or directory changes have been made.', 'better-wp-security'), esc_html($old_name), esc_html($new_name)));
     }
     // Make sure ITSEC_Core knows it's in a different place
     $plugin_file = str_replace($old_dir, $new_dir, ITSEC_Core::get_plugin_file());
     ITSEC_Core::set_plugin_file($plugin_file);
     ITSEC_Core::update_wp_upload_dir($old_dir, $new_dir);
     ITSEC_Modules::update_module_paths($old_dir, $new_dir);
     $new_permissions = ITSEC_Lib_Directory::get_permissions($new_dir);
     if (is_int($old_permissions) && is_int($new_permissions) && $old_permissions != $new_permissions) {
         $result = ITSEC_Lib_Directory::chmod($new_dir, $old_permissions);
         if (is_wp_error($result)) {
             /* translators: 1: Directory path, 2: Directory permissions */
             return new WP_Error('itsec-content-directory-utility-change-content-directory-unable-to-change-permissions', sprintf(__('Unable to set the permissions of the new Directory Name (<code>%1$s</code>) to match the permissions of the old Directory Name. You may have to manually change the permissions of the directory to <code>%2$s</code> in order for your site to function properly.', 'better-wp-security'), esc_html($new_name), esc_html($old_permissions)));
         }
     }
     if ('wp-content' === $dir_name) {
         // We're undoing the change.
         $expression = self::get_wp_config_define_expression();
         $expression = substr($expression, 0, -1);
         $expression .= "[\r\n]*|";
         $modification_result = ITSEC_Lib_Config_File::remove_from_wp_config($expression);
     } else {
         $modification = self::get_wp_config_modification($new_dir, get_option('siteurl') . "/{$dir_name}");
         $modification_result = ITSEC_Lib_Config_File::append_wp_config($modification, true);
     }
     if (is_wp_error($modification_result)) {
         $rename_result = rename($new_dir, $old_dir);
         if ($rename_result) {
             // Reset the ITSEC_Core plugin file back to its old setting.
             $plugin_file = str_replace($new_dir, $old_dir, ITSEC_Core::get_plugin_file());
             ITSEC_Core::set_plugin_file($plugin_file);
             ITSEC_Core::update_wp_upload_dir($new_dir, $old_dir);
             ITSEC_Modules::update_module_paths($new_dir, $old_dir);
             ITSEC_Lib_Directory::chmod($old_dir, $old_permissions);
             /* translators: 1: Specific error details */
             return new WP_Error($modification_result->get_error_code(), sprintf(__('Unable to update the <code>wp-config.php</code> file. No directory or config file changes have been made. The error that prevented the file from updating is as follows: %1$s', 'better-wp-security'), $modification_result->get_error_message()));
         } else {
             /* translators: 1: Old directory path, 2: New directory path, 3: Specific error details */
             return new WP_Error($modification_result->get_error_code(), sprintf(__('CRITICAL ERROR: The <code>%1$s</code> directory was successfully renamed to the new name (<code>%2$s</code>). However, an error occurred when updating the <code>wp-config.php</code> file to configure WordPress to use the new content directory. iThemes Security attempted to rename the directory back to its original name, but an unknown error prevented the rename from working as expected. In order for your site to function properly, you will either need to manually rename the <code>%2$s</code> directory back to <code>%1$s</code> or manually update the <code>wp-config.php</code> file with the necessary modifications. The error that prevented the file from updating is as follows: %3$s', 'better-wp-security'), $old_name, $new_name, $modification_result->get_error_message()));
         }
     }
     $backups_location = ITSEC_Modules::get_setting('backup', 'location');
     $backups_location = str_replace($old_dir, $new_dir, $backups_location);
     ITSEC_Modules::set_setting('backup', 'location', $backups_location);
     $log_location = ITSEC_Modules::get_setting('global', 'log_location');
     $log_location = str_replace($old_dir, $new_dir, $log_location);
     ITSEC_Modules::set_setting('global', 'log_location', $log_location);
     $nginx_file = ITSEC_Modules::get_setting('global', 'nginx_file');
     $nginx_file = str_replace($old_dir, $new_dir, $nginx_file);
     ITSEC_Modules::set_setting('global', 'nginx_file', $nginx_file);
     return $dir_name;
 }
Exemple #11
0
 private static function enforce_setting($module, $setting_name, $setting_value, $description)
 {
     if (!in_array($module, self::$available_modules)) {
         return;
     }
     if (ITSEC_Modules::get_setting($module, $setting_name) !== $setting_value) {
         ITSEC_Modules::set_setting($module, $setting_name, $setting_value);
         ob_start();
         self::open_container();
         echo "<p>{$description}</p>";
         echo '</div>';
         self::$actions_taken[] = ob_get_clean();
         ITSEC_Response::reload_module($module);
     }
 }
Exemple #12
0
 /**
  * Executes backup function.
  *
  * Handles the execution of database backups.
  *
  * @since 4.0.0
  *
  * @param bool $one_time whether this is a one-time backup
  *
  * @return void
  */
 private function execute_backup($one_time = false)
 {
     global $wpdb, $itsec_globals, $itsec_logger;
     //get all of the tables
     if (isset($this->settings['all_sites']) && true === $this->settings['all_sites']) {
         $tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
         //retrieve a list of all tables in the DB
     } else {
         $tables = $wpdb->get_results('SHOW TABLES LIKE "' . $wpdb->base_prefix . '%"', ARRAY_N);
         //retrieve a list of all tables for this WordPress installation
     }
     $return = '';
     //cycle through each table
     foreach ($tables as $table) {
         $num_fields = sizeof($wpdb->get_results('DESCRIBE `' . $table[0] . '`;'));
         $return .= 'DROP TABLE IF EXISTS `' . $table[0] . '`;';
         $row2 = $wpdb->get_row('SHOW CREATE TABLE `' . $table[0] . '`;', ARRAY_N);
         $return .= PHP_EOL . PHP_EOL . $row2[1] . ";" . PHP_EOL . PHP_EOL;
         if (!in_array(substr($table[0], strlen($wpdb->prefix)), $this->settings['exclude'])) {
             $result = $wpdb->get_results('SELECT * FROM `' . $table[0] . '`;', ARRAY_N);
             foreach ($result as $row) {
                 $return .= 'INSERT INTO `' . $table[0] . '` VALUES(';
                 for ($j = 0; $j < $num_fields; $j++) {
                     $row[$j] = addslashes($row[$j]);
                     $row[$j] = preg_replace('#' . PHP_EOL . '#', "\n", $row[$j]);
                     if (isset($row[$j])) {
                         $return .= '"' . $row[$j] . '"';
                     } else {
                         $return .= '""';
                     }
                     if ($j < $num_fields - 1) {
                         $return .= ',';
                     }
                 }
                 $return .= ");" . PHP_EOL;
             }
         }
         $return .= PHP_EOL . PHP_EOL;
     }
     $return .= PHP_EOL . PHP_EOL;
     //save file
     $file = 'backup-' . substr(sanitize_title(get_bloginfo('name')), 0, 20) . '-' . current_time('Ymd-His') . '-' . wp_generate_password(30, false);
     require_once ITSEC_Core::get_core_dir() . 'lib/class-itsec-lib-directory.php';
     $dir = $this->settings['location'];
     ITSEC_Lib_Directory::create($dir);
     $fileext = '.sql';
     $handle = @fopen($dir . '/' . $file . '.sql', 'w+');
     @fwrite($handle, $return);
     @fclose($handle);
     //zip the file
     if (true === $this->settings['zip']) {
         if (!class_exists('PclZip')) {
             require ABSPATH . 'wp-admin/includes/class-pclzip.php';
         }
         $zip = new PclZip($dir . '/' . $file . '.zip');
         if (0 != $zip->create($dir . '/' . $file . '.sql', PCLZIP_OPT_REMOVE_PATH, $dir)) {
             //delete .sql and keep zip
             @unlink($dir . '/' . $file . '.sql');
             $fileext = '.zip';
         }
     }
     if (2 !== $this->settings['method'] || true === $one_time) {
         $attachment = array($dir . '/' . $file . $fileext);
         $body = __('Attached is the backup file for the database powering', 'better-wp-security') . ' ' . get_option('siteurl') . __(' taken', 'better-wp-security') . ' ' . date('l, F jS, Y \\a\\t g:i a', $itsec_globals['current_time']);
         //Setup the remainder of the email
         $recipients = ITSEC_Modules::get_setting('global', 'backup_email');
         $subject = __('Site Database Backup', 'better-wp-security') . ' ' . date('l, F jS, Y \\a\\t g:i a', $itsec_globals['current_time']);
         $subject = apply_filters('itsec_backup_email_subject', $subject);
         $headers = 'From: ' . get_bloginfo('name') . ' <' . get_option('admin_email') . '>' . "\r\n";
         $mail_success = false;
         //Use HTML Content type
         add_filter('wp_mail_content_type', array($this, 'set_html_content_type'));
         //Send emails to all recipients
         foreach ($recipients as $recipient) {
             if (is_email(trim($recipient))) {
                 if (defined('ITSEC_DEBUG') && true === ITSEC_DEBUG) {
                     $body .= '<p>' . __('Debug info (source page): ' . esc_url($_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"])) . '</p>';
                 }
                 $mail_success = wp_mail(trim($recipient), $subject, '<html>' . $body . '</html>', $headers, $attachment);
             }
         }
         //Remove HTML Content type
         remove_filter('wp_mail_content_type', array($this, 'set_html_content_type'));
     }
     if (1 === $this->settings['method']) {
         @unlink($dir . '/' . $file . $fileext);
     } else {
         $retain = isset($this->settings['retain']) ? absint($this->settings['retain']) : 0;
         //delete extra files
         if (0 < $retain) {
             $files = scandir($dir, 1);
             $count = 0;
             if (is_array($files) && 0 < count($files)) {
                 foreach ($files as $file) {
                     if (strstr($file, 'backup')) {
                         if ($count >= $retain) {
                             @unlink(trailingslashit($dir) . $file);
                         }
                         $count++;
                     }
                 }
             }
         }
     }
     if (false === $one_time) {
         ITSEC_Modules::set_setting('backup', 'last_run', ITSEC_Core::get_current_time_gmt());
     }
     switch ($this->settings['method']) {
         case 0:
             if (false === $mail_success) {
                 $status = array('status' => __('Error', 'better-wp-security'), 'details' => __('saved locally but email to backup recipients could not be sent.', 'better-wp-security'));
             } else {
                 $status = array('status' => __('Success', 'better-wp-security'), 'details' => __('emailed to backup recipients and saved locally', 'better-wp-security'));
             }
             break;
         case 1:
             if (false === $mail_success) {
                 $status = array('status' => __('Error', 'better-wp-security'), 'details' => __('email to backup recipients could not be sent.', 'better-wp-security'));
             } else {
                 $status = array('status' => __('Success', 'better-wp-security'), 'details' => __('emailed to backup recipients', 'better-wp-security'));
             }
             break;
         default:
             $status = array('status' => __('Success', 'better-wp-security'), 'details' => __('saved locally', 'better-wp-security'));
             break;
     }
     $itsec_logger->log_event('backup', 3, array($status));
 }