Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/auth/shibboleth/auth.php
Go to the documentation of this file.
00001 <?php
00026 if (!defined('MOODLE_INTERNAL')) {
00027     die('Direct access to this script is forbidden.');    
00028 }
00029 
00030 require_once($CFG->libdir.'/authlib.php');
00031 
00035 class auth_plugin_shibboleth extends auth_plugin_base {
00036 
00040     function auth_plugin_shibboleth() {
00041         $this->authtype = 'shibboleth';
00042         $this->config = get_config('auth/shibboleth');
00043     }
00044 
00053     function user_login($username, $password) {
00054        global $SESSION;
00055 
00056         // If we are in the shibboleth directory then we trust the server var
00057         if (!empty($_SERVER[$this->config->user_attribute])) {
00058             // Associate Shibboleth session with user for SLO preparation
00059             $sessionkey = '';
00060             if (isset($_SERVER['Shib-Session-ID'])){
00061                 // This is only available for Shibboleth 2.x SPs
00062                 $sessionkey = $_SERVER['Shib-Session-ID'];
00063             } else {
00064                 // Try to find out using the user's cookie
00065                 foreach ($_COOKIE as $name => $value){
00066                     if (preg_match('/_shibsession_/i', $name)){
00067                         $sessionkey = $value;
00068                     }
00069                 }
00070             }
00071 
00072             // Set shibboleth session ID for logout
00073             $SESSION->shibboleth_session_id  = $sessionkey;
00074 
00075             return (strtolower($_SERVER[$this->config->user_attribute]) == strtolower($username));
00076         } else {
00077             // If we are not, the user has used the manual login and the login name is
00078             // unknown, so we return false.
00079             return false;
00080         }
00081     }
00082 
00083 
00084 
00091     function get_userinfo($username) {
00092     // reads user information from shibboleth attributes and return it in array()
00093         global $CFG;
00094 
00095         // Check whether we have got all the essential attributes
00096         if ( empty($_SERVER[$this->config->user_attribute]) ) {
00097             print_error( 'shib_not_all_attributes_error', 'auth_shibboleth' , '', "'".$this->config->user_attribute."' ('".$_SERVER[$this->config->user_attribute]."'), '".$this->config->field_map_firstname."' ('".$_SERVER[$this->config->field_map_firstname]."'), '".$this->config->field_map_lastname."' ('".$_SERVER[$this->config->field_map_lastname]."') and '".$this->config->field_map_email."' ('".$_SERVER[$this->config->field_map_email]."')");
00098         }
00099 
00100         $attrmap = $this->get_attributes();
00101 
00102         $result = array();
00103         $search_attribs = array();
00104 
00105         foreach ($attrmap as $key=>$value) {
00106             // Check if attribute is present
00107             if (!isset($_SERVER[$value])){
00108                 $result[$key] = '';
00109                 continue;
00110             }
00111 
00112             // Make usename lowercase
00113             if ($key == 'username'){
00114                 $result[$key] = strtolower($this->get_first_string($_SERVER[$value]));
00115             } else {
00116                 $result[$key] = $this->get_first_string($_SERVER[$value]);
00117             }
00118         }
00119 
00120          // Provide an API to modify the information to fit the Moodle internal
00121         // data representation
00122         if (
00123               $this->config->convert_data
00124               && $this->config->convert_data != ''
00125               && is_readable($this->config->convert_data)
00126             ) {
00127 
00128             // Include a custom file outside the Moodle dir to
00129             // modify the variable $moodleattributes
00130             include($this->config->convert_data);
00131         }
00132 
00133         return $result;
00134     }
00135 
00141     function get_attributes() {
00142         $configarray = (array) $this->config;
00143 
00144         $moodleattributes = array();
00145         foreach ($this->userfields as $field) {
00146             if (isset($configarray["field_map_$field"])) {
00147                 $moodleattributes[$field] = $configarray["field_map_$field"];
00148             }
00149         }
00150         $moodleattributes['username'] = $configarray["user_attribute"];
00151 
00152         return $moodleattributes;
00153     }
00154 
00155     function prevent_local_passwords() {
00156         return true;
00157     }
00158 
00164     function is_internal() {
00165         return false;
00166     }
00167 
00174     function can_change_password() {
00175         return false;
00176     }
00177 
00182     function loginpage_hook() {
00183         global $SESSION, $CFG;
00184 
00185         // Prevent username from being shown on login page after logout
00186         $CFG->nolastloggedin = true;
00187 
00188         return;
00189     }
00190 
00195     function logoutpage_hook() {
00196         global $SESSION, $redirect;
00197 
00198         // Only do this if logout handler is defined, and if the user is actually logged in via Shibboleth
00199         $logouthandlervalid = isset($this->config->logout_handler) && !empty($this->config->logout_handler);
00200         if (isset($SESSION->shibboleth_session_id) && $logouthandlervalid ) {
00201             // Check if there is an alternative logout return url defined
00202             if (isset($this->config->logout_return_url) && !empty($this->config->logout_return_url)) {
00203                 // Set temp_redirect to alternative return url
00204                 $temp_redirect = $this->config->logout_return_url;
00205             } else {
00206                 // Backup old redirect url
00207                 $temp_redirect = $redirect;
00208             }
00209 
00210             // Overwrite redirect in order to send user to Shibboleth logout page and let him return back
00211             $redirect = $this->config->logout_handler.'?return='.urlencode($temp_redirect);
00212         }
00213     }
00214 
00215 
00216 
00225     function config_form($config, $err, $user_fields) {
00226         include "config.html";
00227     }
00228 
00235     function process_config($config) {
00236         global $CFG;
00237 
00238         // set to defaults if undefined
00239         if (!isset($config->auth_instructions) or empty($config->user_attribute)) {
00240             $config->auth_instructions = get_string('auth_shib_instructions', 'auth_shibboleth', $CFG->wwwroot.'/auth/shibboleth/index.php');
00241         }
00242         if (!isset ($config->user_attribute)) {
00243             $config->user_attribute = '';
00244         }
00245         if (!isset ($config->convert_data)) {
00246             $config->convert_data = '';
00247         }
00248 
00249         if (!isset($config->changepasswordurl)) {
00250             $config->changepasswordurl = '';
00251         }
00252 
00253         if (!isset($config->login_name)) {
00254             $config->login_name = 'Shibboleth Login';
00255         }
00256 
00257         // Clean idp list
00258         if (isset($config->organization_selection) && !empty($config->organization_selection) && isset($config->alt_login) && $config->alt_login == 'on') {
00259             $idp_list = get_idp_list($config->organization_selection);
00260             if (count($idp_list) < 1){
00261                 return false;
00262             }
00263             $config->organization_selection = '';
00264             foreach ($idp_list as $idp => $value){
00265                 $config->organization_selection .= $idp.', '.$value[0].', '.$value[1]."\n";
00266             }
00267         }
00268 
00269 
00270         // save settings
00271         set_config('user_attribute',    $config->user_attribute,    'auth/shibboleth');
00272 
00273         if (isset($config->organization_selection) && !empty($config->organization_selection)) {
00274             set_config('organization_selection',    $config->organization_selection,    'auth/shibboleth');
00275         }
00276         set_config('logout_handler',    $config->logout_handler,    'auth/shibboleth');
00277         set_config('logout_return_url',    $config->logout_return_url,    'auth/shibboleth');
00278         set_config('login_name',    $config->login_name,    'auth/shibboleth');
00279         set_config('convert_data',      $config->convert_data,      'auth/shibboleth');
00280         set_config('auth_instructions', $config->auth_instructions, 'auth/shibboleth');
00281         set_config('changepasswordurl', $config->changepasswordurl, 'auth/shibboleth');
00282 
00283         // Overwrite alternative login URL if integrated WAYF is used
00284         if (isset($config->alt_login) && $config->alt_login == 'on'){
00285             set_config('alt_login',    $config->alt_login,    'auth/shibboleth');
00286             set_config('alternateloginurl', $CFG->wwwroot.'/auth/shibboleth/login.php');
00287         } else {
00288             // Check if integrated WAYF was enabled and is now turned off
00289             // If it was and only then, reset the Moodle alternate URL
00290             if (isset($this->config->alt_login) and $this->config->alt_login == 'on'){
00291                 set_config('alt_login',    'off',    'auth/shibboleth');
00292                 set_config('alternateloginurl', '');
00293             }
00294             $config->alt_login = 'off';
00295         }
00296 
00297         // Check values and return false if something is wrong
00298         // Patch Anyware Technologies (14/05/07)
00299         if (($config->convert_data != '')&&(!file_exists($config->convert_data) || !is_readable($config->convert_data))){
00300             return false;
00301         }
00302 
00303         // Check if there is at least one entry in the IdP list
00304         if (isset($config->organization_selection) && empty($config->organization_selection) && isset($config->alt_login) && $config->alt_login == 'on'){
00305             return false;
00306         }
00307 
00308         return true;
00309     }
00310 
00316     function get_first_string($string) {
00317         $list = explode( ';', $string);
00318         $clean_string = rtrim($list[0]);
00319 
00320         return $clean_string;
00321     }
00322 }
00323 
00324 
00331     function set_saml_cookie($selectedIDP) {
00332         if (isset($_COOKIE['_saml_idp']))
00333         {
00334             $IDPArray = generate_cookie_array($_COOKIE['_saml_idp']);
00335         }
00336         else
00337         {
00338             $IDPArray = array();
00339         }
00340         $IDPArray = appendCookieValue($selectedIDP, $IDPArray);
00341         setcookie ('_saml_idp', generate_cookie_value($IDPArray), time() + (100*24*3600));
00342     }
00343 
00348     function print_idp_list(){
00349         $config = get_config('auth/shibboleth');
00350 
00351         $IdPs = get_idp_list($config->organization_selection);
00352         if (isset($_COOKIE['_saml_idp'])){
00353             $idp_cookie = generate_cookie_array($_COOKIE['_saml_idp']);
00354             do {
00355                 $selectedIdP = array_pop($idp_cookie);
00356             } while (!isset($IdPs[$selectedIdP]) && count($idp_cookie) > 0);
00357 
00358         } else {
00359             $selectedIdP = '-';
00360         }
00361 
00362         foreach($IdPs as $IdP => $data){
00363             if ($IdP == $selectedIdP){
00364                 echo '<option value="'.$IdP.'" selected="selected">'.$data[0].'</option>';
00365             } else {
00366                 echo '<option value="'.$IdP.'">'.$data[0].'</option>';
00367             }
00368         }
00369     }
00370 
00371 
00379     function get_idp_list($organization_selection) {
00380         $idp_list = array();
00381 
00382         $idp_raw_list = explode("\n",  $organization_selection);
00383 
00384         foreach ($idp_raw_list as $idp_line){
00385             $idp_data = explode(',', $idp_line);
00386             if (isset($idp_data[2]))
00387             {
00388                 $idp_list[trim($idp_data[0])] = array(trim($idp_data[1]),trim($idp_data[2]));
00389             }
00390             elseif(isset($idp_data[1]))
00391             {
00392                 $idp_list[trim($idp_data[0])] = array(trim($idp_data[1]));
00393             }
00394         }
00395 
00396         return $idp_list;
00397     }
00398 
00405     function generate_cookie_array($value) {
00406 
00407         // Decodes and splits cookie value
00408         $CookieArray = explode(' ', $value);
00409         $CookieArray = array_map('base64_decode', $CookieArray);
00410 
00411         return $CookieArray;
00412     }
00413 
00420     function generate_cookie_value($CookieArray) {
00421 
00422         // Merges cookie content and encodes it
00423         $CookieArray = array_map('base64_encode', $CookieArray);
00424         $value = implode(' ', $CookieArray);
00425         return $value;
00426     }
00427 
00435     function appendCookieValue($value, $CookieArray) {
00436 
00437         array_push($CookieArray, $value);
00438         $CookieArray = array_reverse($CookieArray);
00439         $CookieArray = array_unique($CookieArray);
00440         $CookieArray = array_reverse($CookieArray);
00441 
00442         return $CookieArray;
00443     }
00444 
00445 
00446 
 All Data Structures Namespaces Files Functions Variables Enumerations