From 46f22e706afa85f6eeb5af81503fd5f397e437e5 Mon Sep 17 00:00:00 2001
From: Olav Morken <olav.morken@uninett.no>
Date: Thu, 15 May 2008 16:13:36 +0000
Subject: [PATCH] SAML2-IdP: Fix IdP-initiated logout.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@574 44740490-163a-0410-bde0-09ae8108e29a
---
 www/saml2/idp/SingleLogoutService.php |   4 +
 www/saml2/idp/initSLO.php             | 139 ++------------------------
 2 files changed, 12 insertions(+), 131 deletions(-)

diff --git a/www/saml2/idp/SingleLogoutService.php b/www/saml2/idp/SingleLogoutService.php
index 18f27a917..e9a3f3f8c 100644
--- a/www/saml2/idp/SingleLogoutService.php
+++ b/www/saml2/idp/SingleLogoutService.php
@@ -205,6 +205,10 @@ if (isset($_GET['SAMLRequest'])) {
 	/* Fetch the $logoutInfo variable. */
 	fetchLogoutInfo($_GET['LogoutID']);
 
+} elseif(array_key_exists('ReturnTo', $_GET)) {
+	/* We have a ReturnTo - this is IdP initialized SLO. */
+	$logoutInfo['RelayState'] = $_GET['ReturnTo'];
+
 } else {
 	/*
 	 * We have no idea what to do here. It is neither a logout request, a logout
diff --git a/www/saml2/idp/initSLO.php b/www/saml2/idp/initSLO.php
index 36869e9b3..f14185f00 100644
--- a/www/saml2/idp/initSLO.php
+++ b/www/saml2/idp/initSLO.php
@@ -5,149 +5,26 @@ require_once('../../../www/_include.php');
 require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Utilities.php');
 require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Session.php');
 require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Logger.php');
-require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Metadata/MetaDataStorageHandler.php');
-require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/XML/SAML20/LogoutRequest.php');
-require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/XML/SAML20/LogoutResponse.php');
-require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Bindings/SAML20/HTTPRedirect.php');
-require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/XHTML/Template.php');
 
 
 $config = SimpleSAML_Configuration::getInstance();
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
 $session = SimpleSAML_Session::getInstance();
 
-
 SimpleSAML_Logger::info('SAML2.0 - IdP.initSLO: Accessing SAML 2.0 IdP endpoint init Single Logout');
 
-if (!$config->getValue('enable.saml20-idp', false))
-	SimpleSAML_Utilities::fatalError(isset($session) ? $session->getTrackID() : null, 'NOACCESS');
-
-try {
-	$idpentityid = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
-} catch (Exception $exception) {
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'METADATA', $exception);
-}
-
-
-/**
- * If we get an incomming LogoutRequest then we initiate the logout process.
- * in this case an SAML 2.0 SP is sending an request, which also is referred to as
- * SP initiated Single Logout.
- *
- */
-if (isset($_GET['RelayState'])) {
-
-	$relaystate = $_GET['RelayState'];
-	
-	/** 
-	 * No session exists. Just go to the RelayState.
-	 */
-	if($session === NULL) {
-		SimpleSAML_Logger::info('SAML2.0 - IdP.initSLO: Did not find a session here, so we redirect to the RelayState');
-		SimpleSAML_Utilities::redirect($relaystate);
-		exit;
-	}
-
-	// Set local IdP session to invalid.
-	$session->doLogout(false);
-
-
-	/*
-	 * Create an assoc array of the request to store in the session cache.
-	 */
-	$requestcache = array(
-		'RelayState' => $relaystate
-	);
-		
-	$session->setLogoutRequest($requestcache);
-	SimpleSAML_Logger::debug('SAML2.0 - IDP.initSSO: Setting cached request with relay state ' . $relaystate);
-	
-	//$session->set_sp_logout_completed($logoutrequest->getIssuer() );
-	
-
-}
-
-$lookformore = true;
-$spentityid = null;
-do {
-	/* Dump the current sessions (for debugging). */
-	$session->dump_sp_sessions();
-
-	/*
-	 * We proceed to send logout requests to all remaining SPs.
-	 */
-	$spentityid = $session->get_next_sp_logout();
-	
-	
-	// If there are no more SPs left, then we will not look for more SPs.
-	if (empty($spentityid)) $lookformore = false;
-	
-	try {
-		$spmetadata = $metadata->getMetadata($spentityid, 'saml20-sp-remote');
-	} catch (Exception $e) {
-		continue;
-	}
-	
-	// If the SP we found have an SingleLogout endpoint then we will use it, and
-	// hence we do not need to look for more yet.
-	if (array_key_exists('SingleLogoutService', $spmetadata) && 
-		!empty($spmetadata['SingleLogoutService']) ) $lookformore = false;
-		
-	if ($lookformore)
-		SimpleSAML_Logger::info('SAML2.0 - IDP.SingleLogoutService: Will not logout from ' . $spentityid . ' looking for more SPs');
-
-} while ($lookformore);
-
-
-
-/*
- * We proceed to send logout requests to the first remaining SP.
- */
-$spentityid = $session->get_next_sp_logout();
-if ($spentityid) {
-
-	SimpleSAML_Logger::info('SAML2.0 - IDP.SingleLogoutService: Logout next SP ' . $spentityid);
-
-	try {
-		$lr = new SimpleSAML_XML_SAML20_LogoutRequest($config, $metadata);
-
-		// ($issuer, $receiver, $nameid, $nameidformat, $sessionindex, $mode) {
-		$req = $lr->generate($idpentityid, $spentityid, $session->getNameID(), $session->getSessionIndex(), 'IdP');
-
-		$httpredirect = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config, $metadata);
-
-		$relayState = SimpleSAML_Utilities::selfURL();
-		if (isset($_GET['RelayState'])) {
-			$relayState = $_GET['RelayState'];
-		}
-
-		//$request, $remoteentityid, $relayState = null, $endpoint = 'SingleLogoutService', $direction = 'SAMLRequest', $mode = 'SP'
-		$httpredirect->sendMessage($req, $idpentityid, $spentityid, $relayState, 'SingleLogoutService', 'SAMLRequest', 'IdP');
-
-		exit();
-
-	} catch(Exception $exception) {
-
-		SimpleSAML_Utilities::fatalError($session->getTrackID(), 'GENERATELOGOUTREQUEST', $exception);
-
-	}
-
+if (!$config->getValue('enable.saml20-idp', false)) {
+	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NOACCESS');
 }
 
-if ($config->getValue('debug', false))
-	SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: LogoutService: All SPs done ');
 
-
-if (isset($_GET['RelayState'])) {
-
-	$relayState = $_GET['RelayState'];
-	SimpleSAML_Utilities::redirect($relayState);
-
-} else {
-	
+if (!isset($_GET['RelayState'])) {
 	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NORELAYSTATE');
-
 }
 
+$returnTo = $_GET['RelayState'];
 
+/* We turn processing over to the SingleLogoutService script. */
+SimpleSAML_Utilities::redirect('/' . $config->getBaseURL() . 'saml2/idp/SingleLogoutService.php',
+	array('ReturnTo' => $returnTo));
 
+?>
\ No newline at end of file
-- 
GitLab