From 76a51a1d378ff3f37bc23771d5ad904af3d4d59a Mon Sep 17 00:00:00 2001
From: Olav Morken <olav.morken@uninett.no>
Date: Wed, 27 Jan 2010 09:26:39 +0000
Subject: [PATCH] saml2/idp: Use the new logout processing.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@2140 44740490-163a-0410-bde0-09ae8108e29a
---
 modules/saml/lib/IdP/SAML2.php                | 122 +++++
 templates/logout-iframe.php                   | 239 ----------
 www/saml2/idp/SingleLogoutService.php         | 321 +------------
 www/saml2/idp/SingleLogoutServiceiFrame.php   | 444 +-----------------
 .../SingleLogoutServiceiFrameNoJavascript.php | 102 ----
 .../idp/SingleLogoutServiceiFrameResponse.php |  79 +---
 .../idp/idpInitSingleLogoutServiceiFrame.php  | 276 +----------
 7 files changed, 145 insertions(+), 1438 deletions(-)
 delete mode 100644 templates/logout-iframe.php
 delete mode 100644 www/saml2/idp/SingleLogoutServiceiFrameNoJavascript.php

diff --git a/modules/saml/lib/IdP/SAML2.php b/modules/saml/lib/IdP/SAML2.php
index 746bf94e3..822bdf389 100644
--- a/modules/saml/lib/IdP/SAML2.php
+++ b/modules/saml/lib/IdP/SAML2.php
@@ -314,4 +314,126 @@ class sspmod_saml_IdP_SAML2 {
 		$idp->handleAuthenticationRequest($state);
 	}
 
+
+	/**
+	 * Send a logout response.
+	 *
+	 * @param array &$state  The logout state array.
+	 */
+	public static function sendLogoutResponse(SimpleSAML_IdP $idp, array $state) {
+		assert('isset($state["saml:SPEntityId"])');
+		assert('isset($state["saml:RequestId"])');
+		assert('array_key_exists("saml:RelayState", $state)'); // Can be NULL.
+
+		$spEntityId = $state['saml:SPEntityId'];
+
+		$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+		$idpMetadata = $idp->getConfig();
+		$spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote');
+
+		$lr = sspmod_saml2_Message::buildLogoutResponse($idpMetadata, $spMetadata);
+		$lr->setInResponseTo($state['saml:RequestId']);
+		$lr->setRelayState($state['saml:RelayState']);
+
+		if (isset($state['core:Failed']) && $state['core:Failed']) {
+			$lr->setStatus(array(
+				'Code' => SAML2_Const::STATUS_SUCCESS,
+				'SubCode' => SAML2_Const::STATUS_PARTIAL_LOGOUT,
+			));
+			SimpleSAML_Logger::info('Sending logout response for partial logout to SP ' . var_export($spEntityId, TRUE));
+		} else {
+			SimpleSAML_Logger::debug('Sending logout response to SP ' . var_export($spEntityId, TRUE));
+		}
+
+		$binding = new SAML2_HTTPRedirect();
+		$binding->setDestination(sspmod_SAML2_Message::getDebugDestination());
+		$binding->send($lr);
+	}
+
+
+	/**
+	 * Receive a logout message.
+	 *
+	 * @param SimpleSAML_IdP $idp  The IdP we are receiving it for.
+	 */
+	public static function receiveLogoutMessage(SimpleSAML_IdP $idp) {
+
+		$binding = SAML2_Binding::getCurrentBinding();
+		$message = $binding->receive();
+
+		$spEntityId = $message->getIssuer();
+		if ($spEntityId === NULL) {
+			/* Without an issuer we have no way to respond to the message. */
+			throw new SimpleSAML_Error_BadRequest('Received message on logout endpoint without issuer.');
+		}
+
+		$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+		$idpMetadata = $idp->getConfig();
+		$spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote');
+
+		sspmod_saml2_Message::validateMessage($idpMetadata, $spMetadata, $message);
+
+		if ($message instanceof SAML2_LogoutResponse) {
+
+			$spEntityId = $message->getIssuer();
+			if ($spEntityId === NULL) {
+				throw new SimpleSAML_Error_Exception('Missing <Issuer> in LogoutResponse.');
+			}
+
+			$relayState = $message->getRelayState();
+
+			if (!$message->isSuccess()) {
+				$logoutError = sspmod_saml2_Message::getResponseError($message);
+				SimpleSAML_Logger::warning('Unsuccessful logout. Status was: ' . $logoutError);
+			} else {
+				$logoutError = NULL;
+			}
+
+			$assocId = 'saml:' . $spEntityId;
+
+			$idp->handleLogoutResponse($assocId, $relayState, $logoutError);
+
+
+		} elseif ($message instanceof SAML2_LogoutRequest) {
+
+			$state = array(
+				'Responder' => array('sspmod_saml_IdP_SAML2', 'sendLogoutResponse'),
+				'saml:SPEntityId' => $spEntityId,
+				'saml:RelayState' => $message->getRelayState(),
+				'saml:RequestId' => $message->getId(),
+			);
+
+			$assocId = 'saml:' . $spEntityId;
+			$idp->handleLogoutRequest($state, $assocId);
+
+		} else {
+			throw new SimpleSAML_Error_BadRequest('Unknown message received on logout endpoint: ' . get_class($message));
+		}
+
+	}
+
+
+	/**
+	 * Retrieve a logout URL for a given logout association.
+	 *
+	 * @param SimpleSAML_IdP $idp  The IdP we are sending a logout request from.
+	 * @param array $association  The association that should be terminated.
+	 * @param string|NULL $relayState  An id that should be carried across the logout.
+	 */
+	public static function getLogoutURL(SimpleSAML_IdP $idp, array $association, $relayState) {
+		assert('is_string($relayState) || is_null($relayState)');
+
+		$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+		$idpMetadata = $idp->getConfig();
+		$spMetadata = $metadata->getMetaDataConfig($association['saml:entityID'], 'saml20-sp-remote');
+
+		$lr = sspmod_saml2_Message::buildLogoutRequest($idpMetadata, $spMetadata);
+		$lr->setRelayState($relayState);
+		$lr->setSessionIndex($association['saml:SessionIndex']);
+		$lr->setNameId($association['saml:NameID']);
+
+		$binding = new SAML2_HTTPRedirect();
+		return $binding->getRedirectURL($lr);
+	}
+
 }
