From 520f615460698879d6bdf98c82884f2929ea8dfb Mon Sep 17 00:00:00 2001 From: Olav Morken <olav.morken@uninett.no> Date: Mon, 4 Jan 2010 12:43:24 +0000 Subject: [PATCH] saml2/idp: Log warnings on misbehaving SP logout. This patch makes the iframe logout code log some warnings if it detects something wrong with the SP logout implementation. git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@2064 44740490-163a-0410-bde0-09ae8108e29a --- www/saml2/idp/SingleLogoutServiceiFrame.php | 28 ++++++++++++++++++- .../idp/SingleLogoutServiceiFrameResponse.php | 15 ++++++++++ .../idp/idpInitSingleLogoutServiceiFrame.php | 9 +++++- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/www/saml2/idp/SingleLogoutServiceiFrame.php b/www/saml2/idp/SingleLogoutServiceiFrame.php index 38af9e355..85a6f40c6 100644 --- a/www/saml2/idp/SingleLogoutServiceiFrame.php +++ b/www/saml2/idp/SingleLogoutServiceiFrame.php @@ -232,7 +232,26 @@ if (isset($_REQUEST['SAMLRequest'])) { } 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(); @@ -322,6 +341,13 @@ foreach ($listofsps AS $spentityid) { $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); } diff --git a/www/saml2/idp/SingleLogoutServiceiFrameResponse.php b/www/saml2/idp/SingleLogoutServiceiFrameResponse.php index ec72fb2e0..dddd1b8a1 100644 --- a/www/saml2/idp/SingleLogoutServiceiFrameResponse.php +++ b/www/saml2/idp/SingleLogoutServiceiFrameResponse.php @@ -55,6 +55,21 @@ $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 diff --git a/www/saml2/idp/idpInitSingleLogoutServiceiFrame.php b/www/saml2/idp/idpInitSingleLogoutServiceiFrame.php index 24f8c666f..4e1b2c866 100644 --- a/www/saml2/idp/idpInitSingleLogoutServiceiFrame.php +++ b/www/saml2/idp/idpInitSingleLogoutServiceiFrame.php @@ -227,7 +227,14 @@ foreach ($listofsps AS $spentityid) { $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); -- GitLab