You are here

filters.encryption.inc in Backup and Migrate 7.3

A filter for encrypting bckups with AES.

File

includes/filters.encryption.inc
View source
<?php

/**
 * @file
 * A filter for encrypting bckups with AES.
 */

/**
 * A filter for encrypting backup files.
 *
 * @ingroup backup_migrate_filters
 */
class backup_migrate_filter_encryption extends backup_migrate_filter {
  public $op_weights = array(
    'backup' => 170,
    'restore' => -170,
  );

  /**
   * Called on a backup file after the backup has been completed.
   */
  public function backup($file, $settings) {
    return $this
      ->file_encrypt($file, $settings);
  }

  /**
   * Called on a backup file before importing it.
   */
  public function restore($file, $settings) {
    return $this
      ->file_decrypt($file);
  }

  /**
   * Gets the form for the settings for this filter.
   */
  public function backup_settings_default() {
    return array(
      'encryption' => 'none',
    );
  }

  /**
   * Gets the form for the settings for this filter.
   */
  public function backup_settings_form($settings) {
    $form = array();
    $options = $this
      ->_backup_migrate_get_encryption_form_item_options();
    if (array_intersect_key($options, array_flip(array(
      'aes',
      'encrypt',
    )))) {
      $form['file']['encryption'] = array(
        "#type" => "select",
        "#title" => t("File Encryption"),
        "#options" => $options,
        "#default_value" => @$settings['encryption'],
        '#description' => t('Encrypted files can only be restored by Backup and Migrate and only on sites with the same encryption key.'),
      );
    }
    else {
      $form['file']['encryption'] = array(
        "#type" => 'item',
        "#title" => t("File Encryption"),
        "#markup" => t('Install the !link to enable backup file encryption.', array(
          '!link' => l(t('Encrypt module'), 'http://drupal.org/project/encrypt'),
        )),
      );
    }

    // If the Encrypt method is available add a configuration field.
    if (array_key_exists('encrypt', $options)) {
      $form['file']['encrypt_config'] = array(
        '#type' => 'select',
        '#title' => t('Encryption Configuration'),
        '#options' => encrypt_get_configs_as_options(),
        '#default_value' => @$settings['encrypt_config'],
        '#description' => t('Select a configuration to use for encryption.'),
        '#states' => array(
          'visible' => array(
            ':input[name="filters[encryption]"]' => array(
              'value' => 'encrypt',
            ),
          ),
        ),
      );
    }
    return $form;
  }

  /**
   * Returns a list of backup filetypes.
   */
  public function file_types() {
    return array(
      "aes" => array(
        "extension" => "aes",
        "filemime" => "application/octet-stream",
        "backup" => TRUE,
        "restore" => TRUE,
      ),
      "encrypt" => array(
        "extension" => "encrypt",
        "filemime" => "application/octet-stream",
        "backup" => TRUE,
        "restore" => TRUE,
      ),
    );
  }

  /**
   * Gets the compression options as an options array for a form item.
   */
  public function _backup_migrate_get_encryption_form_item_options() {
    $options = array();
    $options = array(
      '' => t('No Encryption'),
    );
    if (@function_exists("aes_encrypt")) {
      $options['aes'] = t("AES Encryption");
    }
    if (@function_exists("encrypt")) {
      $options['encrypt'] = t("Encryption With Encrypt Module");
    }
    return $options;
  }

  /**
   * AES encrypts a file.
   */
  public function aes_encrypt($source, $dest) {
    $success = FALSE;
    if (function_exists('aes_encrypt')) {
      if ($data = $source
        ->get_contents()) {

        // Add a marker to the end of the data so we can trim the padding on
        // decrpypt.
        $data = pack("a*H2", $data, "80");
        if ($data = aes_encrypt($data, FALSE)) {
          $dest
            ->put_contents($data);
          $success = TRUE;
        }
      }
    }
    return $success;
  }

  /**
   * AES decodes a file.
   */
  public function aes_decrypt($source, $dest) {
    $success = FALSE;
    if (function_exists('aes_decrypt')) {
      if ($data = $source
        ->get_contents()) {
        if ($data = aes_decrypt($data, FALSE)) {

          // Trim all the padding zeros plus our non-zero marker.
          $data = substr(rtrim($data, "\0"), 0, -1);
          $dest
            ->put_contents($data);
          $success = TRUE;
        }
      }
    }
    return $success;
  }