diff --git a/templates/logout-iframe.php b/templates/logout-iframe.php
deleted file mode 100644
index 52751f97e..000000000
--- a/templates/logout-iframe.php
+++ /dev/null
@@ -1,239 +0,0 @@
-<?php 
-
-	$iframehtml = '';
-	foreach ($this->data['sparray'] AS $sp) {
-		$iframehtml .= '<iframe class="hiddeniframe" onload="xajax_updateslostatus()" style="border: 1px solid #888; width: 80%; height: 100px" src="' . htmlentities($sp['url']) . '" ></iframe>';
-	}
-#	$iframehtml = str_replace('"', '\"', $iframehtml);
-#	$iframehtml = str_replace("\n", '', $iframehtml);
-#	$iframehtml = str_replace("\r", '', $iframehtml);
-	
-	$this->data['hideLanguageBar'] = TRUE;
-	$this->data['head']  .= '<script type="text/javascript" src="/' . $this->data['baseurlpath'] . 'resources/jquery.js"></script>';
-	$this->data['head']  .= '<link rel="stylesheet" type="text/css" href="/' . $this->data['baseurlpath'] . 'resources/slo.css" />';
-
-	$nologoutSPs = (count($this->data['sparrayNoLogout']) > 0);
-
-	$this->data['head'] .= '
-<script type="text/javascript" language="JavaScript">
-<!--
-
-
-$(document).ready(function() {
-	$("div#requirejavascript").show();
-/*	$("div.completedButWarnings").hide(); */
-	$("div#interrupt").hide();
-	$("input#ok").click(function () { 
-      startslo();
-    });
-	$("input#cancel").click(function () { 
-      sendResponse();
-    });	
-	$("input#returnanyway").click(function () { 
-      sendResponse();
-    });
-	$("input#interruptbutton").click(function () { 
-      sendResponse();
-    });
-    
-    ' . ($nologoutSPs ? '$("#incapablesps").show();' : '$("#incapablesps").hide();') . '
-
-});
-
-function toolong() {
-	$("div#interrupt").show().fadeOut("fast").fadeIn("fast");
-}
-
-/* This function is called when users clicks to start single logout */
-function startslo() {
-	$("#confirmation").hide();
-	$("#hiddeniframecontainer").html("' . str_replace('"', '\"', $iframehtml) . '");
-	$("table#slostatustable tr.onhold").removeClass("onhold").addClass("inprogress");
-/*	$("div.completedButWarnings").show();  */
-' . ($iframehtml === '' ? 'sendResponse();' : '') . '
-	setTimeout("toolong()", 16000);
-}
-
-/* This function is called from the AJAX response with xajax with the hash of the entityid of the SP   */
-function slocompletesp($entityhash) {
-	$("table#slostatustable tr#" + $entityhash).filter(".inprogress").removeClass("inprogress").addClass("completed").
-		children().fadeOut("fast").fadeIn("fast");
-}
-
-
-/* SLO completed for all sps. */
-function slocompleted() {
-/*	$("div.completedButWarnings").show(); */
-	$("div#interrupt").hide();
-        setTimeout("sendResponse()", 2000);
-}
-
-function sendResponse() {
-	window.location = "' .  $this->data['logoutresponse'] . '";
-}
-// -->
-</script>';
-	
-	$this->includeAtTemplateBase('includes/header.php');
-	
-?>
-
-<!-- Proper fallback for browsers that do not support javascript or have javascript turned off -->
-<noscript> 
-	<div id="nojavascriptframe">
-		<iframe style="margin: 1em; width: 90%; height: 5em; border: 1px solid #eee" src="SingleLogoutServiceiFrameNoJavascript.php?response=<?php echo urlencode($this->data['logoutresponse']); ?>"></iframe>			
-	</div>
-<?php
-	foreach ($this->data['sparray'] AS $sp) {
-		echo '<iframe class="hiddeniframe" onload="xajax_updateslostatus()" style="border: 1px solid #888; width: 80%; height: 100px" 
-			src="' . htmlentities($sp['url']) . '" ></iframe>' . "\n";
-	}
-?>
-</noscript>
-
-
-
-
-<div id="requirejavascript" style="display: none">
-
-	<?php
-	#echo('<pre>'); print_r($this->data); exit;
-	if (array_key_exists('requesterName', $this->data)) {
-		$requesterName = is_array($this->data['requesterName']) ? 
-			$this->getTranslation($this->data['requesterName']) : $this->data['requesterName'];
-	}
-	#echo('<p>' . $this->t('{logout:description}', array('%REQUESTERNAME%' => $requestername)) . '</p>');
-	
-	?>
-
-	<!-- <div class="loggedout"><?php echo($this->t('{logout:logged_out}', array('%REQUESTERNAME%' => $requestername))); ?></div> -->
-
-	<?php
-	
-		if (array_key_exists('requesterName', $this->data)) {
-			echo('<div><img style="float: left; margin-right: 12px" src="/' . $this->data['baseurlpath'] . 'resources/icons/checkmark48.png" alt="Successful logout" />');
-			echo('<p style="padding-top: 16px; ">' . $this->t('{logout:loggedoutfrom}', array('%SP%' => '<strong>' .$requesterName.'</strong>')) . '</p>');
-			echo('<p style="height: 0px; clear: left;"></p>');
-			echo('</div>');
-		}
-
-		echo('<div style="margin-top: 3em; clear: both">');
-		echo('<p style="margin-bottom: .5em">' . $this->t('{logout:also_from}') . '</p>');
-		
-		echo '<table id="slostatustable">';
-
-/** Remove initiated from. showed above instead
-		
-		echo '<tr class="initiated" id="e_initiated">' . "\n";
-		echo '	<td><img style="float: left; margin: 3px" src="/' . $this->data['baseurlpath'] . 
-			'resources/icons/silk/accept.png" alt="Initiated from" /></td>' . "\n";
-		echo '	<td>' . $this->t('{logout:initiated}') . '</td>';
-		echo '	<td>' . $requesterName . '</td>' ."\n";
-		echo '</tr>' . "\n";
-		
-		*/
-
-
-		foreach ($this->data['sparrayNoLogout'] AS $spentityid => $sp) {
-			$spname = is_array($sp['name']) ? $this->getTranslation($sp['name']) : $sp['name'];
-			echo '<tr class="initiated" id="e' . sha1($spentityid) . '">' . "\n";
-			echo '	<td class="statustext">Logout not supported</td>';
-			echo '	<td ><img style="" src="/' . $this->data['baseurlpath'] . 
-				'resources/icons/silk/delete.png" alt="Initiated from" /></td>' . "\n";
-
-			echo '	<td>' . $spname . '</td>' ."\n";
-			echo '</tr>' . "\n";
-		}
-
-		
-		foreach ($this->data['sparray'] AS $spentityid => $sp) {
-			$spname = is_array($sp['name']) ? $this->getTranslation($sp['name']) : $sp['name'];
-			
-			echo '<tr class="ready onhold" id="e' . sha1($spentityid) . '">' . "\n";
-
-			echo '	<td class="statustext">';
-			echo '		<span class="completed">' . $this->t('{logout:completed}') . '</span>' . "\n";
-#			echo '		<span class="onhold">' . $this->t('{logout:hold}') . '</span>' . "\n";
-#			echo '		<span class="onhold"></span>' . "\n";
-			echo '		<span class="inprogress">' . $this->t('{logout:progress}') . '</span>' . "\n";
-			echo '		<span class="failed">' . $this->t('{logout:failed}') . '</span>' . "\n";
-			echo '	</td>';
-
-			echo '	<td class="icons">';
-			echo '		<img class="completed"  src="/' . $this->data['baseurlpath'] . 'resources/icons/silk/accept.png" alt="Completed" />' . "\n";
-			echo '		<img class="onhold"     src="/' . $this->data['baseurlpath'] . 'resources/icons/bullet16_grey.png" alt="SP SLO on hold" />' . "\n";
-			echo '		<img class="inprogress" src="/' . $this->data['baseurlpath'] . 'resources/progress.gif" alt="Progress bar" />' . "\n";
-			echo '		<img class="failed"     src="/' . $this->data['baseurlpath'] . 'resources/icons/silk/exclamation.png" alt="Failed" />' . "\n";
-			echo '	</td>' . "\n";
-			
-
-			
-			echo '	<td>' . $spname . '</td>' ."\n";
-			
-			echo '</tr>' . "\n";
-			
-// 			echo '<div class="inprogress" id="e' . sha1($spentityid) . '">
-// 				<img style="float: left; margin: 3px" src="/' . $this->data['baseurlpath'] . 'resources/progress.gif" alt="Progress bar" />Wait... is logging out from <strong>' . $spname . '</strong></div>'  . "\n";
-		}
-		echo '</table></div>';
-
-		$completed = ' class="allcompleted"';
-		if (count($this->data['sparray']) > 0) {
-			$completed = '';
-		}
-	
-
-	?>
-
-	<div id="confirmation" style="margin-top: 1em" >
-		<p>
-			<?php echo $this->t('{logout:logout_all_question}'); ?> <br />
-		</p>
-		<input type="button" id="ok" name="ok" value="<?php echo $this->t('{logout:logout_all}'); ?>" />
-		<?php
-			
-			if (array_key_exists('requesterName', $this->data)) {
-				echo '<input type="button" id="cancel" name="cancel" value="' . $this->t('{logout:logout_only}', array('%SP%' => $requesterName)) . '" />';
-			} else {
-				echo '<input type="button" id="cancel" name="cancel" value="' . $this->t('{logout:no}') . '" />';
-			}
-			
-		?>
-		
-		
-
-		<p id="incapablesps" >
-			<?php echo($this->t('{logout:incapablesps}')); ?>
-		</p>
-		
-		
-	</div>
-	
-
-	
-	
-	
-	<div id="interrupt" style="margin-top: 1em; border: 1px solid #ccc; padding: 1em; background: #eaeaea" >
-		<p style="margin: 0px; padding; 0px">
-			<img src="/<?php echo($this->data['baseurlpath']); ?>resources/icons/timeout.png" 
-				alt="Timeout"
-				style="float: left; margin: 0px 5px 0px 0px"
-				/>
-			<?php echo $this->t('{logout:respond_info}'); ?> <br />
-			<input type="button" id="interruptbutton" name="interrupt" value="<?php echo $this->t('{logout:return}'); ?>" />
-		</p>
-	</div>
-	
-
-	<div id="hiddeniframecontainer" style="margin: 0px; padding: 0px;"></div>
-
-
-</div> <!-- requirejavascript -->
-
-<!--
-<script type="text/javascript" language="JavaScript">
-	showdiv('requirejavascript');
-</script>
--->
-
-<?php $this->includeAtTemplateBase('includes/footer.php'); ?>
diff --git a/www/saml2/idp/SingleLogoutService.php b/www/saml2/idp/SingleLogoutService.php
index 6a9abe1e6..618068cd8 100644
--- a/www/saml2/idp/SingleLogoutService.php
+++ b/www/saml2/idp/SingleLogoutService.php
@@ -9,324 +9,17 @@
  * @version $Id$
  */
 
