Commit f00b8587 authored by haemmer's avatar haemmer
Browse files

Moved from internal to external SVN

parents
<?php
// WAYF Identity Provider Configuration file
// In the following you see some example entries of Identity Providers and
// cascaded WAYFs
// The keys of $IDProviders must correspond to the entityId of the
// Identity Providers or a unique value in case of a cascaded WAYF/DS or
// a category
// The sequence of IdPs and SPs play a role. No sorting is done.
// A general entry for an IdP can consist of the form:
// Type: [Optional] Some type that is used for the embedded wayf to hide
// or show certain categories. Default type will
// be 'unknown' if not specified.
// Name: [Mandatory] Default name to display in drop-down list
// [en|it|fr||de|pt][Name]: [Optional] Display name in other languages
// SSO: [Mandatory] Should be the SAML1 SSO endpoint of the IdP
// Realm: [Optional] Kerberos Realm
// IP[]: [Optional] IP ranges of that organizations that can be used to guess
// a user's Identity Provider
// An entry for another WAYF that the user shall be redirected to should have:
// Type: 'wayf'
// A category entry can be used to group multiple IdP entries into a optgroup
// The category entries should look like:
// Name: [Mandatory] Default name to display in drop-down list
// [en|it|fr||de|pt][Name]: [Optional] Display name in other languages
// Type: 'category' Category type
// As stated above, the sequence of entries is important. So, one is completely
// flexible when it comes to ordering the category and IdP entries.
//
// Category
$IDProviders['university'] = array (
'Type' => 'category',
'Name' => 'Universities',
);
// Example of a Kerberos-enabled Identity Provider
$IDProviders['bristol.ac.uk'] = array (
'Type' => 'university',
'Name' => 'University of Bristol',
'SSO' => 'https://sso.bris.ac.uk/sso/index.jsp',
'Realm' => 'ADS.BRIS.AC.UK',
);
// Example with optional network blocks that can be used as an
// additional IdP preselection hint
$IDProviders['aitta.funet.fi'] = array (
'Type' => 'university',
'Name' => 'Tampere University of Technology',
'SSO' => 'https://idp.tut.fi/shibboleth-idp/SSO',
'IP' => array ('193.166.2.0/24','130.233.0.0/16'),
);
// Category
$IDProviders['vho'] = array (
'Type' => 'category',
'Name' => 'Virtual Home Organization',
);
// An example of a configuration with multiple network blocks and multiple languages
$IDProviders['urn:mace:switch.ch:SWITCHaai:vho-switchaai.ch'] = array (
'Type' => 'vho',
'Name' => 'Virtual Home Organisation',
'de' => array ('Name' => 'Virtuelle Home Organisation'),
'fr' => array ('Name' => 'Home Organisation Virtuelle'),
'it' => array ('Name' => 'Virtuale Home Organisation'),
'IP' => array ('130.59.6.0/16','127.0.0.0/24'),
'SSO' => 'https://aai.vho-switchaai.ch/shibboleth-idp/SSO',
);
// Example of a WAYF entry that would redirect the user to this cascaded WAYF
// For SAML2 authentication requests, you must set the type to 'wayf' so that
// The user is not returned back to the Service Provider but forwarded to this
// additional Discovery Service
$IDProviders['urn:mace:switch.ch:SWITCHaai:edugain.net'] = array (
'SSO' => 'https://maclh.switch.ch/ShiBE-R/ShiBEWebSSORequester',
'Name' => 'Login via eduGAIN (testing)',
'Type' => 'wayf',
);
$IDProviders['urn:geant:edugain:component:be:switch:development.switch.ch'] = array (
'Type' => 'other',
'Name' => 'Login via eduGAIN (development)',
'SSO' => 'https://maclh.switch.ch/ShiBE-H/WebSSORequestListener',
);
// Example of an IDP you want not to be displayed when IDPs are parsed from
// a metadata file and SAML2MetaOverLocalConf is set to false
//$IDProviders['urn:mace:switch.ch:SWITCHaai:invisibleidp'] = '-';
// Category
$IDProviders['other'] = array (
'Type' => 'category',
'Name' => 'Others',
'de' => array ('Name' => 'Andere'),
'fr' => array ('Name' => 'Autres'),
'it' => array ('Name' => 'Altri'),
);
// Standard example with a Type that could be used to hide certain
// Identity Providers in the list of an embedded WAYF according to their type
$IDProviders['https://toba.switch.ch/idp/shibboleth'] = array(
'Type' => 'other',
'Name' => 'SWITCH - Serving Swiss Universities',
'SSO' => 'https://toba.switch.ch/idp/profile/Shibboleth/SSO',
);
?>
Copyright (c) 2010, SWITCH - Serving Swiss Universities
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of SWITCH nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This diff is collapsed.
<?php
/*
******************************************************************************
SWITCH PHP WAYF,
Copyright 2010 SWITCH - Serving Swiss Universities
Version: 1.12.1
Contact: aai@switch.ch
Web site: http://www.switch.ch/aai/wayf
******************************************************************************
*/
/*------------------------------------------------*/
// Load general configuration and template file
/*------------------------------------------------*/
require_once('config.php');
require_once('templates.php');
require_once('functions.php');
require_once('languages.php');
// Read custom strings
if (file_exists('custom-languages.php')){
require_once('custom-languages.php');
}
/*------------------------------------------------*/
// Turn on logging depending on development mode
/*------------------------------------------------*/
if (isset($developmentMode) && $developmentMode){
ini_set('error_reporting', E_ALL);
ini_set('display_errors', 'On');
ini_set('log_erros', 'Off');
} else {
error_reporting(0);
}
/*------------------------------------------------*/
// Read IDP configuration file
/*------------------------------------------------*/
// Determine language
$language = determineLanguage();
// Check if IdP files differ
// If not load file
if ($IDPConfigFile == $backupIDPConfigFile){
require_once($IDPConfigFile);
// If they do, check config file
} elseif (checkConfig($IDPConfigFile, $backupIDPConfigFile)){
require_once($IDPConfigFile);
// Use backup file if something went wrong
} else {
require_once($backupIDPConfigFile);
}
// Read metadata file if configuration option is set
if(isset($useSAML2Metadata) && $useSAML2Metadata && function_exists('xml_parser_create')){
require('readMetadata.php');
}
// Set default type
foreach ($IDProviders as $key => $values){
if (!isset($IDProviders[$key]['Type'])){
$IDProviders[$key]['Type'] = 'unknown';
}
}
/*------------------------------------------------*/
// Back-wards compatibility logic
/*------------------------------------------------*/
// This is for back-wards compatibility with very old versions of the WAYF
if (isset($_GET['getArguments']) && isset($_GET['origin']) && isset($_GET['redirect'])){
header('Location: '.$_SERVER['PHP_SELF'].'/redirect/'.$_GET['origin'].'?'.$_GET['getArguments']);
exit;
}
/*------------------------------------------------*/
// Set and delete cookies
/*------------------------------------------------*/
// Delete all cookies
if (isRequestType('deleteSettings')){
$cookies = array($redirectCookieName, $redirectStateCookieName, $SAMLDomainCookieName, $SPCookieName);
foreach ($cookies as $cookie){
if (isset($_COOKIE[$cookie])){
setcookie($cookie,'',time()-86400, '/', $commonDomain);
}
}
if (isset($_GET['return'])){
header('Location: '.$_GET['return']);
} else {
header('Location: '.$_SERVER['SCRIPT_NAME']);
}
exit;
}
// Delete permanent cookie
if (isset($_POST['clear_user_idp'])){
setcookie ($redirectCookieName, '', time() - 3600, '/', $commonDomain, false);
header('Location: ?'.$_SERVER['QUERY_STRING']);
exit;
}
// Get previously accessed IdPs
if (isset($_COOKIE[$SAMLDomainCookieName])){
$IDPArray = getIdPArrayFromValue($_COOKIE[$SAMLDomainCookieName]);
} else {
$IDPArray = array();
}
// Get previously accessed SPs
if (isset($_COOKIE[$SPCookieName])){
$SPArray = getIdPArrayFromValue($_COOKIE[$SPCookieName]);
} else {
$SPArray = array();
}
// Set Cookie to remember the selection
if (isset($_POST['user_idp']) && checkIDP($_POST['user_idp'])){
$IDPArray = appendValueToIdPArray($_POST['user_idp'], $IDPArray);
setcookie ($SAMLDomainCookieName, getValueFromIdPArray($IDPArray) , time() + (1000*24*3600), '/', $commonDomain, false);
}
// Set cookie for most recently used Service Provider
if (isset($_GET['entityID'])){
$SPArray = appendValueToIdPArray($_GET['entityID'], array());
setcookie ($SPCookieName, getValueFromIdPArray($SPArray), time() + (10*24*3600), '/', $commonDomain, false);
} else if (isset($_GET['providerId'])){
$SPArray = appendValueToIdPArray($_GET['providerId'], array());
setcookie ($SPCookieName, getValueFromIdPArray($SPArray), time() + (10*24*3600), '/', $commonDomain, false);
}
// Set the permanent or session cookie
if (isset($_POST['permanent'])
&& isset($_POST['user_idp'])
&& checkIDP($_POST['user_idp'])){
// Set permanent cookie
if (is_numeric($_POST['permanent'])){
setcookie ($redirectCookieName, $_POST['user_idp'], time() + ($_POST['permanent']*24*3600), '/', $commonDomain, false);
} else {
setcookie ($redirectCookieName, $_POST['user_idp'], time() + (100*24*3600), '/', $commonDomain, false);
}
} elseif (
isset($_POST['session'])
&& isset($_POST['user_idp'])
&& checkIDP($_POST['user_idp'])
){
// Set redirection cookie and redirection state cookie
setcookie ($redirectCookieName, $_POST['user_idp'], null, '/', $commonDomain, false);
setcookie ($redirectStateCookieName, 'checked', time() + (100*24*3600), '/', $commonDomain, false);
} else {
// Delete cookie for session checkbox
setcookie ($redirectStateCookieName, 'checked', time() - 3600, '/', $commonDomain, false);
}
/*------------------------------------------------*/
// Redirecting user
/*------------------------------------------------*/
// IDP determined by redirect cookie
if (
isValidShibRequest()
&& isset($_COOKIE[$redirectCookieName])
&& checkIDP($_COOKIE[$redirectCookieName], false)
){
$cookieIdP = $_COOKIE[$redirectCookieName];
// Handle cascaded WAYF
if (isset($IDProviders[$cookieIdP]['Type']) && $IDProviders[$cookieIdP]['Type'] == 'wayf'){
// Send user to cascaded WAYF with same request
header('Location: '.$IDProviders[$cookieIdP]['SSO'].'?'.$_SERVER['QUERY_STRING']);
} elseif (isValidDSRequest()){
header('Location: '.$_GET['return'].'&'.getReturnIDParam().'='.urlencode($cookieIdP));
// Create log entry
logAccessEntry('DS', 'Cookie', $_GET['return'], $cookieIdP);
} else {
header('Location: '.$IDProviders[$cookieIdP]['SSO'].'?'.$_SERVER['QUERY_STRING']);
// Create log entry
logAccessEntry('WAYF', 'Cookie', $_GET['shire'], $cookieIdP);
}
exit;
}
// Redirect using Kerberos
// Check if $REMOTE_USER has been set by mod_auth_kerb
if (isset($_SERVER['REMOTE_USER'])) {
$kerberosPrincipal = $_SERVER['REMOTE_USER'];
// Bingo - we have a winner!
$kerberosRealm = substr($user, 1 + strlen($kerberosPrincipal) - strlen(strrchr($kerberosPrincipal, "@")));
if ($kerberosIDP = getKerberosRealm($kerberosRealm) && checkIDP($kerberosIDP, false)){
// Handle cascaded WAYF
if (isset($IDProviders[$kerberosIDP]['Type']) && $IDProviders[$kerberosIDP]['Type'] == 'wayf'){
// Send user to cascaded WAYF with same request
header('Location: '.$IDProviders[$kerberosIDP]['SSO'].'?'.$_SERVER['QUERY_STRING']);
} elseif (isValidDSRequest()){
header('Location: '.$_GET['return'].'&'.getReturnIDParam().'='.urlencode($kerberosIDP));
// Create log entry
logAccessEntry('DS', 'Kerberos', $_GET['return'], $kerberosIDP);
} else {
header('Location: '.$IDProviders[$kerberosIDP]['SSO'].'?'.$_SERVER['QUERY_STRING']);
// Create log entry
logAccessEntry('WAYF', 'Kerberos', $_GET['shire'], $kerberosIDP);
}
exit;
}
}
// Trigger Kerberos authentication
if ($useKerberos && !isset($kerberosRealm)) {
// Check the headers for an Authorisation header.
$headers = getallheaders();
// If its' there...
foreach ($headers as $name => $content) {
if ($name == "Authorization") {
// ... then the user agent is attempting Negotiate, so we
// redirect to the soft link (that points back to this script)
// which is protected by mod_auth_kerb.
$url = $kerberosRedirectURL."?".$_SERVER['QUERY_STRING'];
header("Location: $url");
exit();
}
}
// Send the User Agent a Negotiate header
// This will provoke a User Agent that supports Negotiate into requesting this
// script a second time, including an 'Authorize' header. We catch this header
// in the code above.
header('WWW-Authenticate: Negotiate');
// If the User Agent doesn't support Negotiate, we continue as usual.
}
// For backwards compatiblity
if (
isset($_GET['shire'])
&& isset($_GET['target'])
&& isset($_GET['origin'])
&& checkIDP($_GET['origin'])
){
header('Location: '.$IDProviders[$_GET['origin']]['SSO'].'?'.$_SERVER['QUERY_STRING']);
// Create log entry
logAccessEntry('WAYF', 'Old-Request', $_GET['shire'], $_GET['origin']);
exit;
}
// Redirect using resource hint
$hintedPathIDP = getIdPPathInfoHint();
if ($hintedPathIDP != '-'){
// Handle cascaded WAYF
if (isset($IDProviders[$hintedPathIDP]['Type']) && $IDProviders[$hintedPathIDP]['Type'] == 'wayf'){
// Send user to cascaded WAYF with same request
header('Location: '.$IDProviders[$hintedPathIDP]['SSO'].'?'.$_SERVER['QUERY_STRING']);
exit;
} elseif ( checkPathInfo('redirect') ){
// Set redirect cookie for this session
setcookie ($redirectCookieName, $hintedPathIDP, null, '/', $commonDomain, false);
// Determine if DS or WAYF request
if (isValidDSRequest()){
header('Location: '.$_GET['return'].'&'.getReturnIDParam().'='.urlencode($hintedPathIDP));
// Create log entry
logAccessEntry('DS', 'Path', $_GET['return'], $hintedPathIDP);
} else {
header('Location: '.$IDProviders[$hintedPathIDP]['SSO'].'?'.$_SERVER['QUERY_STRING']);
// Create log entry
logAccessEntry('WAYF', 'Path', $_GET['shire'], $hintedPathIDP);
}
exit;
}
}
// Redirect using user selection
if (
isset($_POST['user_idp'])
&& checkIDP($_POST['user_idp'])
&& isValidShibRequest()
&& !isset($_POST['permanent'])
){
$selectedIDP = $_POST['user_idp'];
// Handle cascaded WAYF
if (isset($IDProviders[$selectedIDP]['Type']) && $IDProviders[$selectedIDP]['Type'] == 'wayf'){
// Send user to cascaded WAYF with same request
header('Location: '.$IDProviders[$selectedIDP]['SSO'].'?'.$_SERVER['QUERY_STRING']);
} else if (isValidDSRequest()){
header('Location: '.$_GET['return'].'&'.getReturnIDParam().'='.urlencode($selectedIDP));
// Create log entry
if (isset($_POST['request_type']) && $_POST['request_type'] == 'embedded'){
logAccessEntry('Embedded-DS', 'Request', $_GET['return'], $selectedIDP);
} else {
logAccessEntry('DS', 'Request', $_GET['return'], $selectedIDP);
}
} else {
header('Location: '.$IDProviders[$selectedIDP]['SSO'].'?'.$_SERVER['QUERY_STRING']);
// Create log entry
if (isset($_POST['request_type']) && $_POST['request_type'] == 'embedded'){
logAccessEntry('Embedded-WAYF', 'Request', $_GET['shire'], $selectedIDP);
} else {
logAccessEntry('WAYF', 'Request', $_GET['shire'], $selectedIDP);
}
}
exit;
}
/*------------------------------------------------*/
// Gather data to preselect user's IdP
/*------------------------------------------------*/
// Initialize selected IdP
$selectedIDP = '-';
// Cookie hint
$hintedCookieIdP = '-';
if (count($IDPArray) > 0){
// Make sure one of these IdP exists
foreach ($IDPArray as $previouslyUsedIDP){
if (isset($IDProviders[$previouslyUsedIDP])){
$hintedCookieIdP = $previouslyUsedIDP;
}
}
}
// IP address range hint
$hintedIPIDP = '-';
$hintedIPIDP = getIPAdressHint();
// Reverse DNS lookup hint
$hintedDomainIDP = '-';
if (isset($useReverseDNSLookup) && $useReverseDNSLookup){
$hintedDomainIDP = getDomainNameFromURIHint();
}
/*------------------------------------------------*/
// Determine preselected IdP using gathered data
/*------------------------------------------------*/
// Prioritise selected IDP in this sequence
// - Previous used IdP
// - Path info hint
// - IP address range hint
// - Reverse DNS Lookup hint
// - No Preselection
if ($hintedCookieIdP != '-'){
$selectedIDP = $hintedCookieIdP;
} elseif ($hintedPathIDP != '-'){
$selectedIDP = $hintedPathIDP;
} elseif ($hintedIPIDP != '-'){
$selectedIDP = $hintedIPIDP;
} elseif ($hintedDomainIDP != '-'){
$selectedIDP = $hintedDomainIDP;
} else {
$selectedIDP = '-';
}
/*------------------------------------------------*/
// Draw WAYF
/*------------------------------------------------*/
// Coming from an SP with proper GET arguments
if (
isValidShibRequest()
&& (!isset($_POST['user_idp']) || $_POST['user_idp'] == '-')
) {
// Return directly to IdP if isPassive is set
if (
isValidDSRequest()
&& isset($_GET['isPassive'])
&& $_GET['isPassive'] == 'true'
){
// Only return user with returnIDParam to SP if IdP could be guessed
if ($selectedIDP == '-' || $selectedIDP == ''){
header('Location: '.$_GET['return']);
// Create log entry
logAccessEntry('DS', 'Passive', $_GET['return'], '-');
} else {
header('Location: '.$_GET['return'].'&'.getReturnIDParam().'='.urlencode($selectedIDP));
// Create log entry
logAccessEntry('DS', 'Passive', $_GET['return'], $selectedIDP);
}
exit;
}
// Show selection
// Show Header
printHeader();
// Show drop down list
printWAYF();
// Show footer
printFooter();
exit;
} elseif(
(!isset($_GET['shire']) && isset($_GET['target']))
|| (isset($_GET['shire']) && !isset($_GET['target']))
){
// Show error
$invalidstring = urldecode($_SERVER['QUERY_STRING']);
$invalidstring = preg_replace('/&/',"&\n",$invalidstring);
if ($invalidstring == '')
$invalidstring = getLocalString('no_arguments');
$message = getLocalString('arguments_missing') . '<pre><code>'.$invalidstring.'</code></pre></p>
<p>'. getLocalString('valid_request_description');
printError($message);
exit;
} elseif(
(!isset($_GET['entityID']) && isset($_GET['return']))
|| (isset($_GET['entityID']) && !isset($_GET['return']))
){
// Show error
$invalidstring = urldecode($_SERVER['QUERY_STRING']);
$invalidstring = preg_replace('/&/',"&\n",$invalidstring);
if ($invalidstring == '')
$invalidstring = getLocalString('no_arguments');
$message = getLocalString('arguments_missing') . '<pre><code>'.$invalidstring.'</code></pre></p>
<p>'. getLocalString('valid_saml2_request_description');
printError($message);
exit;
} elseif(isRequestType('snippet.html')){
// Check if this feature is activated at all
if (!isset($useEmbeddedWAYF) || !$useEmbeddedWAYF){
echo '// The embedded WAYF feature is deactivated in the configuration';
exit;
}
// Return the HTML snippet for including the Embedded WAYF
printEmbeddedConfigurationScript();
exit;
} elseif(isRequestType('snippet.txt')){
header('Content-Type: text/plain');
// Check if this feature is activated at all
if (!isset($useEmbeddedWAYF) || !$useEmbeddedWAYF){