  /**
   * Encrypts a file with the Encrypt module.
   */
  public function encrypt($source, $dest, $settings) {
    $success = FALSE;
    if (function_exists('encrypt')) {
      if (!empty($settings->filters['encrypt_config'])) {
        $config_name = $settings->filters['encrypt_config'];
      }
      else {
        $config = encrypt_get_default_config();
        $config_name = $config['name'];
      }
      if ($data = $source
        ->get_contents()) {

        // Add a marker to the end of the data so we can trim the padding on decrypt.
        $data = pack("a*H2", $data, "80");
        if ($data = encrypt($data, array(
          'base64' => FALSE,
        ), NULL, NULL, $config_name)) {
          $dest
            ->put_contents($data);
          $success = TRUE;
        }
      }
    }
    return $success;
  }

  /**
   * Decrypts a file with the Encrypt module.
   */
  public function decrypt($source, $dest) {
    $success = FALSE;
    if (function_exists('decrypt')) {
      if ($data = $source
        ->get_contents()) {
        if ($data = decrypt($data)) {

          // Trim all the padding zeros plus our non-zero marker.
          $data = substr(rtrim($data, "\0"), 0, -1);
          $dest
            ->put_contents($data);
          $success = TRUE;
        }
      }
    }
    return $success;
  }

  /**
   * Encrypts a file with the given settings.
   *
   * Also updates settings to reflect new file mime and file extension.
   */
  public function file_encrypt($file, $settings) {
    if (!empty($settings->filters['encryption'])) {
      switch ($settings->filters['encryption']) {
        case "aes":
          $from = $file
            ->push_type('aes');
          $from = new backup_file(array(
            'filepath' => $from,
          ));
          if (!($success = $this
            ->aes_encrypt($from, $file))) {
            $file = NULL;
          }
          break;
        case "encrypt":
          $from = $file
            ->push_type('encrypt');
          $from = new backup_file(array(
            'filepath' => $from,
          ));
          if (!($success = $this
            ->encrypt($from, $file, $settings))) {
            $file = NULL;
          }
          break;
      }
      if (!$file) {
        _backup_migrate_message("Could not encrypt backup file. Try backing up without encryption.", array(), 'error');
      }
    }
    return $file;
  }

  /**
   * Decrypts a file with the given settings.
   *
   * Also updates settings to reflect new file mime and file extension.
   */
  public function file_decrypt($file) {
    $success = FALSE;
    if ($file) {
      switch ($file
        ->type_id()) {
        case "aes":
          $from = $file
            ->pop_type();
          $success = $this
            ->aes_decrypt($from, $file);
          break;
        case "encrypt":
          $from = $file
            ->pop_type();
          $success = $this
            ->decrypt($from, $file);
          break;
        default:
          return $file;
      }
      if (!$success) {
        switch ($file
          ->type_id()) {
          case 'aes':
            if (function_exists('aes_decrypt')) {
              _backup_migrate_message("Could not decrpyt backup file. Please check that the file is valid and that the encryption key of the server matches the server that created the backup.", array(), 'error');
            }
            else {
              _backup_migrate_message('You must install the !link to restore encrypted backkups.', array(
                '!link' => l(t('AES Encryption Module'), 'http://drupal.org/project/aes'),
              ), 'error');
            }
            break;
          case 'encrypt':
            if (function_exists('decrypt')) {
              _backup_migrate_message("Could not decrypt backup file. Please check that the file is valid and that the encryption key of the server matches the server that created the backup.", array(), 'error');
            }
            else {
              _backup_migrate_message('You must install the !link to restore encrypted backups.', array(
                '!link' => l(t('Encrypt module'), 'http://drupal.org/project/encrypt'),
              ), 'error');
            }
            break;
        }
      }
    }
    return $success ? $file : NULL;
  }

}

Classes

Namesort descending Description
backup_migrate_filter_encryption A filter for encrypting backup files.