-// TODO: Show error message, when shibboleth sp is logged in.
-
 require_once('../../_include.php');
 
-$config = SimpleSAML_Configuration::getInstance();
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-$session = SimpleSAML_Session::getInstance();
-
 SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: Accessing SAML 2.0 IdP endpoint SingleLogoutService');
 
-if (!$config->getBoolean('enable.saml20-idp', false))
-	SimpleSAML_Utilities::fatalError(isset($session) ? $session->getTrackID() : null, 'NOACCESS');
-
-try {
-	$idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
-	$idpMetadata = $metadata->getMetaDataConfig($idpEntityId, 'saml20-idp-hosted');
-} catch (Exception $exception) {
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'METADATA', $exception);
-}
-
-SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: Got IdP entity id: ' . $idpEntityId);
-
-
-$logouttype = $idpMetadata->getString('logouttype', 'traditional');
-if ($logouttype !== 'traditional') 
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NOACCESS', new Exception('This IdP is configured to use logout type [' . $logouttype . '], but this endpoint is only available for IdP using logout type [traditional]'));
-
-
-
-
-/**
- * The $logoutInfo contains information about the current logout operation.
- * It can have the following attributes:
- * - 'RelayState' - The RelayState which should be returned to the SP which initiated the logout operation.
- * - 'Issuer' - The entity id of the SP which initiated the logout operation.
- * - 'RequestID' - The id of the LogoutRequest which initiated the logout operation.
- */
-$logoutInfo = array();
-
-
-/**
- * This function retrieves the logout info with the given ID.
- *
- * @param $id  The identifier of the logout info.
- */
-function fetchLogoutInfo($id) {
-	global $session;
-	global $logoutInfo;
-
-	$logoutInfo = $session->getData('idplogoutresponsedata', $id);
-
-	if($logoutInfo === NULL) {
-		SimpleSAML_Logger::warning('SAML2.0 - IdP.SingleLogoutService: Lost logout information.');
-	}
-}
-
-
-/**
- * This function saves the logout info with the given ID.
- *
- * @param $id  The identifier the logout info should be saved with.
- */
-function saveLogoutInfo($id) {
-	global $session;
-	global $logoutInfo;
-
-	$session->setData('idplogoutresponsedata', $id, $logoutInfo);
-}
-
-
-/**
- * If we get an incoming 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($_REQUEST['SAMLRequest'])) {
-
-	SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: Got SAML reuqest');
-
-	$binding = SAML2_Binding::getCurrentBinding();
-
-	try {
-		$logoutRequest = $binding->receive();
-		if (!($logoutRequest instanceof SAML2_LogoutRequest)) {
-			throw new Exception('Received a request which wasn\'t a LogoutRequest ' .
-				'on logout endpoint. Was: ' . get_class($logoutRequest));
-		}
-
-		$spEntityId = $logoutRequest->getIssuer();
-		if ($spEntityId === NULL) {
-			throw new Exception('Missing issuer in logout reqeust.');
-		}
-
-		$spMetadata = $metadata->getMetadataConfig($spEntityId, 'saml20-sp-remote');
-
-		sspmod_saml2_Message::validateMessage($spMetadata, $idpMetadata, $logoutRequest);
-
-	} catch(Exception $exception) {
-		SimpleSAML_Utilities::fatalError($session->getTrackID(), 'LOGOUTREQUEST', $exception);
-	}
-
-	SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: got Logoutrequest from ' . $spEntityId);
-	SimpleSAML_Logger::stats('saml20-idp-SLO spinit ' . $spEntityId . ' ' . $idpEntityId);
-
-	/* Fill in the $logoutInfo associative array with information about this logout request. */
-	$logoutInfo['Issuer'] = $spEntityId;
-	$logoutInfo['RequestID'] = $logoutRequest->getId();
-
-	$logoutInfo['RelayState'] = $logoutRequest->getRelayState();
-
-	SimpleSAML_Logger::debug('SAML2.0 - IDP.SingleLogoutService: Setting cached request with issuer ' . $spEntityId);
-
-	$session->set_sp_logout_completed($spEntityId);
-
-
-	/*
-	 * We receive a Logout Response to a Logout Request that we have issued earlier.
-	 */
-} elseif (isset($_REQUEST['SAMLResponse'])) {
-
-	SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: Got SAML response');
-
-	$binding = SAML2_Binding::getCurrentBinding();
-
-	try {
-		$logoutResponse = $binding->receive();
-		if (!($logoutResponse instanceof SAML2_LogoutResponse)) {
-			throw new Exception('Received a response which wasn\'t a LogoutResponse ' .
-				'on logout endpoint. Was: ' . get_class($logoutResponse));
-		}
-
-		$spEntityId = $logoutResponse->getIssuer();
-		if ($spEntityId === NULL) {
-			throw new Exception('Missing issuer in logout response.');
-		}
-
-		SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: SAML response parsed. Issuer is: ' . $spEntityId);
-		$spMetadata = $metadata->getMetadataConfig($spEntityId, 'saml20-sp-remote');
-
-		sspmod_saml2_Message::validateMessage($spMetadata, $idpMetadata, $logoutResponse);
-
-	} catch(Exception $exception) {
-		SimpleSAML_Utilities::fatalError($session->getTrackID(), 'LOGOUTRESPONSE', $exception);
-	}
-
-	/* Fetch the $logoutInfo variable based on the InResponseTo attribute of the response. */
-	fetchLogoutInfo($logoutResponse->getInResponseTo());
-
-	$session->set_sp_logout_completed($spEntityId);
-
-	SimpleSAML_Logger::info('SAML2.0 - IDP.SingleLogoutService: got LogoutResponse from ' . $spEntityId);
-
-} elseif(array_key_exists('LogoutID', $_GET)) {
-	/* This is a response from bridged SLO. */
-	SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: Got response from bridged SLO.');
-
-	/* 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'];
+$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
+$idp = SimpleSAML_IdP::getById('saml2:' . $idpEntityId);
 
+if (isset($_REQUEST['ReturnTo'])) {
+	$idp->doLogoutRedirect((string)$_REQUEST['ReturnTo']);
 } else {
-	/*
-	 * We have no idea what to do here. It is neither a logout request, a logout
-	 * response nor a response from bridged SLO.
-	 */
-	SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: No request, response or bridge');
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'SLOSERVICEPARAMS');
-}
-
-/* First, log out of the current authentication source. */
-$authority = $session->getAuthority();
-if ($authority !== NULL) {
-	/* We are logged in. */
-
-	$bridgedId = SimpleSAML_Utilities::generateID();
-	$returnTo = SimpleSAML_Utilities::selfURLNoQuery() . '?LogoutID=' . $bridgedId;
-
-	/* Save the $logoutInfo until we return from the SP. */
-	saveLogoutInfo($bridgedId);
-
-	if ($authority === $idpMetadata->getString('auth')) {
-		/* This is probably an authentication source. */
-		SimpleSAML_Auth_Default::initLogoutReturn($returnTo);
-	} elseif ($authority === 'saml2') {
-		/* SAML 2 SP which isn't an authentication source. */
-		SimpleSAML_Utilities::redirect('/' . $config->getBaseURL() . 'saml2/sp/initSLO.php',
-			array('RelayState' => $returnTo)
-		);
-	} else {
-		/* A different old-style authentication file. */
-		$session->doLogout();
-	}
-}
-
-
-/*
- * Find the next SP we should log out from. We will search through the list of
- * SPs until we find a valid SP with a SingleLogoutService endpoint.
- */
-while (TRUE) {
-	/* 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)) {
-		break;
-	}
-
-	try {
-		$spMetadata = $metadata->getMetadataConfig($spEntityId, 'saml20-sp-remote');
-	} catch (Exception $e) {
-		/* It seems that an SP has disappeared from the metadata between login and logout. */
-		SimpleSAML_Logger::info('SAML2.0 - IDP.SingleLogoutService: Missing metadata for ' .
-			$spEntityId . '; looking for more SPs.');
-		continue;
-	}
-
-	$singleLogoutService = $spMetadata->getDefaultEndpoint('SingleLogoutService', array(SAML2_Const::BINDING_HTTP_REDIRECT), NULL);
-	if ($singleLogoutService === NULL) {
-		SimpleSAML_Logger::info('SAML2.0 - IDP.SingleLogoutService: No supported SingleLogoutService for ' .
-			$spEntityId . '; looking for more SPs.');
-		continue;
-	}
-
-	/* $spEntityId now contains the next SP. */
-	break;
-}
-
-
-if ($spEntityId) {
-
-	SimpleSAML_Logger::info('SAML2.0 - IDP.SingleLogoutService: Logout next SP ' . $spEntityId);
-
-	try {
-
-		$nameId = $session->getSessionNameId('saml20-sp-remote', $spEntityId);
-		if($nameId === NULL) {
-			$nameId = $session->getNameID();
-		}
-
-		$lr = sspmod_saml2_Message::buildLogoutRequest($idpMetadata, $spMetadata);
-		$lr->setSessionIndex($session->getSessionIndex());
-		$lr->setNameId($nameId);
-
-		/* Save the $logoutInfo until we return from the SP. */
-		saveLogoutInfo($lr->getId());
-
-		$binding = new SAML2_HTTPRedirect();
-		$binding->setDestination(sspmod_SAML2_Message::getDebugDestination());
-		$binding->send($lr);
-
-	} catch(Exception $exception) {
-		SimpleSAML_Utilities::fatalError($session->getTrackID(), 'GENERATELOGOUTREQUEST', $exception);
-	}
-}
-
-if ($config->getBoolean('debug', false))
-	SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: LogoutService: All SPs done ');
-
-
-
-/*
- * Logout procedure is done and we send a Logout Response back to the SP
- */
-
-try {
-
-	if(!$logoutInfo) {
-		SimpleSAML_Utilities::fatalError($session->getTrackID(), 'LOGOUTINFOLOST');
-	}
-
-	SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: Found logout info with these keys: ' . join(',', array_keys($logoutInfo)));
-
-	/**
-	 * Clean up session object to save storage.
-	 */
-	if ($config->getBoolean('debug', false))
-		SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: Session Size before cleaning: ' . $session->getSize());
-
-	$session->clean();
-
-	if ($config->getBoolean('debug', false))
-		SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: Session Size after cleaning: ' . $session->getSize());
-
-
-	/*
-	 * Check if the Single Logout procedure is initated by an SP (alternatively IdP initiated SLO
-	 */
-	if (array_key_exists('Issuer', $logoutInfo)) {
-
-		$spEntityId = $logoutInfo['Issuer'];
-		$spMetadata = $metadata->getMetadataConfig($spEntityId, 'saml20-sp-remote');
-
-		$lr = sspmod_saml2_Message::buildLogoutResponse($idpMetadata, $spMetadata);
-		$lr->setInResponseTo($logoutInfo['RequestID']);
-		$lr->setRelayState($logoutInfo['RelayState']);
-		$binding = new SAML2_HTTPRedirect();
-		$binding->setDestination(sspmod_SAML2_Message::getDebugDestination());
-		$binding->send($lr);
-
-	} elseif (array_key_exists('RelayState', $logoutInfo)) {
-
-		SimpleSAML_Utilities::redirect($logoutInfo['RelayState']);
-		exit;
-
-	} else {
-		echo 'You are logged out'; exit;
-	}
-
-} catch(Exception $exception) {
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'GENERATELOGOUTRESPONSE', $exception);
+	sspmod_saml_IdP_SAML2::receiveLogoutMessage($idp);
 }
