'admin/settings/securesite', 'title' => t('Secure site'), 'callback' => 'drupal_get_form', 'callback arguments' => 'securesite_admin_settings', 'description' => t('Enables HTTP-AUTH security or an HTML form to restrict site access.'), 'access' => user_access('administer site configuration'), ); } return $items; } /** * Implementation of hook_settings(). */ function securesite_admin_settings() { global $base_url; // Authentication settings $form['authentication'] = array( '#type' => 'fieldset', '#title' => t('Authentication'), ); $form['authentication']['securesite_enabled'] = array( '#type' => 'radios', '#title' => t('Secure site'), '#default_value' => variable_get('securesite_enabled', 0), '#options' => array( t('Disabled'), t('Enabled with web browser HTTP-AUTH security'), t('Enabled with web browser HTTP-AUTH security, with browser logout workaround'), t('Enabled with HTML login form'), ), '#description' => t('HTTP-AUTH requires extra configuration if your PHP is not configured as an Apache module. At least one role must also have permission under access control page. The browser workaround is for when a user logs out, as all browsers manage the HTTP Auth variables differently the workaround will append to the end of the realm a random number to force the browser to clear the username and password. The workaround is only for some browsers. Without the workaround user will not be properly logged out in some browsers.', array('!extra' => url('http://drupal.org/node/28408'), '!access' => url('admin/user/access'))), ); $form['authentication']['securesite_guest_name'] = array( '#type' => 'textfield', '#title' => t('Guest user'), '#default_value' => variable_get('securesite_guest_name', ''), '#length' => 30, '#maxlength' => 40, '#description' => t('Guests can access the secured site without an account. Leave empty for no guest access'), ); $form['authentication']['securesite_guest_pass'] = array( '#type' => 'textfield', '#title' => t('Guest password'), '#default_value' => variable_get('securesite_guest_pass', ''), '#length' => 30, '#maxlength' => 40, '#description' => t('Leave empty for no guest access'), ); $form['authentication']['securesite_realm'] = array( '#type' => 'textfield', '#title' => t('Authentication realm'), '#default_value' => variable_get('securesite_realm', preg_replace('`^https?://`i', '', $base_url)), '#length' => 30, '#maxlength' => 40, '#description' => t('Name to identify log-in area.'), ); // HTML log-in form settings $form['login_form'] = array( '#type' => 'fieldset', '#title' => t('HTML log-in form'), ); $form['login_form']['securesite_login_form'] = array( '#type' => 'textarea', '#title' => t('Message for HTML log-in form'), '#default_value' => variable_get('securesite_login_form', t('
Enter your %site username and password.
', array('%site' => variable_get('site_name', 'drupal')))), '#length' => 60, '#height' => 3, ); $form['login_form']['securesite_request_form'] = array( '#type' => 'textarea', '#title' => t('Message for request password reset form'), '#default_value' => variable_get('securesite_request_form', t('Enter your username or your e-mail address.
')), '#length' => 60, '#height' => 3, '#description' => t('Leave empty to not process password resets through this module.'), ); // Bypass login filter pages settings $form['filter_pages'] = array( '#type' => 'fieldset', '#title' => t('Bypass log-in filter'), ); $form['filter_pages']['securesite_filter_pages_type'] = array( '#type' => 'radios', '#title' => t('Filter type'), '#default_value' => variable_get('securesite_filter_pages_type', 0), '#options' => array( t('Only the listed pages.'), t('Every page except the listed pages.'), ), ); $form['filter_pages']['securesite_filter_pages'] = array( '#type' => 'textarea', '#title' => t('Pages'), '#default_value' => variable_get('securesite_filter_pages', ''), '#length' => 60, '#height' => 3, '#description' => t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are 'blog' for the blog page and 'blog/*' for every personal blog."), ); return system_settings_form($form); } /** * Implementation of hook_init(). * * Implements the securesite authentication. */ function securesite_init() { global $user, $base_path; $guest_name = variable_get('securesite_guest_name', ''); $guest_pass = variable_get('securesite_guest_pass', ''); $securesite_enabled = variable_get('securesite_enabled', 0); // Ignore securesite for cron requests. if (!$securesite_enabled || request_uri() == $base_path .'cron.php') { return; } // Create edit variables. if ($securesite_enabled == 3 && !empty($_POST)) { $edit = $_POST['edit']; } elseif ($securesite_enabled == 1 || $securesite_enabled == 2) { $edit = array( 'name' => (isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : ''), 'pass' => (isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '') ); } // Check if this page should bypass the authentication, but only if the user is not logged in. if (!$user->uid) { $check_name = securesite_filter_check(); if ($check_name) { if (!is_bool($check_name)) { $user = user_load(array('name' => $check_name, 'status' => 1)); } return; } } // Check if user is logged in. if (($user->uid == 1) || ($user->uid && user_access('access site'))) { return; } // Check if guest user, already logged in if ((isset($_SESSION['securesite_guest']) ? $_SESSION['securesite_guest'] : '')) { return; } // Check if authentication is needed first if (empty($edit) && ($user->uid == 0)) { securesite_user_auth(); } // Check if user is a guest, still to login if ((!empty($guest_name) && $guest_name == $edit['name'] && $guest_pass == $edit['pass'])) { // Mark this session to prevent re-login (note: guest can't log out). $_SESSION['securesite_guest'] = TRUE; if (arg(0) != 'logout') { // only redirect if on logout page return; } securesite_goto(); } unset($_SESSION['securesite_guest']); // If not a guest make sure to unset guest session. /** * Attempt to log in using the LDAP auth module. * The LDAP auth module does not use Drupal's authentication system, * but instead adds a submit handler to the user login form. * * This is done to not require the username@example.com format */ if (function_exists('_ldapauth_user_authenticate')) { $account = _ldapauth_user_authenticate($edit['name'], $edit['pass']); } else { $account = user_authenticate($edit['name'], $edit['pass']); } if ($account->uid && user_access('access site', $account)) { // Log-in is successful. $user = $account; watchdog('user', t('Session opened for %name.', array('%name' => $user->name))); db_query("UPDATE {users} SET login = '%d' WHERE uid = '%s'", time(), $user->uid); user_module_invoke('login', $edit, $user); if (arg(0) != 'logout') { // only redirect if on logout page return; } securesite_goto(); } else { // Log-in failed. securesite_user_auth(); } } /** * Implementation of hook_user(). */ function securesite_user($op, &$edit, &$user) { if ($op == 'logout') { module_invoke_all('exit', request_uri()); unset($GLOBALS['user']); $securesite_enabled = variable_get('securesite_enabled', 0); if ($securesite_enabled == 1 || $securesite_enabled == 2) { securesite_user_auth(); } else { // redirect first to browser prevent caching problems securesite_goto(); } } } /** * Securesite redirect. */ function securesite_goto() { global $base_url; $url = (arg(0) == 'logout' ? $base_url : request_uri()); if (ini_get('session.use_trans_sid') && session_id() && !strstr($url, session_id())) { $url .= (strstr($url, '?') && !strstr($url, $sid) ? '&' : '?') . session_name() .'='. session_id(); } header('Location: '. $url); exit; } /** * Display authentication dialog and send password requests. */ function securesite_user_auth() { global $base_url; include_once('securesite.inc'); $edit = isset($_POST['edit']) ? $_POST['edit'] : ''; $securesite_enabled = variable_get('securesite_enabled', 0); $account = ''; $content = ''; // Log failed requests. if ((isset($_POST['securesite_login_form']) ? $_POST['securesite_login_form'] : '') && $edit['name'] && $edit['pass']) { watchdog('user', t('Log-in attempt failed for %name.', array('%name' => $edit['name']))); drupal_set_message(t('Sorry. Unrecognized username or password.'), 'error'); } // Set user messages. if ((isset($_POST['securesite_request_form']) ? $_POST['securesite_request_form'] : '') && $edit['name'] && $edit['mail']) { if (!$account = user_load(array('name' => $edit['name'], 'status' => 1))) { drupal_set_message(t('Sorry. Unrecognized username or e-mail address.'), 'error'); } elseif (!$account = user_load(array('mail' => $edit['mail'], 'status' => 1))) { drupal_set_message(t('Sorry. Unrecognized username or e-mail address.'), 'error'); } } // E-mail a user a new password. if ($account->uid) { $from = variable_get('site_mail', ini_get('sendmail_from')); // Generate a new password for this user. $pass = user_password(); user_save($account, array('pass' => $pass)); // Mail new password: $variables = array( '!username' => $account->name, '!site' => variable_get('site_name', 'drupal'), '!login_url' => user_pass_reset_url($account), '!uri' => $base_url, '!uri_brief' => preg_replace('`^https?://`i', '', $base_url), '!mailto' => $account->mail, '!date' => format_date(time()), '!login_uri' => url('user', NULL, NULL, TRUE), '!edit_uri' => url('user/'. $account->uid .'/edit', NULL, NULL, TRUE)); $subject = _user_mail_text('pass_subject', $variables); $body = _user_mail_text('pass_body', $variables); $mail_success = drupal_mail("securesite-password", $account->mail, $subject, $body); if ($mail_success) { watchdog('user', t('Password mailed to %name at %email.', array('%name' => $account->name, '%email' => $account->mail))); drupal_set_message(t('Your password and further instructions have been sent to your e-mail address.')); } else { watchdog('user', t('Error mailing password to %name at %email.', array('%name' => $account->name, '%email' => $account->mail)), WATCHDOG_ERROR); drupal_set_message(t('Unable to send mail. Please contact the site admin.', 'error')); } //nowhere to go!! //securesite_goto(); } // Get content for dialog. if ($securesite_enabled == 3) { $content .= _securesite_login_form(); } $content .= _securesite_request_form(); // HTTP AUTH if (($securesite_enabled == 1 || $securesite_enabled == 2) && !$account->uid) { $realm = variable_get('securesite_realm', variable_get('site_name', 'drupal')); if ($securesite_enabled == 2) { // Fix logout on cancel in Opera and IE $browser_user_agent = strtolower($_SERVER['HTTP_USER_AGENT']); if (strpos($browser_user_agent, "gecko") === FALSE) { // Firefox $suffix = ' - '. mt_rand(10, 99); } else { // Opera, IE, others? $suffix = ''; } $realm .= $suffix; } header('WWW-Authenticate: Basic realm="'. $realm .'"'); header('HTTP/1.0 401 Unauthorized'); } // Display dialog _securesite_dialog_page($content); drupal_set_title(t('Log in')); module_invoke_all('exit', request_uri()); exit; } /** * Check if pages should bypass securesite. */ function securesite_filter_check() { // If cache is enabled we need to load the path system if (variable_get('cache', CACHE_DISABLED) != CACHE_DISABLED) { drupal_bootstrap(DRUPAL_BOOTSTRAP_PATH); } // Fetch paths to ignore $pages = variable_get('securesite_filter_pages', ''); // Check if the current path matches the list defined by the admin. $path = drupal_get_path_alias($_GET['q']); $regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\