ÿØÿà JFIF    ÿÛ „  ( %"1!%)+...383,7(-.+  -+++--++++---+-+-----+---------------+---+-++7-----ÿÀ  ß â" ÿÄ     ÿÄ H    !1AQaq"‘¡2B±ÁÑð#R“Ò Tbr‚²á3csƒ’ÂñDS¢³$CÿÄ   ÿÄ %  !1AQa"23‘ÿÚ   ? ôÿ ¨pŸªáÿ —åYõõ\?àÒü©ŠÄï¨pŸªáÿ —åYõõ\?àÓü©ŠÄá 0Ÿªáÿ Ÿå[úƒ ú®ði~TÁbqÐ8OÕpÿ ƒOò¤Oè`–RÂáœá™êi€ßÉ< FtŸI“öÌ8úDf´°å}“¾œ6  öFá°y¥jñÇh†ˆ¢ã/ÃÐ:ªcÈ "Y¡ðÑl>ÿ ”ÏËte:qž\oäŠe÷󲍷˜HT4&ÿ ÓÐü6ö®¿øþßèô Ÿ•7Ñi’•j|“ñì>b…þS?*Óôÿ ÓÐü*h¥£ír¶ü UãS炟[AÐaè[ûª•õ&õj?†Éö+EzP—WeÒírJFt ‘BŒ†Ï‡%#tE Øz ¥OÛ«!1›üä±Í™%ºÍãö]°î(–:@<‹ŒÊö×òÆt¦ãº+‡¦%ÌÁ²h´OƒJŒtMÜ>ÀÜÊw3Y´•牋4ǍýʏTì>œú=Íwhyë,¾Ôò×õ¿ßÊa»«þˆѪQ|%6ž™A õ%:øj<>É—ÿ Å_ˆCbõ¥š±ý¯Ýƒï…¶|RëócÍf溪“t.СøTÿ *Ä¿-{†çàczůŽ_–^XþŒ±miB[X±d 1,é”zEù»& î9gœf™9Ð'.;—™i}!ôšåîqêÛ٤ёý£½ÆA–àôe"A$˝Úsäÿ ÷Û #°xŸëí(l »ý3—¥5m! rt`†0~'j2(]S¦¦kv,ÚÇ l¦øJA£Šƒ J3E8ÙiŽ:cÉžúeZ°€¯\®kÖ(79«Ž:¯X”¾³Š&¡* ….‰Ž(ÜíŸ2¥ª‡×Hi²TF¤ò[¨íÈRëÉ䢍mgÑ.Ÿ<öäS0í„ǹÁU´f#Vß;Õ–…P@3ío<ä-±»Ž.L|kªÀê›fÂ6@»eu‚|ÓaÞÆŸ…¨ááå>åŠ?cKü6ùTÍÆ”†sĤÚ;H2RÚ†õ\Ö·Ÿn'¾ ñ#ºI¤Å´%çÁ­‚â7›‹qT3Iï¨ÖÚ5I7Ë!ÅOóŸ¶øÝñØôת¦$Tcö‘[«Ö³šÒ';Aþ ¸èíg A2Z"i¸vdÄ÷.iõ®§)¿]¤À†–‡É&ä{V¶iŽ”.Ó×Õÿ û?h¬Mt–íª[ÿ Ñÿ ÌV(í}=ibÔ¡›¥¢±b Lô¥‡piη_Z<‡z§èŒ)iÖwiÇ 2hÙ3·=’d÷8éŽ1¦¸c¤µ€7›7Ø ð\á)} ¹fËí›pAÃL%âc2 í§æQz¿;T8sæ°qø)QFMð‰XŒÂ±N¢aF¨…8¯!U  Z©RÊ ÖPVÄÀÍin™Ì-GˆªÅËŠ›•zË}º±ŽÍFò¹}Uw×#ä5B¤{î}Ð<ÙD é©¤&‡ïDbàÁôMÁ.. /** * Contains a helper class for the Shibboleth authentication plugin. * * @package auth_shibboleth * @copyright 2018 Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace auth_shibboleth; defined('MOODLE_INTERNAL') || die(); /** * The helper class for the Shibboleth authentication plugin. * * @package auth_shibboleth * @copyright 2018 Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class helper { /** * Delete session of user using file sessions. * * @param string $spsessionid SP-provided Shibboleth Session ID * @return \SoapFault or void if everything was fine */ public static function logout_file_session($spsessionid) { global $CFG; if (!empty($CFG->session_file_save_path)) { $dir = $CFG->session_file_save_path; } else { $dir = $CFG->dataroot . '/sessions'; } if (is_dir($dir)) { if ($dh = opendir($dir)) { // Read all session files. while (($file = readdir($dh)) !== false) { // Check if it is a file. if (is_file($dir.'/'.$file)) { // Read session file data. $data = file($dir.'/'.$file); if (isset($data[0])) { $usersession = self::unserializesession($data[0]); // Check if we have found session that shall be deleted. if (isset($usersession['SESSION']) && isset($usersession['SESSION']->shibboleth_session_id)) { // If there is a match, delete file. if ($usersession['SESSION']->shibboleth_session_id == $spsessionid) { // Delete session file. if (!unlink($dir.'/'.$file)) { return new SoapFault('LogoutError', 'Could not delete Moodle session file.'); } } } } } } closedir($dh); } } } /** * Delete session of user using DB sessions. * * @param string $spsessionid SP-provided Shibboleth Session ID */ public static function logout_db_session($spsessionid) { global $CFG, $DB; $sessions = $DB->get_records_sql( 'SELECT userid, sessdata FROM {sessions} WHERE timemodified > ?', array(time() - $CFG->sessiontimeout) ); foreach ($sessions as $session) { // Get user session from DB. $usersession = self::unserializesession(base64_decode($session->sessdata)); if (isset($usersession['SESSION']) && isset($usersession['SESSION']->shibboleth_session_id)) { // If there is a match, kill the session. if ($usersession['SESSION']->shibboleth_session_id == trim($spsessionid)) { // Delete this user's sessions. \core\session\manager::kill_user_sessions($session->userid); } } } } /** * Unserialize a session string. * * @param string $serializedstring * @return array */ private static function unserializesession($serializedstring) { $variables = array(); $index = 0; // Find next delimiter after current index. It's key being the characters between those points. while ($delimiterpos = strpos($serializedstring, '|', $index)) { $key = substr($serializedstring, $index, $delimiterpos - $index); // Start unserializing immediately after the delimiter. PHP will read as much valid data as possible. $value = unserialize(substr($serializedstring, $delimiterpos + 1), ['allowed_classes' => ['stdClass']]); $variables[$key] = $value; // Advance index beyond the length of the previously captured serialized value. $index = $delimiterpos + 1 + strlen(serialize($value)); } return $variables; } }