From 1f225dda7a8e4c904cd0308a77130845dd191d2e Mon Sep 17 00:00:00 2001
From: Olav Morken <olav.morken@uninett.no>
Date: Mon, 28 Sep 2009 12:16:10 +0000
Subject: [PATCH] iframe-logout: Improvements in behaviour when one of the SPs
 doesn't support SLO.

Fixes issue 187

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@1795 44740490-163a-0410-bde0-09ae8108e29a
---
 templates/logout-iframe.php                   |  3 ++-
 www/saml2/idp/SingleLogoutServiceiFrame.php   | 25 ++++++++++++++++-
 .../idp/idpInitSingleLogoutServiceiFrame.php  | 27 +++++++++++++++++--
 3 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/templates/logout-iframe.php b/templates/logout-iframe.php
index 5f8ab0e20..52751f97e 100644
--- a/templates/logout-iframe.php
+++ b/templates/logout-iframe.php
@@ -50,6 +50,7 @@ function startslo() {
 	$("#hiddeniframecontainer").html("' . str_replace('"', '\"', $iframehtml) . '");
 	$("table#slostatustable tr.onhold").removeClass("onhold").addClass("inprogress");
 /*	$("div.completedButWarnings").show();  */
+' . ($iframehtml === '' ? 'sendResponse();' : '') . '
 	setTimeout("toolong()", 16000);
 }
 
@@ -64,7 +65,7 @@ function slocompletesp($entityhash) {
 function slocompleted() {
 /*	$("div.completedButWarnings").show(); */
 	$("div#interrupt").hide();
-' . ($nologoutSPs ? ' ' : 'setTimeout("sendResponse()", 2000);') . '
+        setTimeout("sendResponse()", 2000);
 }
 
 function sendResponse() {
diff --git a/www/saml2/idp/SingleLogoutServiceiFrame.php b/www/saml2/idp/SingleLogoutServiceiFrame.php
index b394474d5..c27ce3a84 100644
--- a/www/saml2/idp/SingleLogoutServiceiFrame.php
+++ b/www/saml2/idp/SingleLogoutServiceiFrame.php
@@ -104,7 +104,30 @@ function updateslostatus() {
 	$templistofsps = $session->get_sp_list(SimpleSAML_Session::STATE_ONLINE);
 	$listofsps = array();
 	foreach ($templistofsps AS $spentityid) {
-		if (!empty($_COOKIE['spstate-' . sha1($spentityid)])) $listofsps[] = $spentityid;
+		if (!empty($_COOKIE['spstate-' . sha1($spentityid)])) {
+			$listofsps[] = $spentityid;
+			continue;
+		}
+
+		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.
+			 */
+			$listofsps[] = $spentityid;
+			continue;
+		}
+
+		if (!isset($spmetadata['SingleLogoutService'])) {
+			/* 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));
diff --git a/www/saml2/idp/idpInitSingleLogoutServiceiFrame.php b/www/saml2/idp/idpInitSingleLogoutServiceiFrame.php
index c75dcdcf0..3db8a69ac 100644
--- a/www/saml2/idp/idpInitSingleLogoutServiceiFrame.php
+++ b/www/saml2/idp/idpInitSingleLogoutServiceiFrame.php
@@ -97,7 +97,30 @@ function updateslostatus() {
 	$templistofsps = $session->get_sp_list(SimpleSAML_Session::STATE_ONLINE);
 	$listofsps = array();
 	foreach ($templistofsps AS $spentityid) {
-		if (!empty($_COOKIE['spstate-' . sha1($spentityid)])) $listofsps[] = $spentityid;
+		if (!empty($_COOKIE['spstate-' . sha1($spentityid)])) {
+			$listofsps[] = $spentityid;
+			continue;
+		}
+
+		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.
+			 */
+			$listofsps[] = $spentityid;
+			continue;
+		}
+
+		if (!isset($spmetadata['SingleLogoutService'])) {
+			/* 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));
@@ -224,7 +247,7 @@ SimpleSAML_Logger::debug('SAML2.0 - SP Counter. other SPs with SLO support (' .
 /*
  * If the user is not logged into any other SPs.
  */
-if (count($sparray) === 0) {
+if (count($sparray) + count($sparrayNoLogout) === 0) {
 	SimpleSAML_Utilities::redirect($relayState);
 	exit;
 } 
-- 
GitLab