You are here

function restrict_ip_boot in Restrict IP 7.2

Implements hook_boot().

Determines whether or not the user should be whitelisted, and if they should, sets a flag indicating so.

File

./restrict_ip.module, line 96
Holds hooks for the restrict_ip module.

Code

function restrict_ip_boot() {
  global $user;
  if (variable_get('restrict_ip_enable', 0)) {
    drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION);
    drupal_session_start();
    if (isset($_SESSION['restrict_ip'])) {
      unset($_SESSION['restrict_ip']);
    }

    // Allow Drush requests regardless of IP.
    if (!drupal_is_cli()) {
      $access_denied = TRUE;
      if (variable_get('restrict_ip_white_black_list', 0)) {
        $whitelisted_pages = trim(variable_get('restrict_ip_page_whitelist', ''));
        if (strlen($whitelisted_pages)) {
          $whitelisted_pages = explode(PHP_EOL, $whitelisted_pages);
          for ($i = 0; $i < count($whitelisted_pages); $i++) {
            $whitelisted_pages[$i] = strtolower(trim($whitelisted_pages[$i]));
          }
          $current_path = strtolower($_GET['q']);
          if (in_array($current_path, $whitelisted_pages)) {
            $access_denied = FALSE;
          }
        }
      }
      if ($access_denied && variable_get('restrict_ip_white_black_list', 0) == 2) {
        $blacklisted_pages = trim(variable_get('restrict_ip_page_blacklist', ''));
        if (strlen($blacklisted_pages)) {
          $blacklisted_pages = explode(PHP_EOL, $blacklisted_pages);
          for ($i = 0; $i < count($blacklisted_pages); $i++) {
            $blacklisted_pages[$i] = strtolower(trim($blacklisted_pages[$i]));
          }
          $current_path = strtolower($_GET['q']);
          if (!in_array($current_path, $blacklisted_pages)) {
            $access_denied = FALSE;
          }
        }
      }
      if ($access_denied) {

        // Get the value saved to the system, and turn it into an array of IP
        // addresses.
        $ip_addresses = restrict_ip_sanitize_ip_list(variable_get('restrict_ip_address_list', ''));

        // Add any whitelisted IPs from the settings.php file to the whitelisted
        // array.
        if (count(variable_get('restrict_ip_whitelist', array()))) {
          $ip_addresses = array_merge($ip_addresses, restrict_ip_sanitize_ip_list(implode(PHP_EOL, variable_get('restrict_ip_whitelist', array()))));
        }
        if (count($ip_addresses)) {
          $user_ip = ip_address();
          foreach ($ip_addresses as $ip_address) {
            $ip_address = trim($ip_address);
            if (strlen($ip_address)) {

              // Check if the given IP address matches the current user.
              if ($ip_address == $user_ip) {

                // The given IP is allowed - so don't deny access (aka allow it)
                $access_denied = FALSE;

                // No need to continue as user is allowed.
                break;
              }
              $pieces = explode('-', $ip_address);

              // We only need to continue checking this IP address if it is a
              // range of addresses.
              if (count($pieces) == 2) {
                $start_ip = $pieces[0];
                $end_ip = $pieces[1];
                $start_pieces = explode('.', $start_ip);

                // If there are not 4 sections to the IP then its an invalid
                // IPv4 address, and we don't need to continue checking.
                if (count($start_pieces) === 4) {
                  $user_pieces = explode('.', $user_ip);
                  $continue = TRUE;

                  // We compare the first three chunks of the first IP address
                  // With the first three chunks of the user's IP address
                  // If they are not the same, then the IP address is not within
                  // the range of IPs.
                  for ($i = 0; $i < 3; $i++) {
                    if ((int) $user_pieces[$i] !== (int) $start_pieces[$i]) {

                      // One of the chunks has failed, so we can stop
                      // checking this range.
                      $continue = FALSE;
                      break;
                    }
                  }

                  // The first three chunks have past testing, so now check the
                  // range given to see if the final chunk is in this range.
                  if ($continue) {

                    // First we get the start of the range.
                    $start_final_chunk = (int) array_pop($start_pieces);
                    $end_pieces = explode('.', $end_ip);

                    // Then we get the end of the range. This will work
                    // whether the user has entered
                    // XXX.XXX.XXX.XXX - XXX.XXX.XXX.XXX or XXX.XXX.XXX.XXX-XXX.
                    $end_final_chunk = (int) array_pop($end_pieces);

                    // Now we get the user's final chunk.
                    $user_final_chunk = (int) array_pop($user_pieces);

                    // Finally check to see if the user's chunk lies in that
                    // range.
                    if ($user_final_chunk >= $start_final_chunk && $user_final_chunk <= $end_final_chunk) {

                      // The user's IP lies in the range, so access is not
                      // denied (ie - granted).
                      $access_denied = FALSE;

                      // No need to cintinue checking addresses as access has
                      // been granted.
                      break;
                    }
                  }
                }
              }
            }
          }
        }

        // Determine if the countries module and the ip2country module are
        // enabled. module_exists() is not available in hook_boot(), so a
        // database query is required. Any schema version above -1 means the
        // module is enabled.
        $schema_version = db_query('SELECT name, schema_version FROM {system} WHERE name = :countries OR name = :ip2country', array(
          ':countries' => 'countries',
          ':ip2country' => 'ip2country',
        ));
        foreach ($schema_version as $version) {
          $name = $version->name;
          ${$name} = $version->schema_version > -1;
        }
        if ($access_denied) {
          if (variable_get('restrict_ip_country_white_black_list', 0) == 1) {
            $country_code = $user->data['country_iso_code_2'];
            if ($country_code) {
              $countries = variable_get('restrict_ip_country_list', array());
              $access_denied = !in_array(strtoupper($country_code), $countries);
            }
          }
          elseif (variable_get('restrict_ip_country_white_black_list', 0) == 2) {
            $country_code = $user->data['country_iso_code_2'];
            if ($country_code) {
              $countries = variable_get('restrict_ip_country_list', array());
              $access_denied = in_array(strtoupper($country_code), $countries);
            }
          }
        }

        // The user has been denied access, so we need to set this value as so.
        if ($access_denied) {
          $_SESSION['restrict_ip'] = TRUE;
          ip_restricted(TRUE);
        }
      }
    }
  }
}