View source
<?php
function securepages_init() {
global $base_url;
$path = isset($_GET['q']) ? $_GET['q'] : '';
if ($path == 'admin/settings/securepages/test') {
if (securepages_is_secure()) {
header('HTTP/1.1 200 OK');
}
else {
header('HTTP/1.1 404 Not Found');
}
exit;
}
if (!variable_get('securepages_enable', 0) || basename($_SERVER['PHP_SELF']) != 'index.php') {
return;
}
$page_match = securepages_match($path);
if ($_POST) {
}
elseif ($page_match && !securepages_is_secure()) {
securepages_goto(TRUE);
}
elseif ($page_match === 0 && securepages_is_secure() && variable_get('securepages_switch', FALSE)) {
securepages_goto(FALSE);
}
if (securepages_is_secure()) {
$base_url = securepages_baseurl();
}
}
function securepages_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'admin/settings/securepages',
'title' => t('Secure Pages'),
'description' => t('Configure which pages are and are not to be viewed in SSL'),
'callback' => 'drupal_get_form',
'callback arguments' => 'securepages_settings',
'access' => user_access('administer site configuration'),
'type' => MENU_NORMAL_ITEM,
);
}
return $items;
}
function securepages_settings() {
$form = array();
$form['securepages_enable'] = array(
'#type' => 'radios',
'#title' => t('Enable Secure Pages'),
'#default_value' => variable_get('securepages_enable', 0),
'#options' => array(
t('Disabled'),
t('Enabled'),
),
'#disabled' => !securepages_test(),
'#description' => t('To start using secure pages this setting must be enabled. This setting will only be able to changed when the web server has been configured for SSL.<br />If this test has failed then go <a href="!url">here</a>', array(
'!url' => preg_replace(';^http://;i', 'https://', url($_GET['q'], NULL, NULL, TRUE)),
)),
);
$form['securepages_switch'] = array(
'#type' => 'checkbox',
'#title' => t('Switch back to http pages when there are no matches'),
'#return_value' => TRUE,
'#default_value' => variable_get('securepages_switch', FALSE),
);
$form['securepages_basepath'] = array(
'#type' => 'textfield',
'#title' => t('Non-secure Base URL'),
'#default_value' => variable_get('securepages_basepath', ''),
);
$form['securepages_basepath_ssl'] = array(
'#type' => 'textfield',
'#title' => t('Secure Base URL'),
'#default_value' => variable_get('securepages_basepath_ssl', ''),
);
$form['securepages_secure'] = array(
'#type' => 'radios',
'#title' => t('Pages which will be be secure'),
'#default_value' => variable_get('securepages_secure', 1),
'#options' => array(
t('Make secure every page except the listed pages.'),
t('Make secure only the listed pages.'),
),
);
$form['securepages_pages'] = array(
'#type' => 'textarea',
'#title' => t('Pages'),
'#default_value' => variable_get('securepages_pages', "node/add*\nnode/*/edit\nuser/*\nadmin*"),
'#cols' => 40,
'#rows' => 5,
'#description' => t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are '<em>blog</em>' for the blog page and '<em>blog/*</em>' for every personal blog. '<em><front></em>' is the front page."),
);
$form['securepages_ignore'] = array(
'#type' => 'textarea',
'#title' => t('Ignore pages'),
'#default_value' => variable_get('securepages_ignore', "*/autocomplete/*"),
'#cols' => 40,
'#rows' => 5,
'#description' => t("The pages listed here will be ignored and be either returned in http or https. Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are '<em>blog</em>' for the blog page and '<em>blog/*</em>' for every personal blog. '<em><front></em>' is the front page."),
);
return system_settings_form($form);
}
function securepages_form_alter($form_id, &$form) {
if (!variable_get('securepages_enable', 0)) {
return;
}
if (isset($form['#action']) && securepages_can_alter_url($form['#action'])) {
extract(parse_url($form['#action']));
parse_str($query, $query);
if (isset($query['q'])) {
$path = $query['q'];
}
else {
$base_path = base_path();
$path = !strncmp($path, $base_path, strlen($base_path)) ? substr($path, strlen($base_path)) : $path;
}
$path = drupal_get_normal_path($path);
$query = drupal_query_string_encode($query);
$page_match = securepages_match($path);
if ($page_match && !securepages_is_secure()) {
$form['#action'] = securepages_url($path, $query, NULL, TRUE);
}
elseif ($page_match === 0 && securepages_is_secure() && variable_get('securepages_switch', FALSE)) {
$form['#action'] = securepages_url($path, $query, NULL, FALSE);
}
}
}
function securepages_link_alter(&$node, &$links) {
if (!variable_get('securepages_enable', 0)) {
return;
}
foreach ($links as $module => $link) {
if ($link['href'] && securepages_can_alter_url($link['href'])) {
$page_match = securepages_match($link['href']);
if ($page_match && !securepages_is_secure()) {
$links[$module]['href'] = securepages_url($link['href'], NULL, NULL, TRUE);
}
elseif ($page_match === 0 && securepages_is_secure() && variable_get('securepages_switch', FALSE)) {
$links[$module]['href'] = securepages_url($link['href'], NULL, NULL, FALSE);
}
}
}
}
function securepages_goto($secure) {
$path = !empty($_REQUEST['q']) ? $_REQUEST['q'] : '';
$query = count($_GET) > 1 ? securepages_get_query($_GET) : NULL;
$url = securepages_url($path, $query, NULL, $secure);
if (function_exists('module_invoke_all')) {
foreach (module_implements('exit') as $module) {
if ($module != 'devel') {
module_invoke($module, 'exit');
}
}
}
else {
bootstrap_invoke_all('exit');
}
header('Location: ' . $url);
exit;
}
function securepages_match($path) {
if (function_exists('menu_get_item')) {
$item = menu_get_item(menu_get_active_item());
if (isset($item['secure'])) {
return $item['secure'];
}
}
$secure = variable_get('securepages_secure', 1);
$pages = variable_get('securepages_pages', "node/add*\nnode/*/edit\nuser/*\nadmin*");
$ignore = variable_get('securepages_ignore', "*/autocomplete/*\n*/ajax/*");
if ($ignore) {
$regexp = '/^(' . preg_replace(array(
'/(\\r\\n?|\\n)/',
'/\\\\\\*/',
'/(^|\\|)\\\\<front\\\\>($|\\|)/',
), array(
'|',
'.*',
'\\1' . preg_quote(variable_get('site_frontpage', 'node'), '/') . '\\2',
), preg_quote($ignore, '/')) . ')$/';
if (preg_match($regexp, $path)) {
return securepages_is_secure() ? 1 : 0;
}
}
if ($pages) {
$regexp = '/^(' . preg_replace(array(
'/(\\r\\n?|\\n)/',
'/\\\\\\*/',
'/(^|\\|)\\\\<front\\\\>($|\\|)/',
), array(
'|',
'.*',
'\\1' . preg_quote(variable_get('site_frontpage', 'node'), '/') . '\\2',
), preg_quote($pages, '/')) . ')$/';
return !($secure xor preg_match($regexp, $path)) ? 1 : 0;
}
else {
return;
}
}
function securepages_test() {
if (securepages_is_secure()) {
return TRUE;
}
$url = 'https://' . preg_replace(';^http[s]?://;s', '', url('admin/settings/securepages/test', NULL, NULL, TRUE));
$response = drupal_http_request($url);
return $response->code == 200 ? TRUE : FALSE;
}
function securepages_is_secure() {
return isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? TRUE : FALSE;
}
function securepages_url($path = NULL, $query = NULL, $fragment = NULL, $secure = FALSE) {
if (isset($fragment)) {
$fragment = '#' . $fragment;
}
$colonpos = strpos($path, ':');
if ($colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && filter_xss_bad_protocol($path, FALSE) == check_plain($path)) {
if (strpos($path, '#') !== FALSE) {
list($path, $old_fragment) = explode('#', $path, 2);
if (isset($old_fragment) && !isset($fragment)) {
$fragment = '#' . $old_fragment;
}
}
if (isset($query)) {
$path .= (strpos($path, '?') !== FALSE ? '&' : '?') . $query;
}
return $path . $fragment;
}
global $base_url;
static $script;
static $clean_url;
if (!isset($script)) {
$script = strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') === FALSE ? 'index.php' : '';
}
if (!isset($clean_url)) {
$clean_url = (bool) variable_get('clean_url', '0');
}
$base = securepages_baseurl($secure) . '/';
if (!empty($path) && $path != '<front>' && function_exists('drupal_get_path_alias')) {
$path = drupal_get_path_alias($path);
$path = drupal_urlencode($path);
if (!$clean_url) {
if (!empty($query)) {
return $base . $script . '?q=' . $path . '&' . $query . $fragment;
}
else {
return $base . $script . '?q=' . $path . $fragment;
}
}
else {
if (!empty($query)) {
return $base . $path . '?' . $query . $fragment;
}
else {
return $base . $path . $fragment;
}
}
}
else {
if (!empty($query)) {
return $base . $script . '?' . $query . $fragment;
}
else {
return $base . $fragment;
}
}
}
function securepages_baseurl($secure = TRUE) {
global $base_url;
if ($secure) {
$url = variable_get('securepages_basepath_ssl', NULL);
}
else {
$url = variable_get('securepages_basepath', NULL);
}
if (!empty($url)) {
return $url;
}
return preg_replace('/http[s]?:\\/\\//i', $secure ? 'https://' : 'http://', $base_url, 1);
}
function securepages_get_query($query) {
unset($query['q']);
$q = array();
foreach ($query as $key => $value) {
$q[] = drupal_urlencode($key) . '=' . drupal_urlencode($value);
}
return implode('&', $q);
}
function securepages_urlencode($text) {
if (variable_get('clean_url', '0')) {
return str_replace(array(
'%2F',
'%26',
'%23',
'//',
), array(
'/',
'%2526',
'%2523',
'/%252F',
), urlencode($text));
}
else {
return str_replace('%2F', '/', urlencode($text));
}
}
function securepages_can_alter_url($url) {
global $base_path;
extract(parse_url($url));
if (!isset($scheme) && $base_path == '/') {
return TRUE;
}
if (strtolower($host) != strtolower($_SERVER['HTTP_HOST'])) {
return FALSE;
}
if (strlen($base_path) > 1 && substr($base_url, -1) != substr($path, 1, strlen($base_path))) {
return FALSE;
}
return TRUE;
}