View source
<?php
require_once 'CAS/CAS.php';
define('CAS_NO_VERIFY', 'none');
define('CAS_VERIFY', 'verify');
define('CAS_CA_VERIFY', 'ca_verify');
function cas_invoke_auth_transform(&$cas_name) {
foreach (module_list() as $module) {
$function = $module . '_auth_transform';
if (function_exists($function)) {
$function('cas', $cas_name);
}
}
}
function cas_invoke_auth_filter($cas_name) {
foreach (module_list() as $module) {
$function = $module . '_auth_filter';
if (function_exists($function)) {
if (($return = $function('cas', $cas_name)) === FALSE) {
return FALSE;
}
}
}
return TRUE;
}
function cas_login_check() {
global $user, $account;
if ($user->uid) {
}
elseif (_cas_force_login()) {
$cas_user_register = variable_get('cas_user_register', 1);
$cas_authmap = variable_get('cas_authmap', 0);
$all_roles = user_roles();
$cas_roles = array();
foreach ($all_roles as $key => $value) {
if (array_key_exists($key, variable_get('cas_auto_assigned_role', array(
DRUPAL_AUTHENTICATED_RID,
)))) {
$cas_roles[$key] = $key;
}
}
$server_version = (string) variable_get('cas_version', '2.0');
$server_cas_server = (string) variable_get('cas_server', '');
$server_port = (int) variable_get('cas_port', '443');
$server_uri = (string) variable_get('cas_uri', '');
$cas_domain = (string) variable_get('cas_domain', '');
$cas_cert_verify = (string) variable_get('cas_cert_verify', CAS_NO_VERIFY);
$cas_cert = (string) variable_get('cas_cert', '');
$start_session = (bool) FALSE;
cas_save_page();
phpCAS::client($server_version, $server_cas_server, $server_port, $server_uri, $start_session);
if (is_callable(array(
phpCAS,
'setNoCasServerValidation',
))) {
switch ($cas_cert_verify) {
case CAS_NO_VERIFY:
phpCAS::setNoCasServerValidation();
break;
case CAS_VERIFY:
phpCAS::setCasServerCert($cas_cert);
break;
case CAS_CA_VERIFY:
phpCAS::setCasServerCACert($cas_cert);
break;
}
}
if (is_callable(array(
phpCAS,
'authenticateIfNeeded',
))) {
phpCAS::authenticateIfNeeded();
}
else {
phpCAS::forceAuthentication();
}
$cas_name = phpCAS::getUser();
cas_invoke_auth_transform($cas_name);
if (($allow = cas_invoke_auth_filter($cas_name)) === FALSE) {
drupal_set_message("The user account {$cas_name} is not available on this site.", "error");
return;
}
if (user_is_blocked($cas_name)) {
drupal_set_message("The username {$cas_name} has been blocked.", "error");
return;
}
else {
if (drupal_is_denied('user', $cas_name)) {
drupal_set_message("The name {$cas_name} is a reserved username.", "error");
return;
}
}
if ($cas_authmap) {
$user = user_load(array(
"name" => $cas_name,
));
}
else {
$user = user_external_load($cas_name);
if (!$user->uid && variable_get('cas_hijack_user', 0)) {
$user = user_load(array(
"name" => $cas_name,
));
if ($user->uid) {
user_set_authmaps($user, array(
'authname_cas' => $cas_name,
));
}
}
}
if (!$user->uid) {
if ($cas_user_register == 1) {
$user_default = array(
"name" => $cas_name,
"pass" => user_password(),
"init" => db_escape_string($cas_name),
"status" => 1,
"roles" => $cas_roles,
);
if (!$cas_authmap) {
$user_default['authname_cas'] = $cas_name;
}
if ($cas_domain) {
$user_default['mail'] = $cas_name . '@' . $cas_domain;
}
$admin = array(
'uid' => 1,
);
$user = user_load($admin);
$user = user_save("", $user_default);
watchdog("user", t('new user: %n (CAS)', array(
'%n' => $user->name,
)), WATCHDOG_NOTICE, l(t("edit user"), "admin/user/edit/{$user->uid}"));
if ($user->uid && $user->uid > 0 && $cas_authmap) {
module_invoke_all('user', 'login', null, $user);
unset($_SESSION['cas_goto']);
watchdog('user', t('Session opened for %name.', array(
'%name' => $user->name,
)));
drupal_goto("user/" . $user->uid . "/edit");
}
$_SESSION['cas_first_login'] = true;
}
}
if ($user->uid && $user->uid > 0) {
if (variable_get('cas_useldap_groups', '')) {
if ($ldap_config_name = _get_ldap_config_name($user->name)) {
_ldapauth_init($ldap_config_name);
include_once 'modules/ldap_integration/ldapgroups.module';
$user->ldap_authentified = true;
ldapgroups_user_login($user);
}
}
$roles = $user->roles;
foreach ($cas_roles as $role) {
$roles[$role] = $role;
}
$user_up = array(
"pass" => user_password(),
"roles" => $roles,
);
$user = user_save($user, $user_up);
module_invoke_all('user', 'login', null, $user);
drupal_set_message(t(variable_get('cas_login_message', 'Logged in via CAS as %cas_username.'), array(
'%cas_username' => $user->name,
)));
watchdog('user', t('Session opened for %name.', array(
'%name' => $user->name,
)));
cas_login_page();
}
else {
session_destroy();
$user = drupal_anonymous_user();
}
}
}
function cas_perm() {
return array(
'administer cas',
);
}
function cas_help($section) {
switch ($section) {
case 'admin/modules#description':
return t("Allows users to authenticate via a Central Authentication Service.");
}
}
function cas_menu($may_cache) {
global $user;
$items = array();
cas_login_check();
if ($may_cache) {
$items[] = array(
'path' => 'admin/user/cas',
'title' => t('CAS settings'),
'description' => 'Configure central authentication services',
'callback' => 'drupal_get_form',
'callback arguments' => 'cas_admin_settings',
'access' => user_access('administer cas'),
'type' => MENU_NORMAL_ITEM,
);
if (!$user->uid || arg(0) == 'admin' && arg(1) == 'build' && arg(2) == 'menu') {
$items[] = array(
'path' => 'cas',
'title' => t('CAS Login'),
'callback' => 'cas_login_page',
'access' => TRUE,
'type' => MENU_SUGGESTED_ITEM,
);
}
if ($user->uid || arg(0) == 'admin' && arg(1) == 'build' && arg(2) == 'menu') {
$items[] = array(
'path' => 'caslogout',
'title' => t('CAS Logout'),
'callback' => 'cas_logout',
'access' => TRUE,
'type' => MENU_SUGGESTED_ITEM,
);
}
}
return $items;
}
function cas_admin_settings() {
$form['server'] = array(
'#type' => 'fieldset',
'#title' => t('CAS server settings'),
'#collapsible' => true,
'#collapsed' => false,
);
$form['server']['cas_version'] = array(
'#type' => 'radios',
'#title' => t('CAS version'),
'#default_value' => variable_get('cas_version', '2.0'),
'#options' => array(
'1.0' => '1.0',
'2.0' => '2.0',
),
);
$form['server']['cas_server'] = array(
'#type' => 'textfield',
'#title' => t('CAS server'),
'#default_value' => variable_get('cas_server', ''),
'#size' => 30,
'#maxlength' => 55,
'#description' => t('Location of CAS authentication service.'),
);
$form['server']['cas_port'] = array(
'#type' => 'textfield',
'#title' => t('CAS port'),
'#default_value' => variable_get('cas_port', '443'),
'#size' => 30,
'#maxlength' => 8,
'#description' => '443 is the standard ssl port. 8443 is the standard non-root port for Tomcat.',
);
$form['server']['cas_uri'] = array(
'#type' => 'textfield',
'#title' => t('CAS URI'),
'#default_value' => variable_get('cas_uri', ''),
'#size' => 30,
'#description' => 'If CAS is not at the root of the host, include a URI (e.g., /cas).',
);
$form['server']['cas_verify'] = array(
'#type' => 'radios',
'#title' => t('CAS PEM certificate verification'),
'#default_value' => variable_get('cas_verify', CAS_NO_VERIFY),
'#options' => array(
CAS_NO_VERIFY => 'Do not verify the certificate',
CAS_VERIFY => 'Verify the server using PEM cerificate',
CAS_CA_VERIFY => 'Verify the Certificate Authority using PEM certificate',
),
);
$form['server']['cas_cert'] = array(
'#type' => 'textfield',
'#title' => t('CAS PEM Certificate (phpCAS 0.6 or greater)'),
'#default_value' => variable_get('cas_cert', ''),
'#size' => 30,
'#description' => 'With client version 0.6 or greater this is the certificate for validating cas or the cas CA as appropriate.',
);
$form['account'] = array(
'#type' => 'fieldset',
'#title' => t('User account settings'),
'#collapsible' => true,
'#collapsed' => true,
);
$form['account']['cas_authmap'] = array(
'#type' => 'checkbox',
'#title' => t('Is Drupal also the CAS user repository?'),
'#default_value' => variable_get('cas_authmap', 0),
'#description' => t('In most cases, the answer will be no; an LDAP repository will be the source of CAS users. But in some cases, the Drupal user database could be used as the central user store for single sign-on. If this is the case, select this option.'),
);
$form['account']['cas_hijack_user'] = array(
'#type' => 'checkbox',
'#title' => t('If CAS is not the user repository, should cas highjack users with the same name?'),
'#default_value' => variable_get('cas_hijack_user', 0),
'#description' => t('If you have pre-created regular accounts in cas that you want converted to mapped accounts, check this box. Otherwise CAS will likely throw duplicate key violation errors on new users.'),
);
$form['account']['cas_user_register'] = array(
'#type' => 'checkbox',
'#title' => t('Should Drupal user accounts be automatically created?'),
'#default_value' => variable_get('cas_user_register', 1),
'#description' => t('If a CAS user logs in, his Drupal account will automatically be created. If you don\'t check this option, you will have to pre-create accounts for the users you want to allow.'),
);
$form['account']['cas_domain'] = array(
'#type' => 'textfield',
'#title' => t('Email Domain'),
'#default_value' => variable_get('cas_domain', ''),
'#size' => 30,
'#maxlength' => 55,
'#description' => t('Append this domain name to each new user in order generate his email address.'),
);
$form['account']['cas_hide_email'] = array(
'#type' => 'checkbox',
'#title' => t('Users canot change email address'),
'#default_value' => variable_get('cas_hide_email', 0),
'#description' => t('Hide email address field on the edit user form.'),
);
$form['account']['cas_hide_password'] = array(
'#type' => 'checkbox',
'#title' => t('Users canot change password'),
'#default_value' => variable_get('cas_hide_password', 0),
'#description' => t('Hide password field on the edit user form.'),
);
$form['account']['cas_auto_assigned_role'] = array(
'#type' => 'select',
'#title' => t('Auto-assign users to the role(s)'),
'#default_value' => variable_get('cas_auto_assigned_role', array(
DRUPAL_AUTHENTICATED_RID,
)),
'#options' => user_roles(true),
'#multiple' => true,
'#description' => t('This value can be used to establish a role automatically for all CAS users. As an example, if you are also using the simple_ldap module, you can use this role to establish a tie between CAS and LDAP-populated data. i.e. Users with the role of \'cas:user\' should have their LDAP data updated automatically.'),
);
$form['pages'] = array(
'#type' => 'fieldset',
'#title' => t('Redirection settings'),
'#collapsible' => true,
'#collapsed' => true,
);
$form['pages']['cas_access'] = array(
'#type' => 'radios',
'#title' => t('Require CAS login for'),
'#default_value' => variable_get('cas_access', 0),
'#options' => array(
t('specific pages'),
t('all pages except specific pages'),
),
);
$form['pages']['cas_pages'] = array(
'#type' => 'textarea',
'#title' => t('Specific pages'),
'#default_value' => variable_get('cas_pages', ''),
'#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['pages']['cas_first_login'] = array(
'#type' => 'checkbox',
'#title' => t('Force redirection on initial login'),
'#default_value' => variable_get('cas_first_login', 0),
'#description' => t("Activate this option if you want a user to be directed to the following page after their first CAS login."),
);
$form['pages']['cas_first_login_destination'] = array(
'#type' => 'textfield',
'#title' => t('Initial login landing page'),
'#default_value' => variable_get('cas_first_login_destination', ''),
'#size' => 30,
'#maxlength' => 55,
'#description' => t("Drupal path or URL. An example path is '<em>blog</em>' for the blog page. '<front>' is the front page. An example URL is '<em>http://www.example.com</em>'."),
);
$form['pages']['cas_login_message'] = array(
'#type' => 'textfield',
'#title' => t('Successful login message'),
'#default_value' => variable_get('cas_login_message', 'Logged in via CAS as %cas_username.'),
'#description' => 'The message displayed to a user when he successfully logs in via CAS. You may specify \'%cas_username\', the username of the user.',
);
$form['pages']['cas_logout_redirect'] = array(
'#type' => 'checkbox',
'#title' => t('Redirect user on logout'),
'#default_value' => variable_get('cas_logout_redirect', 0),
'#description' => t("Activate this option if you want a user to be directed after logging out of CAS. If this option is enabled, but the logout destination is not specified below, we redirect back to this site."),
);
$form['pages']['cas_logout_destination'] = array(
'#type' => 'textfield',
'#title' => t('Logout destination'),
'#default_value' => variable_get('cas_logout_destination', ''),
'#size' => 30,
'#maxlength' => 55,
'#description' => t("URL. An example URL is '<em>http://www.example.com</em>'."),
);
$form['misc'] = array(
'#type' => 'fieldset',
'#title' => t('Miscellaneous settings'),
'#collapsible' => true,
'#collapsed' => true,
);
$form['misc']['cas_changePasswordURL'] = array(
'#type' => 'textfield',
'#title' => t('Change password URL'),
'#default_value' => variable_get('cas_changePasswordURL', ''),
'#description' => t('The URL users should use for changing their password. Leave blank to use the standard Drupal page.'),
);
$form['misc']['cas_registerURL'] = array(
'#type' => 'textfield',
'#title' => t('Registration URL'),
'#default_value' => variable_get('cas_registerURL', ''),
'#description' => t('The URL users should use for changing registering. Leave blank to use the standard Drupal page.'),
);
$form['ldap'] = array(
'#type' => 'fieldset',
'#title' => t('LDAP settings'),
'#collapsible' => true,
'#collapsed' => true,
);
$form['ldap']['cas_useldap'] = array(
'#type' => 'checkbox',
'#title' => t('Should we extract the user email from an LDAP directory?'),
'#default_value' => variable_get('cas_useldap', 0),
'#description' => t('Activate this option if you want to extract the user email from an LDAP directory. <strong>Ldapauth module must be enabled and configured</strong>.'),
);
$form['ldap']['cas_ldap_email_attribute'] = array(
'#type' => 'textfield',
'#title' => t('Email attribute'),
'#default_value' => variable_get('cas_ldap_email_attribute', 'mail'),
'#size' => 30,
'#maxlength' => 55,
'#description' => t('LDAP entry attribute containing the email address.'),
);
$form['ldap']['cas_useldap_groups'] = array(
'#type' => 'checkbox',
'#title' => t('Should we extract user groups from an LDAP directory?'),
'#default_value' => variable_get('cas_useldap_groups', 0),
'#description' => t('Activate this option if you want to extract the user groups from an LDAP directory. <strong>Ldapgroups module must be enabled and configured</strong>.'),
);
return system_settings_form($form);
}
function cas_save_page() {
if (!$_SESSION['cas_goto']) {
if (arg(0) == 'cas') {
$_SESSION['cas_goto'] = $_SERVER['HTTP_REFERER'];
}
else {
$_SESSION['cas_goto'] = $_GET['q'];
}
}
}
function cas_login_page() {
global $user;
$destination = variable_get('site_frontpage', 'node');
if ($_SESSION['cas_first_login'] && variable_get('cas_first_login', 0) == 1) {
$destination = variable_get('cas_first_login_destination', '');
unset($_SESSION['cas_first_login']);
}
elseif ($_GET['destination']) {
$destination = $_GET['destination'];
}
elseif ($_SESSION['cas_goto']) {
$destination = $_SESSION['cas_goto'];
unset($_SESSION['cas_goto']);
}
drupal_goto($destination);
$output .= t("Cas page... you should never get here");
drupal_set_message('hi');
return $output;
}
function cas_logout() {
global $user;
global $base_url;
watchdog('user', t('Session closed for %name.', array(
'%name' => theme('placeholder', $user->name),
)));
session_destroy();
module_invoke_all('user', 'logout', NULL, $user);
$user = user_load(array(
'uid' => 0,
));
$port = variable_get('cas_port', '443');
$server = variable_get('cas_server', 'cas');
$uri = variable_get('cas_uri', '');
$logout_destination = 'https://' . $server;
if ($port != '443') {
$logout_destination .= ':' . $port;
}
$logout_destination .= '/' . trim($uri, '/') . '/logout';
$destination = preg_replace("/(destination=|caslogout)/", "", drupal_get_destination());
if (empty($destination) && variable_get('cas_logout_redirect', 0)) {
$destination = variable_get('cas_logout_destination', '');
if (empty($destination)) {
$destination = $base_url;
}
}
if ($destination) {
$logout_destination .= '?destination=' . $destination . '&service=' . $destination . '&url=' . $destination;
}
drupal_goto($logout_destination);
}
function cas_block($op = 'list', $delta = 0, $edit = array()) {
global $user;
if ($op == 'list') {
$blocks[0]['info'] = t('CAS User login');
return $blocks;
}
else {
if ($op == 'view') {
$block = array();
switch ($delta) {
case 0:
if (!$user->uid && !(arg(0) == 'user' && !is_numeric(arg(1)))) {
$edit = $_POST['edit'];
$output = "<div class=\"user-login-block\">\n";
$output .= l(t('Login'), 'cas');
$output .= "</div>\n";
$block['subject'] = t('User Login');
$block['content'] = $output;
}
return $block;
}
}
}
}
function _cas_force_login() {
list($arg0) = split('/', $_GET['q']);
if ($arg0 == "cas") {
return true;
}
if (base_path() . 'cron.php' == $_SERVER['PHP_SELF'] || base_path() . 'xmlrpc.php' == $_SERVER['PHP_SELF']) {
return false;
}
if (variable_get('cas_access', 0) == 1) {
$force_login = TRUE;
}
else {
$force_login = FALSE;
}
$pages = variable_get('cas_pages', '');
if ($pages) {
$path = drupal_get_path_alias($_GET['q']);
$regexp = '/^(' . preg_replace(array(
'/(\\r\\n?|\\n)/',
'/\\\\\\*/',
'/(^|\\|)\\\\<front\\\\>($|\\|)/',
), array(
'|',
'.*',
'\\1' . variable_get('site_frontpage', 'node') . '\\2',
), preg_quote($pages, '/')) . ')$/';
$path_match = preg_match($regexp, $path);
if ($path_match) {
if ($force_login) {
$force_login = false;
}
else {
$force_login = true;
}
}
}
return $force_login;
}
function cas_form_alter($form_id, &$form) {
switch ($form_id) {
case 'user_edit':
if (variable_get('cas_hide_email', 0)) {
if (variable_get('cas_domain', '')) {
$form['account']['mail']['#type'] = 'hidden';
$form['account']['mail']['#value'] = $form['account']['name']['#default_value'] . '@' . variable_get('cas_domain', '');
}
if (variable_get('cas_useldap', '')) {
global $ldapauth_ldap, $user;
if ($ldap_config_name = _get_ldap_config_name($user->name)) {
_ldapauth_init($ldap_config_name);
_ldapauth_user_lookup($user->name);
$cas_ldap_email_attribute = (string) variable_get('cas_ldap_email_attribute', 'mail');
$ldap_entries = $ldapauth_ldap
->search($ldapauth_ldap
->getOption('basedn'), $ldapauth_ldap
->getOption('user_attr') . '=' . $user->name, array(
$cas_ldap_email_attribute,
));
if ($ldap_entries['count'] == 1 && isset($ldap_entries[0][$cas_ldap_email_attribute][0])) {
if (trim($ldap_entries[0][$cas_ldap_email_attribute][0]) != '') {
$form['account']['mail']['#type'] = 'hidden';
$form['account']['mail']['#value'] = $ldap_entries[0][$cas_ldap_email_attribute][0];
}
}
}
}
}
if (variable_get('cas_hide_password', 0)) {
unset($form['account']['pass']);
}
break;
case 'user_pass':
if (!user_access('administer users') && variable_get('cas_changePasswordURL', '') != '') {
drupal_goto(variable_get('cas_changePasswordURL', ''));
}
break;
case 'user_register':
if (!user_access('administer users') && variable_get('cas_registerURL', '') != '') {
drupal_goto(variable_get('cas_registerURL', ''));
}
break;
}
}
function _get_ldap_config_name($user_name) {
include_once 'modules/ldap_integration/ldapauth.module';
$user_found = false;
$result = db_query("SELECT name FROM {ldapauth} WHERE status = '%d' ORDER BY sid", 1);
while ($row = db_fetch_object($result)) {
_ldapauth_init($row->name);
$ldap_user_entry = _ldapauth_user_lookup($user_name);
if ($ldap_user_entry) {
$user_found = true;
break;
}
}
if ($user_found) {
return $row->name;
}
else {
return false;
}
}