+assert('FALSE');
diff --git a/www/saml2/idp/SingleLogoutServiceiFrame.php b/www/saml2/idp/SingleLogoutServiceiFrame.php
index 85a6f40c6..1e06782c2 100644
--- a/www/saml2/idp/SingleLogoutServiceiFrame.php
+++ b/www/saml2/idp/SingleLogoutServiceiFrame.php
@@ -11,444 +11,10 @@
 
 require_once('../../_include.php');
 
-$config = SimpleSAML_Configuration::getInstance();
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-$session = SimpleSAML_Session::getInstance();
-
 SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutServiceiFrame: Accessing SAML 2.0 IdP endpoint SingleLogoutService (iFrame version)');
 
-SimpleSAML_Logger::debug('Initially; ' . join(',', $session->get_sp_list(SimpleSAML_Session::STATE_ONLINE)));
-
-if (!$config->getBoolean('enable.saml20-idp', false))
-	SimpleSAML_Utilities::fatalError(isset($session) ? $session->getTrackID() : null, 'NOACCESS');
-
-try {
-	$idpentityid = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
-	$idpMetadata = $metadata->getMetaDataConfig($idpentityid, 'saml20-idp-hosted');
-} catch (Exception $exception) {
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'METADATA', $exception);
-}
-
-SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame: Got IdP entity id: ' . $idpentityid);
-
-
-
-$logouttype = 'traditional';
-$idpmeta = $metadata->getMetaDataCurrent('saml20-idp-hosted');
-if (array_key_exists('logouttype', $idpmeta)) $logouttype = $idpmeta['logouttype'];
-
-if ($logouttype !== 'iframe') 
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NOACCESS', new Exception('This IdP is configured to use logout type [' . $logouttype . '], but this endpoint is only available for IdP using logout type [iframe]'));
-
-
-
-/**
- * The $logoutInfo contains information about the current logout operation.
- * It can have the following attributes:
- * - 'RelayState' - The RelayState which should be returned to the SP which initiated the logout operation.
- * - 'Issuer' - The entity id of the SP which initiated the logout operation.
- * - 'RequestID' - The id of the LogoutRequest which initiated the logout operation.
- */
-$logoutInfo = array();
-
-
-/**
- * This function retrieves the logout info with the given ID.
- *
- * @param $id  The identifier of the logout info.
- */
-function fetchLogoutInfo($id) {
-	global $session;
-	global $logoutInfo;
-
-	$logoutInfo = $session->getData('idplogoutresponsedata', $id);
-
-	if($logoutInfo === NULL) {
-		SimpleSAML_Logger::warning('SAML2.0 - IdP.SingleLogoutService: Lost logout information.');
-	}
-}
-
-
-/**
- * This function saves the logout info with the given ID.
- *
- * @param $id  The identifier the logout info should be saved with.
- */
-function saveLogoutInfo($id) {
-	global $session;
-	global $logoutInfo;
-
-	$session->setData('idplogoutresponsedata', $id, $logoutInfo);
-}
-
-
-// Include XAJAX definition.
-require_once(SimpleSAML_Utilities::resolvePath('libextinc') . '/xajax/xajax.inc.php');
-
-
-
-/*
- * This function is called via AJAX and will send LogoutRequest to one single SP by
- * sending a LogoutRequest using HTTP-REDIRECT
- */
-function updateslostatus() {
-
-	SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutServiceiFrame: Accessing SAML 2.0 IdP endpoint SingleLogoutService (iFrame version) within updateslostatus() ');
-
-	$config = SimpleSAML_Configuration::getInstance();
-	$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-	$session = SimpleSAML_Session::getInstance();
-
-	$idpentityid = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
-	
-	$templistofsps = $session->get_sp_list(SimpleSAML_Session::STATE_ONLINE);
-	$listofsps = array();
-	foreach ($templistofsps AS $spentityid) {
-		if (!empty($_COOKIE['spstate-' . sha1($spentityid)])) {
-			$listofsps[] = $spentityid;
-			continue;
-		}
-
-		try {
-			$spMetadata = $metadata->getMetaDataConfig($spentityid, 'saml20-sp-remote');
-		} catch (Exception $e) {
-			/*
-			 * For some reason, the metadata for this SP is no longer available. Most
-			 * likely it was deleted from the IdP while the user had a session to it.
-			 * In any case - skip this SP.
-			 */
-			$listofsps[] = $spentityid;
-			continue;
-		}
-
-		$singleLogoutService = $spMetadata->getDefaultEndpoint('SingleLogoutService', array(SAML2_Const::BINDING_HTTP_REDIRECT), NULL);
-		if ($singleLogoutService === NULL) {
-			/* No logout endpoint. */
-			$listofsps[] = $spentityid;
-			continue;
-		}
-
-		/* This SP isn't ready yet. */
-	}
-	SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame: templistofsps ' . join(',', $templistofsps));
-	SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame:     listofsps ' . join(',', $listofsps));
-
-
-	// Using template object to be able to translate name of service provider.
-	$t = new SimpleSAML_XHTML_Template($config, 'logout-iframe.php');
-
-    // Instantiate the xajaxResponse object
-    $objResponse = new xajaxResponse();
-
-	foreach ($listofsps AS $spentityid) {
-
-		SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame: Completed ' . $spentityid);
-		
-		// add a command to the response to assign the innerHTML attribute of
-		// the element with id="SomeElementId" to whatever the new content is
-		
-		try {
-			$spmetadata = $metadata->getMetaData($spentityid, 'saml20-sp-remote');
-		} catch (Exception $e) {
-			/*
-			 * For some reason, the metadata for this SP is no longer available. Most
-			 * likely it was deleted from the IdP while the user had a session to it.
-			 * In any case - skip this SP.
-			 */
-			continue;
-		}
-
-		$name = array_key_exists('name', $spmetadata) ? $spmetadata['name'] : $spentityid;
-		
-		$spname = is_array($name) ? $t->getTranslation($name) : $name;
-		
-		$objResponse->addScriptCall('slocompletesp', 'e' . sha1($spentityid));
-
-	}
-	
-	if (count($templistofsps) === count($listofsps)) {
-
-		$templistofsps = $session->get_sp_list(SimpleSAML_Session::STATE_ONLINE);
-		foreach ($templistofsps AS $spentityid) {
-			$session->set_sp_logout_completed($spentityid);
-			setcookie('spstate-' . sha1($spentityid) , '', time() - 3600); // Delete cookie
-		}
-
-		$objResponse->addScriptCall('slocompleted');
-
-		/**
-		 * Clean up session object to save storage.
-		 */
-		if ($config->getBoolean('debug', false))
-			SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: Session Size before cleaning: ' . $session->getSize());
-			
-		$session->clean();
-		
-		if ($config->getBoolean('debug', false))
-			SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: Session Size after cleaning: ' . $session->getSize());
-
-	} else {
-		SimpleSAML_Logger::debug('SAML2.0 - sp_logout_completed FALSE');
-	}
-    
-    //return the  xajaxResponse object
-    return $objResponse;
-}
-
-
-
-$xajax = new xajax();
-$xajax->registerFunction("updateslostatus");
-$xajax->processRequests();
-
-
-
-
-
-/*
- * If we get an LogoutRequest then we initiate the logout process.
- */
-if (isset($_REQUEST['SAMLRequest'])) {
-
-	SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: Got SAML reuqest');
-
-	$binding = SAML2_Binding::getCurrentBinding();
-
-	try {
-		$logoutrequest = $binding->receive();
-		if (!($logoutrequest instanceof SAML2_LogoutRequest)) {
-			throw new Exception('Not a valid logout request.');
-		}
-
-		$spEntityId = $logoutrequest->getIssuer();
-		if ($spEntityId === NULL) {
-			throw new Exception('Missing issuer in logout request.');
-		}
-
-		$spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote');
-
-		sspmod_saml2_Message::validateMessage($spMetadata, $idpMetadata, $logoutrequest);
-
-	} catch(Exception $exception) {
-		SimpleSAML_Utilities::fatalError($session->getTrackID(), 'LOGOUTREQUEST', $exception);
-	}
-
-	/* Log a warning if the NameID in the LogoutRequest isn't the one we assigned to the SP. */
-	$requestNameId = $logoutrequest->getNameId();
-	ksort($requestNameId);
-	$sessionNameId = $session->getSessionNameId('saml20-sp-remote', $spEntityId);
-	ksort($sessionNameId);
-	if ($sessionNameId !== NULL && $requestNameId !== $sessionNameId) {
-		SimpleSAML_Logger::warning('Wrong NameID in LogoutRequest from ' .
-			var_export($spEntityId, TRUE) . '.');
-	}
-
-	/* Log a warning if the SessionIndex in the LogoutRequest isn't correct. */
-	$requestSessionIndex = $logoutrequest->getSessionIndex();
-	$sessionSessionIndex = $session->getSessionIndex();
-	if ($requestSessionIndex !== $sessionSessionIndex) {
-		SimpleSAML_Logger::warning('Wrong SessionIndex in LogoutRequest from ' .
-			var_export($spEntityId, TRUE) . '.');
-	}
-
-
-	// Extract some parameters from the logout request
-	#$requestid = $logoutrequest->getRequestID();
-	$requester = $logoutrequest->getIssuer();
-	#$relayState = $logoutrequest->getRelayState();
-	$responder = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
-	
-	SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: got Logoutrequest from ' . $logoutrequest->getIssuer());
-	SimpleSAML_Logger::stats('saml20-idp-SLO spinit ' . $requester . ' ' . $responder);
-	
-
-	$session->doLogout();
-
-
-	/* Fill in the $logoutInfo associative array with information about this logout request. */
-	$logoutInfo['Issuer'] = $logoutrequest->getIssuer();
-	$logoutInfo['RequestID'] = $logoutrequest->getId();
-
-	$relayState = $logoutrequest->getRelayState();
-	if($relayState !== NULL) {
-		$logoutInfo['RelayState'] = $relayState;
-	}
-		
-	SimpleSAML_Logger::debug('SAML2.0 - IDP.SingleLogoutService: Setting cached request with issuer ' . $logoutrequest->getIssuer());
-	
-	$session->set_sp_logout_completed($logoutrequest->getIssuer());
-
-
-/*
- * We receive a Logout Response to a Logout Request that we have issued earlier.
- * If so, there is a misconfiguration.
- */
-} elseif (isset($_REQUEST['SAMLResponse'])) {
-
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'LOGOUTRESPONSE', 
-		new Exception('The SP is likely to be misconfigured. The LogoutResponse is sent to wrong endpoint. This iFrame endpoint only accepts LogoutRequests, and the response is to be sent to a separate endpoint. Please revisit the IdP-Remote metadata on the SP.')
-	);
-
-} else {
-	/*
-	 * We have no idea what to do here. It is neither a logout request, a logout
-	 * response nor a response from bridged SLO.
-	 */
-	SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: No request, response or bridge');
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'SLOSERVICEPARAMS');
-}
-
-
-// Debug entries in the log about what services the user is logged into.
-$session->dump_sp_sessions();
-
-
-
-/*
- * Generate a list of all service providers, and create a LogoutRequest message for all these SPs.
- */
-$listofsps = $session->get_sp_list();
-$sparray = array();
-$sparrayNoLogout = array();
-foreach ($listofsps AS $spentityid) {
-
-	// ($issuer, $receiver, $nameid, $nameidformat, $sessionindex, $mode) {
-	$nameId = $session->getSessionNameId('saml20-sp-remote', $spentityid);
-	if($nameId === NULL) {
-		$nameId = $session->getNameID();
-	}
-
-	try {
-		$spMetadata = $metadata->getMetaDataConfig($spentityid, 'saml20-sp-remote');
-	} catch (Exception $e) {
-		/*
-		 * For some reason, the metadata for this SP is no longer available. Most
-		 * likely it was deleted from the IdP while the user had a session to it.
-		 * In any case - skip this SP.
-		 */
-		continue;
-	}
-
-	$name = $spMetadata->getValue('name', $spentityid);
-
-	try {
-		$lr = sspmod_saml2_Message::buildLogoutRequest($idpMetadata, $spMetadata);
-		$lr->setSessionIndex($session->getSessionIndex());
-		$lr->setNameId($nameId);
-
-		$httpredirect = new SAML2_HTTPRedirect();
-		$url = $httpredirect->getRedirectURL($lr);
-
-		$sparray[$spentityid] = array('url' => $url, 'name' => $name);
-
-		/* Add the SP logout request information to the session so that we can check it later. */
-		$requestInfo = array(
-			'ID' => $lr->getId(),
-			'RelayState' => $lr->getRelayState(),
-		);
-		$session->setData('slo-request-info', $spentityid, $requestInfo, 15*60);
-
-	} catch (Exception $e) {
-		$sparrayNoLogout[$spentityid] = array('name' => $name);
-	}
-
-}
-
-
-SimpleSAML_Logger::debug('SAML2.0 - SP Counter. other SPs with SLO support (' . count($sparray) . ')  without SLO support (' . count($sparrayNoLogout) . ')');
-
-
-#print_r($sparray);
-
-
-
-
-
-
-/*
- * Logout procedure is done and we send a Logout Response back to the SP
- */
-
-try {
-
-	if(!$logoutInfo) SimpleSAML_Utilities::fatalError($session->getTrackID(), 'LOGOUTINFOLOST');
-	SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: Found logout info with these keys: ' . join(',', array_keys($logoutInfo)));
-	
-	/*
-	 * Check if the Single Logout procedure is initated by an SP (alternatively IdP initiated SLO)
-	 */
-	if (array_key_exists('Issuer', $logoutInfo)) {
-
-		$spMetadata = $metadata->getMetaDataConfig($logoutInfo['Issuer'], 'saml20-sp-remote');
-
-		// Find the relaystate if cached.
-		$relayState = isset($logoutInfo['RelayState']) ? $logoutInfo['RelayState'] : null;
-
-		/* Create a Logout Response. */
-		$rg = sspmod_saml2_Message::buildLogoutResponse($idpMetadata, $spMetadata);
-		$rg->setInResponseTo($logoutInfo['RequestID']);
-		$rg->setRelayState($relayState);
-
-		$httpredirect = new SAML2_HTTPRedirect();
-
-		/*
-		 * If the user is not logged into any other SPs, send the LogoutResponse immediately
-		 */
-		if (count($sparray) + count($sparrayNoLogout) === 0) {
-			$httpredirect->setDestination(sspmod_SAML2_Message::getDebugDestination());
-			$httpredirect->send($rg);
-		} else {
-			$logoutresponse = $httpredirect->getRedirectURL($rg);
-		}
-
-		
-	} elseif (array_key_exists('RelayState', $logoutInfo)) {
-
-		SimpleSAML_Utilities::redirect($logoutInfo['RelayState']);
-		exit;
-		
-	} else {
-	
-		echo 'You are logged out'; exit;
-	
-	}
-
-} catch(Exception $exception) {
-	
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'GENERATELOGOUTRESPONSE', $exception);
-	
-}
-
-
-
-
-$spmeta = $metadata->getMetaData($requester, 'saml20-sp-remote');
-$spname = $requester;
-if (array_key_exists('name', $spmeta)) $spname = $spmeta['name'];
-
-
-
-
-
-
-
-$et = new SimpleSAML_XHTML_Template($config, 'logout-iframe.php');
-
-$et->data['header'] = 'Logout';
-$et->data['sparray'] = $sparray;
-$et->data['sparrayNoLogout'] = $sparrayNoLogout;
-
-$et->data['logoutresponse'] = $logoutresponse;
-$et->data['xajax'] = $xajax;
-$et->data['requesterName'] = $spname;
-
-$et->data['head'] = $xajax->getJavascript();
-
-$et->show();
-
-exit(0);
-
-
-
-
-?>
\ No newline at end of file
+$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
+$idp = SimpleSAML_IdP::getById('saml2:' . $idpEntityId);
+sspmod_saml_IdP_SAML2::receiveLogoutMessage($idp);
+assert('FALSE');
diff --git a/www/saml2/idp/SingleLogoutServiceiFrameNoJavascript.php b/www/saml2/idp/SingleLogoutServiceiFrameNoJavascript.php
deleted file mode 100644
index c5a96ea3a..000000000
--- a/www/saml2/idp/SingleLogoutServiceiFrameNoJavascript.php
+++ /dev/null
@@ -1,102 +0,0 @@
-<?php
-
-/**
- * This SAML 2.0 endpoint can receive incoming LogoutRequests. It will also send LogoutResponses, 
- * and LogoutRequests and also receive LogoutResponses. It is implemeting SLO at the SAML 2.0 IdP.
- *
- * @author Andreas Ã…kre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
- * @package simpleSAMLphp
- * @version $Id$
- */
-
-require_once('../../_include.php');
-
-$config = SimpleSAML_Configuration::getInstance();
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-$session = SimpleSAML_Session::getInstance();
-
-SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutServiceiFrame: Accessing SAML 2.0 IdP endpoint SingleLogoutService (iFrame version)');
-
-if (!$config->getBoolean('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);
-}
-
-SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame: Got IdP entity id: ' . $idpentityid);
-
-
-
-$logouttype = 'traditional';
-$idpmeta = $metadata->getMetaDataCurrent('saml20-idp-hosted');
-if (array_key_exists('logouttype', $idpmeta)) $logouttype = $idpmeta['logouttype'];
-
-if ($logouttype !== 'iframe') 
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NOACCESS', new Exception('This IdP is configured to use logout type [' . $logouttype . '], but this endpoint is only available for IdP using logout type [iframe]'));
-
-
-
-SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutServiceiFrameNoJavascript: Accessing SAML 2.0 IdP endpoint SingleLogoutService (iFrame version without javascript support) ');
-
-$config = SimpleSAML_Configuration::getInstance();
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-$session = SimpleSAML_Session::getInstance();
-
-$idpentityid = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
-
-
-
-$templistofsps = $session->get_sp_list(SimpleSAML_Session::STATE_ONLINE);
-$listofsps = array();
-foreach ($templistofsps AS $spentityid) {
-	if (!empty($_COOKIE['spstate-' . sha1($spentityid)])) $listofsps[] = $spentityid;
-}
-
-
-if (count($templistofsps) === count($listofsps)) {
-
-	$templistofsps = $session->get_sp_list(SimpleSAML_Session::STATE_ONLINE);
-	foreach ($templistofsps AS $spentityid) {
-		$session->set_sp_logout_completed($spentityid);
-		setcookie('spstate-' . sha1($spentityid) , '', time() - 3600); // Delete cookie
-	}
-
-
-	echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
-	<title>Logout Update notificator for Non-Javascript Single Log-Out</title>
-</head>
-<body>
-	<p>You are successfully logged out. [ <a target="_top" href="' . htmlentities($_REQUEST['response']) . '">Continue</a> ]</p>
-</body>
-</html>
-';
-
-
-
-} else {
-	echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
-	<meta http-equiv="refresh" content="3;url=SingleLogoutServiceiFrameNoJavascript.php?response=' . urlencode($_REQUEST['response']) . '" />
-	<title>Logout Update notificator for Non-Javascript Single Log-Out</title>
-</head>
-<body>
-	<p>
-	<img style="float: left; margin: 3px" src="/' . $config->getBaseURL() . 'resources/progress.gif" alt="Progress bar" />
-	Logout in progress. [ <a target="_top" href="' . htmlentities($_REQUEST['response']) . '">Interrupt</a> ]</p>
-</body>
-</html>
-';
-}
-
-
-?>
\ No newline at end of file
diff --git a/www/saml2/idp/SingleLogoutServiceiFrameResponse.php b/www/saml2/idp/SingleLogoutServiceiFrameResponse.php
index dddd1b8a1..de95805e9 100644
--- a/www/saml2/idp/SingleLogoutServiceiFrameResponse.php
+++ b/www/saml2/idp/SingleLogoutServiceiFrameResponse.php
@@ -11,79 +11,10 @@
 
 require_once('../../_include.php');
 
-$config = SimpleSAML_Configuration::getInstance();
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-$session = SimpleSAML_Session::getInstance();
-
 SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutServiceiFrameResponse: Accessing SAML 2.0 IdP endpoint SingleLogoutServiceResponse (iFrame version)');
 
-if (!$config->getBoolean('enable.saml20-idp', false))
-	SimpleSAML_Utilities::fatalError(isset($session) ? $session->getTrackID() : null, 'NOACCESS');
-
-try {
-	$idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
-	$idpMetadata = $metadata->getMetaDataConfig($idpEntityId, 'saml20-idp-hosted');
-} catch (Exception $exception) {
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'METADATA', $exception);
-}
-
-SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame: Got IdP entity id: ' . $idpEntityId);
-
-$logouttype = $idpMetadata->getString('logouttype', 'traditional');
-if ($logouttype !== 'iframe') 
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NOACCESS', new Exception('This IdP is configured to use logout type [' . $logouttype . '], but this endpoint is only available for IdP using logout type [iframe]'));
-
-
-if (!isset($_REQUEST['SAMLResponse'])) {
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'SLOSERVICEPARAMS',
-		new Exception('No valid SAMLResponse found? Probably some error in remote partys metadata that sends something to this endpoint that is not SAML LogoutResponses') );
-}
-
-$binding = SAML2_Binding::getCurrentBinding();;
-$logoutResponse = $binding->receive();;
-if (!($logoutResponse instanceof SAML2_LogoutResponse)) {
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'SLOSERVICEPARAMS',
-		new Exception('Message received on response endpoint wasn\'t a response. Was: ' . get_class($logoutResponse)));
-}
-
-$spEntityId = $logoutResponse->getIssuer();
-if ($spEntityId === NULL) {
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'SLOSERVICEPARAMS',
-		new Exception('Missing issuer on logout response.'));
-}
-$spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote');
-
-sspmod_saml2_Message::validateMessage($spMetadata, $idpMetadata, $logoutResponse);
-
-/*
- * Check the logout response against the logout request, and log
- * warnings if there is a mismatch.
- */
-$requestInfo = $session->getData('slo-request-info', $spEntityId);
-if ($requestInfo !== NULL) {
-	if ($logoutResponse->getInResponseTo() !== $requestInfo['ID']) {
-		SimpleSAML_Logger::warning('Wrong InResponseTo in LogoutResponse from ' .
-			var_export($spEntityId, TRUE) . '.');
-	}
-	if ($logoutResponse->getRelayState() !== $requestInfo['RelayState']) {
-		SimpleSAML_Logger::warning('Wrong RelayState in LogoutResponse from ' .
-			var_export($spEntityId, TRUE) . '.');
-	}
-}
-
-$sphash = sha1($spEntityId);
-setcookie('spstate-' . $sphash , '1'); // Duration: 2 hours
-
-SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutServiceiFrameResponse: Logging out completed');
-
-echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
-	<title>Logout OK</title>
-</head>
-<body>OK</body>
-</html>';
-
-?>
\ No newline at end of file
+$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
+$idp = SimpleSAML_IdP::getById('saml2:' . $idpEntityId);
+sspmod_saml_IdP_SAML2::receiveLogoutMessage($idp);
+assert('FALSE');
diff --git a/www/saml2/idp/idpInitSingleLogoutServiceiFrame.php b/www/saml2/idp/idpInitSingleLogoutServiceiFrame.php
index 4e1b2c866..18b3d332e 100644
--- a/www/saml2/idp/idpInitSingleLogoutServiceiFrame.php
+++ b/www/saml2/idp/idpInitSingleLogoutServiceiFrame.php
@@ -10,277 +10,13 @@
 
 require_once('../../_include.php');
 
