From 4d5c9a011692b6f37319b240e375e4b0eca19c62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=85kre=20Solberg?= <andreas.solberg@uninett.no> Date: Mon, 8 Dec 2008 22:08:16 +0000 Subject: [PATCH] Initial checkin of CAS Server in simpleSAMLphp. Implemented as a module. Works with saml2 and shib13. documentation TBD. git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@1056 44740490-163a-0410-bde0-09ae8108e29a --- .../config-templates/module_casserver.php | 24 ++++ modules/casserver/default-disable | 0 modules/casserver/www/login.php | 105 ++++++++++++++++++ modules/casserver/www/serverValidate.php | 105 ++++++++++++++++++ modules/casserver/www/validate.php | 96 ++++++++++++++++ 5 files changed, 330 insertions(+) create mode 100644 modules/casserver/config-templates/module_casserver.php create mode 100644 modules/casserver/default-disable create mode 100644 modules/casserver/www/login.php create mode 100644 modules/casserver/www/serverValidate.php create mode 100644 modules/casserver/www/validate.php diff --git a/modules/casserver/config-templates/module_casserver.php b/modules/casserver/config-templates/module_casserver.php new file mode 100644 index 000000000..a7097b786 --- /dev/null +++ b/modules/casserver/config-templates/module_casserver.php @@ -0,0 +1,24 @@ +<?php +/* + * Configuration for the module casserver. + * + * $Id: $ + */ + +$config = array ( + + 'legal_service_urls' => array( + 'http://test.feide.no/casclient', + 'http://test.feide.no/cas2', + ), + + // Legal values: saml2, shib13 + 'auth' => 'saml2', + + 'ticketcache' => 'ticketcache', + + 'attrname' => 'mail', // 'eduPersonPrincipalName', + +); + +?> diff --git a/modules/casserver/default-disable b/modules/casserver/default-disable new file mode 100644 index 000000000..e69de29bb diff --git a/modules/casserver/www/login.php b/modules/casserver/www/login.php new file mode 100644 index 000000000..a953bd663 --- /dev/null +++ b/modules/casserver/www/login.php @@ -0,0 +1,105 @@ +<?php + +/* + * Incomming parameters: + * service + * renew + * gateway + * + */ + + +if (!array_key_exists('service', $_GET)) + throw new Exception('Required URL query parameter [service] not provided. (CAS Server)'); + +$service = $_GET['service']; +$renew = FALSE; +$gateway = FALSE; + +if (array_key_exists('renew', $_GET)) { + $renew = TRUE; +} + +if (array_key_exists('gateway', $_GET)) { + $gateway = TRUE; + throw new Exception('CAS gateway to SAML IsPassive: Not yet implemented properly.'); +} + + + + + +/* Load simpleSAMLphp, configuration and metadata */ +$config = SimpleSAML_Configuration::getInstance(); +$casconfig = $config->copyFromBase('casconfig', 'module_casserver.php'); +$session = SimpleSAML_Session::getInstance(); + + +$legal_service_urls = $casconfig->getValue('legal_service_urls'); +if (!checkServiceURL($service, $legal_service_urls)) + throw new Exception('Service parameter provided to CAS server is not listed as a legal service: [service] = ' . $service); + +$auth = $casconfig->getValue('auth', 'saml2'); +if (!in_array($auth, array('saml2', 'shib13'))) + throw new Exception('CAS Service configured to use [auth] = ' . $auth . ' only [saml2,shib13] is legal.'); + +if (!$session->isValid($auth) ) { + SimpleSAML_Utilities::redirect( + '/' . $config->getBaseURL() . $auth . '/sp/initSSO.php', + array('RelayState' => SimpleSAML_Utilities::selfURL() ) + ); +} +$attributes = $session->getAttributes(); + +$path = $casconfig->resolvePath($casconfig->getValue('ticketcache', 'ticketcache')); +$ticket = SimpleSAML_Utilities::generateID(); +storeTicket($ticket, $path, $attributes); + +// $test = retrieveTicket($ticket, $path); + + +SimpleSAML_Utilities::redirect( + SimpleSAML_Utilities::addURLparameter($service, + array('ticket' => $ticket) + ) +); + + + +function storeTicket($ticket, $path, &$value ) { + + if (!is_dir($path)) + throw new Exception('Directory for CAS Server ticket storage [' . $path . '] does not exists. '); + + if (!is_writable($path)) + throw new Exception('Directory for CAS Server ticket storage [' . $path . '] is not writable. '); + + $filename = $path . '/' . $ticket; + file_put_contents($filename, serialize($value)); +} + +function retrieveTicket($ticket, $path) { + + if (!is_dir($path)) + throw new Exception('Directory for CAS Server ticket storage [' . $path . '] does not exists. '); + + + $filename = $path . '/' . $ticket; + return unserialize(file_get_contents($filename)); +} + + + +function checkServiceURL($service, array $legal_service_urls) { + foreach ($legal_service_urls AS $legalurl) { + if (strpos($service, $legalurl) === 0) return TRUE; + } + return FALSE; +} + + + + + + +?> \ No newline at end of file diff --git a/modules/casserver/www/serverValidate.php b/modules/casserver/www/serverValidate.php new file mode 100644 index 000000000..7b78932b4 --- /dev/null +++ b/modules/casserver/www/serverValidate.php @@ -0,0 +1,105 @@ +<?php + +/* + * Incomming parameters: + * service + * renew + * ticket + * + */ + + +if (!array_key_exists('service', $_GET)) + throw new Exception('Required URL query parameter [service] not provided. (CAS Server)'); + +$service = $_GET['service']; + +if (!array_key_exists('ticket', $_GET)) + throw new Exception('Required URL query parameter [ticket] not provided. (CAS Server)'); + +$ticket = $_GET['ticket']; + +$renew = FALSE; + +if (array_key_exists('renew', $_GET)) { + $renew = TRUE; +} + + + +try { + /* Load simpleSAMLphp, configuration and metadata */ + $config = SimpleSAML_Configuration::getInstance(); + $casconfig = $config->copyFromBase('casconfig', 'module_casserver.php'); + + + $path = $casconfig->resolvePath($casconfig->getValue('ticketcache', 'ticketcache')); + + $ticketcontent = retrieveTicket($ticket, $path); + + $usernamefield = $casconfig->getValue('attrname', 'eduPersonPrincipalName'); + + if (array_key_exists($usernamefield, $ticketcontent)) { + returnResponse('YES', $ticketcontent[$usernamefield][0]); + } else { + returnResponse('NO'); + } + +} catch (Exception $e) { + + returnResponse('NO', $e->getMessage()); +} + +function returnResponse($value, $content = '') { + if ($value === 'YES') { + echo '<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas"> + <cas:authenticationSuccess> + <cas:user>' . htmlentities($content) . '</cas:user> + </cas:authenticationSuccess> +</cas:serviceResponse>'; + + } else { + echo '<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas"> + <cas:authenticationFailure code="..."> + ' . $content . ' + </cas:authenticationFailure> +</cas:serviceResponse>'; + } +} + + +function storeTicket($ticket, $path, &$value ) { + + if (!is_dir($path)) + throw new Exception('Directory for CAS Server ticket storage [' . $path . '] does not exists. '); + + if (!is_writable($path)) + throw new Exception('Directory for CAS Server ticket storage [' . $path . '] is not writable. '); + + $filename = $path . '/' . $ticket; + file_put_contents($filename, serialize($value)); +} + +function retrieveTicket($ticket, $path) { + + if (!preg_match('/^_?[a-zA-Z0-9]+$/', $ticket)) throw new Exception('Invalid characters in ticket'); + + if (!is_dir($path)) + throw new Exception('Directory for CAS Server ticket storage [' . $path . '] does not exists. '); + + $filename = $path . '/' . $ticket; + + if (!file_exists($filename)) + throw new Exception('Could not find ticket'); + + $content = file_get_contents($filename); + + unlink($filename); + + return unserialize($content); +} + + + + +?> \ No newline at end of file diff --git a/modules/casserver/www/validate.php b/modules/casserver/www/validate.php new file mode 100644 index 000000000..4a2b32639 --- /dev/null +++ b/modules/casserver/www/validate.php @@ -0,0 +1,96 @@ +<?php + +/* + * Incomming parameters: + * service + * renew + * ticket + * + */ + + +if (!array_key_exists('service', $_GET)) + throw new Exception('Required URL query parameter [service] not provided. (CAS Server)'); + +$service = $_GET['service']; + +if (!array_key_exists('ticket', $_GET)) + throw new Exception('Required URL query parameter [ticket] not provided. (CAS Server)'); + +$ticket = $_GET['ticket']; + +$renew = FALSE; + +if (array_key_exists('renew', $_GET)) { + $renew = TRUE; +} + + + +try { + /* Load simpleSAMLphp, configuration and metadata */ + $config = SimpleSAML_Configuration::getInstance(); + $casconfig = $config->copyFromBase('casconfig', 'module_casserver.php'); + + + $path = $casconfig->resolvePath($casconfig->getValue('ticketcache', 'ticketcache')); + + $ticketcontent = retrieveTicket($ticket, $path); + + $usernamefield = $casconfig->getValue('attrname', 'eduPersonPrincipalName'); + + if (array_key_exists($usernamefield, $ticketcontent)) { + returnResponse('YES', $ticketcontent[$usernamefield][0]); + } else { + returnResponse('NO'); + } + +} catch (Exception $e) { + + returnResponse('NO'); +} + +function returnResponse($value, $username = '') { + if ($value === 'YES') { + echo 'YES' . "\n" . $username; + } else { + echo 'NO' . "\n"; + } +} + + +function storeTicket($ticket, $path, &$value ) { + + if (!is_dir($path)) + throw new Exception('Directory for CAS Server ticket storage [' . $path . '] does not exists. '); + + if (!is_writable($path)) + throw new Exception('Directory for CAS Server ticket storage [' . $path . '] is not writable. '); + + $filename = $path . '/' . $ticket; + file_put_contents($filename, serialize($value)); +} + +function retrieveTicket($ticket, $path) { + + if (!preg_match('/^_?[a-zA-Z0-9]+$/', $ticket)) throw new Exception('Invalid characters in ticket'); + + if (!is_dir($path)) + throw new Exception('Directory for CAS Server ticket storage [' . $path . '] does not exists. '); + + $filename = $path . '/' . $ticket; + + if (!file_exists($filename)) + throw new Exception('Could not find ticket'); + + $content = file_get_contents($filename); + + unlink($filename); + + return unserialize($content); +} + + + + +?> \ No newline at end of file -- GitLab