-$config = SimpleSAML_Configuration::getInstance();
 $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-$session = SimpleSAML_Session::getInstance();
-
-SimpleSAML_Logger::info('SAML2.0 - IdP.idpInitSingleLogoutServiceiFrame: Accessing SAML 2.0 IdP endpoint SingleLogoutService (iFrame version)');
-
-SimpleSAML_Logger::debug('Initially; ' . join(',', $session->get_sp_list(SimpleSAML_Session::STATE_ONLINE)));
-
-if (!$config->getBoolean('enable.saml20-idp', false))
-	SimpleSAML_Utilities::fatalError(isset($session) ? $session->getTrackID() : null, 'NOACCESS');
-
-try {
-	$idpentityid = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
-	$idpMetadata = $metadata->getMetaDataConfig($idpentityid, 'saml20-idp-hosted');
-} catch (Exception $exception) {
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'METADATA', $exception);
-}
-
-SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame: Got IdP entity id: ' . $idpentityid);
-
-
-
-$logouttype = 'traditional';
-$idpmeta = $metadata->getMetaDataCurrent('saml20-idp-hosted');
-if (array_key_exists('logouttype', $idpmeta)) $logouttype = $idpmeta['logouttype'];
-
-if ($logouttype !== 'iframe') 
-	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NOACCESS', new Exception('This IdP is configured to use logout type [' . $logouttype . '], but this endpoint is only available for IdP using logout type [iframe]'));
-
-
-
-
-
-
-
-/**
- * This function retrieves the logout info with the given ID.
- *
- * @param $id  The identifier of the logout info.
- */
-function fetchLogoutInfo($id) {
-	global $session;
-	global $logoutInfo;
-
-	$logoutInfo = $session->getData('idplogoutresponsedata', $id);
-
-	if($logoutInfo === NULL) {
-		SimpleSAML_Logger::warning('SAML2.0 - IdP.SingleLogoutService: Lost logout information.');
-	}
-}
-
-
-/**
- * This function saves the logout info with the given ID.
- *
- * @param $id  The identifier the logout info should be saved with.
- */
-function saveLogoutInfo($id) {
-	global $session;
-	global $logoutInfo;
-
-	$session->setData('idplogoutresponsedata', $id, $logoutInfo);
-}
-
-
-// Include XAJAX definition.
-require_once(SimpleSAML_Utilities::resolvePath('libextinc') . '/xajax/xajax.inc.php');
-
-
-
-/*
- * This function is called via AJAX and will send LogoutRequest to one single SP by
- * sending a LogoutRequest using HTTP-REDIRECT
- */
-function updateslostatus() {
-
-	SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutServiceiFrame: Accessing SAML 2.0 IdP endpoint SingleLogoutService (iFrame version) within updateslostatus() ');
-
-	$config = SimpleSAML_Configuration::getInstance();
-	$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-	$session = SimpleSAML_Session::getInstance();
-
-	$idpentityid = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
-	
-	$templistofsps = $session->get_sp_list(SimpleSAML_Session::STATE_ONLINE);
-	$listofsps = array();
-	foreach ($templistofsps AS $spentityid) {
-		if (!empty($_COOKIE['spstate-' . sha1($spentityid)])) {
-			$listofsps[] = $spentityid;
-			continue;
-		}
-
-		try {
-			$spMetadata = $metadata->getMetaDataConfig($spentityid, 'saml20-sp-remote');
-		} catch (Exception $e) {
-			/*
-			 * For some reason, the metadata for this SP is no longer available. Most
-			 * likely it was deleted from the IdP while the user had a session to it.
-			 * In any case - skip this SP.
-			 */
-			$listofsps[] = $spentityid;
-			continue;
-		}
-
-		$singleLogoutService = $spMetadata->getDefaultEndpoint('SingleLogoutService', array(SAML2_Const::BINDING_HTTP_REDIRECT), NULL);
-		if ($singleLogoutService === NULL) {
-			/* No logout endpoint. */
-			$listofsps[] = $spentityid;
-			continue;
-		}
-
-		/* This SP isn't ready yet. */
-	}
-	SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame: templistofsps ' . join(',', $templistofsps));
-	SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame:     listofsps ' . join(',', $listofsps));
-
-
-	// Using template object to be able to translate name of service provider.
-	$t = new SimpleSAML_XHTML_Template($config, 'logout-iframe.php');
-
-    // Instantiate the xajaxResponse object
-    $objResponse = new xajaxResponse();
-
-	foreach ($listofsps AS $spentityid) {
-
-		SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutServiceiFrame: Completed ' . $spentityid);
-		
-		// add a command to the response to assign the innerHTML attribute of
-		// the element with id="SomeElementId" to whatever the new content is
-		
-		$spmetadata = $metadata->getMetaData($spentityid, 'saml20-sp-remote');
-		$name = array_key_exists('name', $spmetadata) ? $spmetadata['name'] : $spentityid;
-		
-		$spname = is_array($name) ? $t->getTranslation($name) : $name;
-		
-		$objResponse->addScriptCall('slocompletesp', 'e' . sha1($spentityid));
-
-	}
-	
-	if (count($templistofsps) === count($listofsps)) {
-
-		$templistofsps = $session->get_sp_list(SimpleSAML_Session::STATE_ONLINE);
-		foreach ($templistofsps AS $spentityid) {
-			$session->set_sp_logout_completed($spentityid);
-			setcookie('spstate-' . sha1($spentityid) , '', time() - 3600); // Delete cookie
-		}
-
-		$objResponse->addScriptCall('slocompleted');
-
-		/**
-		 * Clean up session object to save storage.
-		 */
-		if ($config->getBoolean('debug', false))
-			SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: Session Size before cleaning: ' . $session->getSize());
-			
-		$session->clean();
-		
-		if ($config->getBoolean('debug', false))
-			SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: Session Size after cleaning: ' . $session->getSize());
-
-	} else {
-		SimpleSAML_Logger::debug('SAML2.0 - sp_logout_completed FALSE');
-	}
-    
-    //return the  xajaxResponse object
-    return $objResponse;
-}
-
-
-
-$xajax = new xajax();
-$xajax->registerFunction("updateslostatus");
-$xajax->processRequests();
-
-
-
-
-/**
- * Which URL to send the user to after logout?
- */
-$relayState = NULL;
-if (array_key_exists('RelayState', $_REQUEST)) $relayState = $_REQUEST['RelayState'];
-
-// Do logout from the IdP
-$session->doLogout();
-
-// Debug entries in the log about what services the user is logged into.
-$session->dump_sp_sessions();
-
-
-
-/*
- * Generate a list of all service providers, and create a LogoutRequest message for all these SPs.
- */
-$listofsps = $session->get_sp_list();
-$sparray = array();
-$sparrayNoLogout = array();
-foreach ($listofsps AS $spentityid) {
-
-	// ($issuer, $receiver, $nameid, $nameidformat, $sessionindex, $mode) {
-	$nameId = $session->getSessionNameId('saml20-sp-remote', $spentityid);
-	if($nameId === NULL) {
-		$nameId = $session->getNameID();
-	}
-
-	$spMetadata = $metadata->getMetaDataConfig($spentityid, 'saml20-sp-remote');
-	$name = $spMetadata->getValue('name', $spentityid);
-
-	try {	
-		$lr = sspmod_saml2_Message::buildLogoutRequest($idpMetadata, $spMetadata);
-		$lr->setSessionIndex($session->getSessionIndex());
-		$lr->setNameId($nameId);
-
-		$httpredirect = new SAML2_HTTPRedirect();
-		$url = $httpredirect->getRedirectURL($lr);
-
-		$sparray[$spentityid] = array('url' => $url, 'name' => $name);
-
-		/* Add the SP logout request information to the session so that we can check it later. */
-		$requestInfo = array(
-			'ID' => $lr->getId(),
-			'RelayState' => $lr->getRelayState(),
-		);
-		$session->setData('slo-request-info', $spentityid, $requestInfo, 15*60);
-
-	} catch (Exception $e) {
-		
-		$sparrayNoLogout[$spentityid] = array('name' => $name);
-		
-	}
+$idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
+$idp = SimpleSAML_IdP::getById('saml2:' . $idpEntityId);
 
+if (!isset($_REQUEST['RelayState'])) {
+	throw new SimpleSAML_Error_BadRequest('Missing required RelayState parameter.');
 }
 
-
-SimpleSAML_Logger::debug('SAML2.0 - SP Counter. other SPs with SLO support (' . count($sparray) . ')  without SLO support (' . count($sparrayNoLogout) . ')');
-
-
-#print_r($sparray);
-
-
-
-
-/*
- * If the user is not logged into any other SPs.
- */
-if (count($sparray) + count($sparrayNoLogout) === 0) {
-	SimpleSAML_Utilities::redirect($relayState);
-	exit;
-} 
-
-
-$et = new SimpleSAML_XHTML_Template($config, 'logout-iframe.php');
-
-$et->data['header'] = 'Logout';
-$et->data['sparray'] = $sparray;
-$et->data['sparrayNoLogout'] = $sparrayNoLogout;
-
-$et->data['logoutresponse'] = $relayState;
-$et->data['xajax'] = $xajax;
-
-#$et->data['idpInitRelayState'] = $relayState;
-
-# $et->data['requesterName'] = $spname;
-
-$et->data['head'] = $xajax->getJavascript();
-
-$et->show();
-
-exit(0);
-
-
-
-
-?>
\ No newline at end of file
+$idp->doLogoutRedirect((string)$_REQUEST['RelayState']);
+assert('FALSE');
-- 
GitLab