public function run($testrun) { $this->crawler->reset(); $this->crawler2->reset(); // Get authentication request $this->log($testrun, 'Getting an authentication request'); $result1 = $this->crawler->getURLraw($this->initurl); $this->expectAuthenticationRequest($result1); $request = $result1['Request']; $requestRaw = $result1['RequestRaw']; $relaystate = $result1['RelayState']; // Create Response $this->log($testrun, 'Creating a Response'); $samlResponse = $this->createResponse($testrun, $request, $relaystate); $this->responsePrepared($samlResponse); // Sent response and get web page as result $result2 = $this->crawler->sendResponse($samlResponse['url'], $samlResponse['Response'], $samlResponse['RelayState']); $result2b = $this->crawler->getURLraw($this->attributeurl); // error_log('Getting an authentication request'); // $result2b = $this->crawler->getURLraw($this->initurl); // Check output $this->log($testrun, 'Verifying that the user is logged in'); $this->requireLoginOK($testrun, $result2b['body']); // IdP Initiated Logout... // Create logout request $this->log($testrun, 'Creating a LogoutRequest'); $lr = $this->createLogoutRequest($testrun, $samlResponse); $this->logoutrequestPrepared($lr); $binding = new SAML2_HTTPRedirect(); $binding->setDestination($lr['url']); $redirURL = $binding->getRedirectURL($lr['RequestObj']); $this->log($testrun, 'Sending a LogoutRequest'); $result4 = $this->crawler2->getURLraw($redirURL); $logoutResponse = $result4['Request']; $logoutResponseRaw = $result4['RequestRaw']; $this->expectLogoutResponse($logoutResponseRaw); $this->log($testrun, 'Do a new GET to the first page to check if the user is logged in.'); $result5 = $this->crawler->getURLraw($this->attributeurl); # getDebugOutput($testrun, $body, $request, $relaystate, $response, $logoutRequest, $logoutRelayState, $LogoutResponse, $result2) { // error_log($testrun); // error_log($result5['body']); // error_log($requestRaw); // error_log($samlResponse['RelayState']); // error_log($samlResponse['Response']); // error_log($lr['Request']); // error_log($result4['RelayState']); // error_log('logout response' . var_export($logoutResponseRaw, TRUE)); // $debugoutput = $this->getDebugOutputExtended($testrun, $result5['body'], $requestRaw, // isset($samlResponse['RelayState']) ? $samlResponse['RelayState'] : NULL, // isset($samlResponse['Response']) ? $samlResponse['Response'] : NULL, // isset($lr['Request']) ? $lr['Request'] : NULL, // isset($result4['RelayState']) ? $result4['RelayState'] : NULL, // isset($logoutResponseRaw) ? $logoutResponseRaw : NULL, // $result5['body']); $this->log($testrun, 'Check output if user is logged in.'); $this->expectedResult($testrun, $result5['body'], $debugoutput); # error_log('url to logout: ' . $this->initslo); # echo '<pre>'; print_r($this->flushResults()); exit; return $this->flushResults(); }
function sendQuery($dataId, $url, $nameId) { assert('is_string($dataId)'); assert('is_string($url)'); assert('is_array($nameId)'); SimpleSAML_Logger::debug('attributequery - sending request'); $query = new SAML2_AttributeQuery(); $query->setRelayState($dataId); $query->setDestination($url); $query->setIssuer($GLOBALS['spEntityId']); $query->setNameId($nameId); $binding = new SAML2_HTTPRedirect(); $binding->send($query); }
public function run($testrun) { $this->crawler->reset(); // Get authentication request $result1 = $this->crawler->getURLraw($this->initurl); // Fail if no authentication request was made $this->expectAuthenticationRequest($result1); $request = $result1['Request']; $requestRaw = $result1['RequestRaw']; $relaystate = $result1['RelayState']; // Create Response $samlResponse = $this->createResponse($testrun, $request, $relaystate); $this->responsePrepared($samlResponse); // Sent response and get web page as result $result2 = $this->crawler->sendResponse($samlResponse['url'], $samlResponse['Response'], $samlResponse['RelayState']); // Check output $this->requireLoginOK($testrun, $result2['body']); // SP Initiated Logout... $result3 = $this->crawler->getURLraw($this->initslo); if (!isset($result3['Request'])) { error_log('Logout URL did not return a logout request'); throw new Exception('Logout URL did not return a logout request'); } $logoutRequest = $result3['Request']; $logoutRequestRaw = $result3['RequestRaw']; $logoutRelayState = $result3['RelayState']; // Create logout response $this->log($testrun, 'Creating LogoutResponse'); $logoutResponse = $this->createLogoutResponse($testrun, $logoutRequest, $logoutRelayState); $binding = new SAML2_HTTPRedirect(); $binding->setDestination($logoutResponse['url']); $redirURL = $binding->getRedirectURL($logoutResponse['ResponseObj']); $this->log($testrun, 'Sending LogoutResponse'); $result4 = $this->crawler->getURLraw($redirURL); // Get authentication request $this->log($testrun, 'Sending a new request to the initURL endpoint, to verify if user is logged in or not'); $result5 = $this->crawler->getURLraw($this->attributeurl); # getDebugOutput($testrun, $body, $request, $relaystate, $response, $logoutRequest, $logoutRelayState, $LogoutResponse, $result2) { $debugoutput = $this->getDebugOutputExtended($testrun, $result4['body'], $requestRaw, $samlResponse['RelayState'], $samlResponse['Response'], $logoutRequestRaw, $logoutResponse['RelayState'], $logoutResponse['Response'], $result5['body']); $this->expectedResult($testrun, $result5['body'], $debugoutput); # error_log('url to logout: ' . $this->initslo); # echo '<pre>'; print_r($this->flushResults()); exit; return $this->flushResults(); }
/** * 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)'); SimpleSAML_Logger::info('Sending SAML 2.0 LogoutRequest to: ' . var_export($association['saml:entityID'], TRUE)); $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpMetadata = $idp->getConfig(); $spMetadata = $metadata->getMetaDataConfig($association['saml:entityID'], 'saml20-sp-remote'); $lr = sspmod_saml_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); }
/** * Start a SAML 2 logout operation. * * @param array $state The logout state. */ public function startSLO2(&$state) { assert('is_array($state)'); assert('array_key_exists("saml:logout:IdP", $state)'); assert('array_key_exists("saml:logout:NameID", $state)'); assert('array_key_exists("saml:logout:SessionIndex", $state)'); $id = SimpleSAML_Auth_State::saveState($state, 'saml:slosent'); $idp = $state['saml:logout:IdP']; $nameId = $state['saml:logout:NameID']; $sessionIndex = $state['saml:logout:SessionIndex']; $idpMetadata = $this->getIdPMetadata($idp); $endpoint = $idpMetadata->getDefaultEndpoint('SingleLogoutService', array(SAML2_Const::BINDING_HTTP_REDIRECT), FALSE); if ($endpoint === FALSE) { SimpleSAML_Logger::info('No logout endpoint for IdP ' . var_export($idp, TRUE) . '.'); return; } $lr = sspmod_saml_Message::buildLogoutRequest($this->metadata, $idpMetadata); $lr->setNameId($nameId); $lr->setSessionIndex($sessionIndex); $lr->setRelayState($id); $encryptNameId = $idpMetadata->getBoolean('nameid.encryption', NULL); if ($encryptNameId === NULL) { $encryptNameId = $this->metadata->getBoolean('nameid.encryption', FALSE); } if ($encryptNameId) { $lr->encryptNameId(sspmod_saml_Message::getEncryptionKey($idpMetadata)); } $b = new SAML2_HTTPRedirect(); $b->send($lr); assert('FALSE'); }
<?php $session = SimpleSAML_Session::getInstance(); SimpleSAML_Logger::debug('IdP Endpoint accessed....'); $config = SimpleSAML_Configuration::getInstance(); $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $samlredir = new SAML2_HTTPRedirect(); $request = $samlredir->receive(); $entityid = $request->getIssuer(); error_log('Entity ID was [' . $entityid . ']'); $idpm = new sspmod_fedlab_IdPMetadata($config); $spm = new sspmod_fedlab_SPMetadata($entityid, TRUE); #$spm->debug(); $idpentityid = SimpleSAML_Utilities::getBaseURL() . 'module.php/fedlab/metadata.php'; $idpmetadata = array('entityid' => $idpentityid, 'certificate' => 'server.crt', 'privatekey' => 'server.pem'); $test = new sspmod_fedlab_BasicSPTest($idpmetadata, $spm->parsed, $entity, $initurl, $initslo, $attributeurl); $crawler = new sspmod_fedlab_SAMLCrawler(); $requestRaw = sspmod_fedlab_SAMLCrawler::getHTTPRedirectMessage(); echo '<h2>Request</h2>' . "\n"; echo '<textarea style="width: 90%; height: 300px">'; echo htmlspecialchars(SimpleSAML_Utilities::formatXMLString($requestRaw)); echo '</textarea>'; # print_r($request); $relaystate = NULL; if (isset($_REQUEST['RelayState'])) { $relaystate = $_REQUEST['RelayState']; } # createResponse($testrun, $request, $relayState = NULL) { $samlResponse = $test->createResponseP('idp', $request, $relaystate); echo '<h2>Prepared Response</h2>' . "\n"; echo '<textarea style="width: 90%; height: 300px">';
throw new SimpleSAML_Error_Error('NORELAYSTATE'); } try { $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpEntityId = $session->getAuthData('saml2', 'saml:sp:IdP'); if ($idpEntityId === NULL) { SimpleSAML_Logger::info('SAML2.0 - SP.initSLO: User not authenticated with an IdP.'); SimpleSAML_Utilities::redirect($returnTo); } $idpMetadata = $metadata->getMetaDataConfig($idpEntityId, 'saml20-idp-remote'); $SLOendpoint = $idpMetadata->getDefaultEndpoint('SingleLogoutService', array(SAML2_Const::BINDING_HTTP_REDIRECT), NULL); if ($SLOendpoint === NULL) { $session->doLogout('saml2'); SimpleSAML_Logger::info('SAML2.0 - SP.initSLO: No supported SingleLogoutService endpoint in IdP.'); SimpleSAML_Utilities::redirect($returnTo); } $spEntityId = isset($_GET['spentityid']) ? $_GET['spentityid'] : $metadata->getMetaDataCurrentEntityID(); $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-hosted'); $nameId = $session->getAuthData('saml2', 'saml:sp:NameID'); $lr = sspmod_saml_Message::buildLogoutRequest($spMetadata, $idpMetadata); $lr->setNameId($nameId); $lr->setSessionIndex($session->getAuthData('saml2', 'saml:sp:SessionIndex')); $session->doLogout('saml2'); /* Save the $returnTo url until the user returns from the IdP. */ $session->setData('spLogoutReturnTo', $lr->getId(), $returnTo); SimpleSAML_Logger::info('SAML2.0 - SP.initSLO: SP (' . $spEntityId . ') is sending logout request to IdP (' . $idpEntityId . ')'); $b = new SAML2_HTTPRedirect(); $b->send($lr); } catch (Exception $exception) { throw new SimpleSAML_Error_Error('CREATEREQUEST', $exception); }
/** * 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)'); SimpleSAML_Logger::info('Sending SAML 2.0 LogoutRequest to: ' . var_export($association['saml:entityID'], TRUE)); $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpMetadata = $idp->getConfig(); $spMetadata = $metadata->getMetaDataConfig($association['saml:entityID'], 'saml20-sp-remote'); $lr = sspmod_saml_Message::buildLogoutRequest($idpMetadata, $spMetadata); $lr->setRelayState($relayState); $lr->setSessionIndex($association['saml:SessionIndex']); $lr->setNameId($association['saml:NameID']); $assertionLifetime = $spMetadata->getInteger('assertion.lifetime', NULL); if ($assertionLifetime === NULL) { $assertionLifetime = $idpMetadata->getInteger('assertion.lifetime', 300); } $lr->setNotOnOrAfter(time() + $assertionLifetime); $encryptNameId = $spMetadata->getBoolean('nameid.encryption', NULL); if ($encryptNameId === NULL) { $encryptNameId = $idpMetadata->getBoolean('nameid.encryption', FALSE); } if ($encryptNameId) { $lr->encryptNameId(sspmod_saml_Message::getEncryptionKey($spMetadata)); } SimpleSAML_Stats::log('saml:idp:LogoutRequest:sent', array('spEntityID' => $association['saml:entityID'], 'idpEntityID' => $idpMetadata->getString('entityid'))); $binding = new SAML2_HTTPRedirect(); return $binding->getRedirectURL($lr); }
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;
/** * This function requests a url with a GET request. * * @param $curl The curl handle which should be used. * @param $url The url which should be requested. * @param $parameters Associative array with parameters which should be appended to the url. * @return The content of the returned page. */ function getURLraw($url, $parameters = array(), $type = 'get', $maxredirs = 10, $cookies = NULL) { if (empty($url)) { throw new Exception('Trying to crawl an empty URL'); } if ($maxredirs < 0) { throw new Exception('Max redirection reached...'); } $p = ''; foreach ($parameters as $k => $v) { if ($p != '') { $p .= '&'; } $p .= urlencode($k) . '=' . urlencode($v); } switch ($type) { case 'post': curl_setopt($this->curl, CURLOPT_POSTFIELDS, $p); curl_setopt($this->curl, CURLOPT_POST, TRUE); break; case 'get': default: if (!empty($parameters)) { if (strpos($url, '?') === FALSE) { $url .= '?' . $p; } else { $url .= '&' . $p; } } curl_setopt($this->curl, CURLOPT_HTTPGET, TRUE); } curl_setopt($this->curl, CURLOPT_URL, $url); if (isset($cookies)) { $cookieline = join('; ', $cookies); curl_setopt($this->curl, CURLOPT_COOKIE, $cookieline); $this->log('Set cookies in request to [' . $cookieline . ']'); } $this->log('Contacting URL [' . $url . ']'); $response = curl_exec($this->curl); if ($response === FALSE) { #echo('Failed to get url: ' . $url . "\n"); #echo('Curl error: ' . curl_error($curl) . "\n"); $this->log('Error retrieving URL: ' . curl_error($this->curl)); return FALSE; } $header_size = curl_getinfo($this->curl, CURLINFO_HEADER_SIZE); $result['header'] = substr($response, 0, $header_size); $result['body'] = substr($response, $header_size); $result['http_code'] = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); $result['last_url'] = curl_getinfo($this->curl, CURLINFO_EFFECTIVE_URL); $result['headerout'] = curl_getinfo($this->curl, CURLINFO_HEADER_OUT); $result['setCookies'] = $this->parseCookiesFromHeader($result['header']); // $this->log('Header :' . $result['header']); if (!empty($result['setCookies'])) { $this->log('Cookies :' . var_export($result['setCookies'], TRUE)); } $info = curl_getinfo($this->curl); $headers = self::parseHeaders($result['header']); // error_log('headers: ' . var_export($headers, TRUE)); // error_log('headers raw: ' . var_export($result['header'], TRUE)); // error_log('info: ' . var_export($info, TRUE)); if (isset($headers['location'])) { $nexturl = $headers['location']; $this->log('Location header found [' . $nexturl . ']'); if (substr($nexturl, 0, 1) == '/') { if (preg_match('|(http(s)?://.*?)/|', $info['url'], $matches)) { $nexturl = $matches[1] . $nexturl; $this->log('Constructed new URL [' . $nexturl . ']'); } } # $url = $info['url']; $urlp = parse_url($nexturl); # echo '<p>Next url [' . $nexturl . ']'; // If next step is server; then look for AuthnRequest... #error_log('Location header query part: ' . $urlp['query']); $this->log('Next URL host is [' . (string) $urlp['host'] . '] comparing with my host [' . (string) SimpleSAML_Utilities::getSelfHost() . ']'); if (strcmp((string) $urlp['host'], (string) SimpleSAML_Utilities::getSelfHost()) == 0) { #echo "FOUND REQUEST"; #print_r($urlp['query']); $_SERVER['QUERY_STRING'] = $urlp['query']; $samlredir = new SAML2_HTTPRedirect(); if (strstr($urlp['query'], 'SAMLRequest=') || strstr($urlp['query'], 'SAMLResponse=')) { $result['RequestRaw'] = self::getHTTPRedirectMessage(); $result['Request'] = $samlredir->receive(); # $params = parse_str($urlp['query']); $result['RelayState'] = $result['Request']->getRelayState(); # $this->log('Parameters: ' . var_export($params, TRUE)); # if (isset($params['RelayState'])) $result['RelayState'] = $params['RelayState']; } return $result; } // Follow redirects return $this->getURLraw($nexturl, $parameters, $type, $maxredirs - 1, $cookies); } if (preg_match('/method="POST"/', $result['body'])) { $body = $result['body']; $action = null; if (preg_match('|action="(.*?)"|', $body, $matches)) { $action = $matches[1]; } $data = array(); if (preg_match_all('|type="hidden" name="([^"]*?)" value="([^"]*?)"|', $body, $matches, PREG_SET_ORDER)) { foreach ($matches as $m) { $data[$m[1]] = htmlspecialchars_decode($m[2]); } } foreach ($data as $k => $v) { error_log('key : ' . $k); error_log('value : ' . $v); } //error_log('WS-Fed Hack: ' . $result['body']); error_log('Action : ' . $action); if (empty($data) || empty($action)) { throw new Exception('Could not get WS-Fed Form data....'); } // getURLraw($url, $parameters = array(), $type = 'get', $maxredirs = 10, $cookies = NULL) { $this->getURLraw($action, $data, 'post'); } $this->log('Accessed a page with neither a redirect nor a SAML message'); $this->log('body: ' . strip_tags($result['body'])); return $result; }
/** * Start a SAML 2 logout operation. * * @param array $state The logout state. */ public function startSLO2(&$state) { assert('is_array($state)'); assert('array_key_exists("saml:logout:IdP", $state)'); assert('array_key_exists("saml:logout:NameID", $state)'); assert('array_key_exists("saml:logout:SessionIndex", $state)'); $id = SimpleSAML_Auth_State::saveState($state, 'saml:slosent'); $idp = $state['saml:logout:IdP']; $nameId = $state['saml:logout:NameID']; $sessionIndex = $state['saml:logout:SessionIndex']; $idpMetadata = $this->getIdPMetadata($idp); $endpoint = $idpMetadata->getString('SingleLogoutService', FALSE); if ($endpoint === FALSE) { SimpleSAML_Logger::info('No logout endpoint for IdP ' . var_export($idp, TRUE) . '.'); return; } $lr = sspmod_saml2_Message::buildLogoutRequest($this->metadata, $idpMetadata); $lr->setNameId($nameId); $lr->setSessionIndex($sessionIndex); $lr->setRelayState($id); $b = new SAML2_HTTPRedirect(); $b->setDestination(sspmod_SAML2_Message::getDebugDestination()); $b->send($lr); assert('FALSE'); }
$ar->setRelayState($_REQUEST['RelayState']); if ($isPassive) { $ar->setIsPassive(TRUE); } if ($forceAuthn) { $ar->setForceAuthn(TRUE); } if (array_key_exists('IDPList', $spmetadata)) { $IDPList = array_unique(array_merge($IDPList, $spmetadata['IDPList'])); } if (isset($_GET['IDPList']) && !empty($_GET['IDPList'])) { $providers = $_GET['IDPList']; if (!is_array($providers)) { $providers = array($providers); } $IDPList = array_merge($IDPList, $providers); } $ar->setIDPList($IDPList); /* Save request information. */ $info = array(); $info['RelayState'] = $_REQUEST['RelayState']; if (array_key_exists('OnError', $_REQUEST)) { $info['OnError'] = $_REQUEST['OnError']; } $session->setData('SAML2:SP:SSO:Info', $ar->getId(), $info); $b = new SAML2_HTTPRedirect(); $b->setDestination(sspmod_SAML2_Message::getDebugDestination()); $b->send($ar); } catch (Exception $exception) { SimpleSAML_Utilities::fatalError($session->getTrackID(), 'CREATEREQUEST', $exception); }
/** * Handle logout operation. * * @param array $state The logout state. */ public function logout(&$state) { assert('is_array($state)'); assert('array_key_exists(self::LOGOUT_IDP, $state)'); assert('array_key_exists(self::LOGOUT_NAMEID, $state)'); assert('array_key_exists(self::LOGOUT_SESSIONINDEX, $state)'); $id = SimpleSAML_Auth_State::saveState($state, self::STAGE_LOGOUTSENT); $idp = $state[self::LOGOUT_IDP]; $nameId = $state[self::LOGOUT_NAMEID]; $sessionIndex = $state[self::LOGOUT_SESSIONINDEX]; if (array_key_exists('value', $nameId)) { /* * This session was saved by an old version of simpleSAMLphp. * Convert to the new NameId format. * * TODO: Remove this conversion once every session should use the new format. */ $nameId['Value'] = $nameId['value']; unset($nameId['value']); } $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpMetadata = $metadata->getMetaDataConfig($idp, 'saml20-idp-remote'); $lr = sspmod_saml2_Message::buildLogoutRequest($this->metadata, $idpMetadata); $lr->setNameId($nameId); $lr->setSessionIndex($sessionIndex); $lr->setRelayState($id); $b = new SAML2_HTTPRedirect(); $b->setDestination(sspmod_SAML2_Message::getDebugDestination()); $b->send($lr); assert('FALSE'); }
public function run($testrun) { $this->crawler->reset(); /* ----- o ------ o ------ * Initiate authentication. Send authentication request. * ----- o ------ o ------ */ $this->log($testrun, 'Getting an authentication request'); $result1 = $this->crawler->getURLraw($this->initurl); // Fail if no authentication request was made $this->expectAuthenticationRequest($result1); $request = $result1['Request']; $requestRaw = $result1['RequestRaw']; $relaystate = $result1['RelayState']; /* ----- o ------ o ------ * IdP Initiated Logout... * ----- o ------ o ------ */ // First create a response... $this->log($testrun, 'Creating a Response'); $samlResponse = $this->createResponse($testrun, $request, $relaystate); // Create logout request $this->log($testrun, 'Creating a LogoutRequest'); $lr = $this->createLogoutRequest($testrun, $samlResponse); $this->logoutrequestPrepared($lr); $binding = new SAML2_HTTPRedirect(); $binding->setDestination($lr['url']); $redirURL = $binding->getRedirectURL($lr['RequestObj']); #error_log('getRedirectURL returns: ['. $redirURL . ']'); $this->log($testrun, 'Sending a LogoutRequest'); $result4 = $this->crawler->getURLraw($redirURL); $logoutResponse = $result4['Request']; $logoutResponseRaw = $result4['RequestRaw']; $this->expectLogoutResponse($logoutResponseRaw); /* ----- o ------ o ------ * Create Response with Assertion... * ----- o ------ o ------ */ // Sent response and get web page as result $this->responsePrepared($samlResponse); $result2 = $this->crawler->sendResponse($samlResponse['url'], $samlResponse['Response'], $samlResponse['RelayState']); // Get authentication request $this->log($testrun, 'Do a new GET to the first page to check if the user is logged in.'); $result5 = $this->crawler->getURLraw($this->attributeurl); $this->log($testrun, 'Prepare debug output'); # getDebugOutput($testrun, $body, $request, $relaystate, $response, $logoutRequest, $logoutRelayState, $LogoutResponse, $result2) { /** * body Web page shown after logout. * request The authentication request * relaystate The relaystate of the authentication request * response The Response * logoutRequest The logout request * logoutRelayState * result2 The web site shown at attribute page accessing after flow. */ // $debugoutput = $this->getDebugOutputExtended($testrun, // $requestRaw, // isset($samlResponse['RelayState']) ? $samlResponse['RelayState'] : NULL, // isset($samlResponse['Response']) ? $samlResponse['Response'] : NULL, // isset($lr['Request']) ? $lr['Request'] : NULL, // isset($result4['RelayState']) ? $result4['RelayState'] : NULL, // isset($logoutResponseRaw) ? $logoutResponseRaw : NULL, // $result5['body']); $this->log($testrun, 'Check output if user is logged in.'); $this->expectedResult($testrun, $result5['body'], null); # error_log('url to logout: ' . $this->initslo); # echo '<pre>'; print_r($this->flushResults()); exit; return $this->flushResults(); }
$ar->setAssertionConsumerServiceURL($assertionConsumerServiceURL); $ar->setRelayState($_REQUEST['RelayState']); if ($isPassive) { $ar->setIsPassive(TRUE); } if ($forceAuthn) { $ar->setForceAuthn(TRUE); } if (array_key_exists('IDPList', $spmetadata)) { $IDPList = array_unique(array_merge($IDPList, $spmetadata['IDPList'])); } if (isset($_GET['IDPList']) && !empty($_GET['IDPList'])) { $providers = $_GET['IDPList']; if (!is_array($providers)) { $providers = array($providers); } $IDPList = array_merge($IDPList, $providers); } $ar->setIDPList($IDPList); /* Save request information. */ $info = array(); $info['RelayState'] = $_REQUEST['RelayState']; if (array_key_exists('OnError', $_REQUEST)) { $info['OnError'] = $_REQUEST['OnError']; } $session->setData('SAML2:SP:SSO:Info', $ar->getId(), $info); $b = new SAML2_HTTPRedirect(); $b->send($ar); } catch (Exception $exception) { throw new SimpleSAML_Error_Error('CREATEREQUEST', $exception); }
$spEntityId = $source->getEntityId(); $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpMetadata = $metadata->getMetaDataConfig($idpEntityId, 'saml20-idp-remote'); $spMetadata = $source->getMetadata(); sspmod_saml2_Message::validateMessage($idpMetadata, $spMetadata, $message); if ($message instanceof SAML2_LogoutResponse) { $relayState = $message->getRelayState(); if ($relayState === NULL) { /* Somehow, our RelayState has been lost. */ throw new SimpleSAML_Error_BadRequest('Missing RelayState in logout response.'); } if (!$message->isSuccess()) { SimpleSAML_Logger::warning('Unsuccessful logout. Status was: ' . sspmod_saml2_Message::getResponseError($message)); } $state = SimpleSAML_Auth_State::loadState($relayState, sspmod_saml2_Auth_Source_SP::STAGE_LOGOUTSENT); SimpleSAML_Auth_Source::completeLogout($state); } elseif ($message instanceof SAML2_LogoutRequest) { SimpleSAML_Logger::debug('module/saml2/sp/logout: Request from ' . $idpEntityId); SimpleSAML_Logger::stats('saml20-idp-SLO idpinit ' . $spEntityId . ' ' . $idpEntityId); /* Notify source of logout, so that it may call logout callbacks. */ $source->onLogout($idpEntityId); /* Create an send response. */ $lr = sspmod_saml2_Message::buildLogoutResponse($spMetadata, $idpMetadata); $lr->setRelayState($message->getRelayState()); $lr->setInResponseTo($message->getId()); $binding = new SAML2_HTTPRedirect(); $binding->setDestination(sspmod_SAML2_Message::getDebugDestination()); $binding->send($lr); } else { throw new SimpleSAML_Error_BadRequest('Unknown message received on logout endpoint: ' . get_class($message)); }
$idpMetadata = $metadata->getMetaDataConfig($idpEntityId, 'saml20-idp-remote'); $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-hosted'); sspmod_saml_Message::validateMessage($idpMetadata, $spMetadata, $message); if ($message instanceof SAML2_LogoutRequest) { try { // Extract some parameters from the logout request $requestid = $message->getId(); SimpleSAML_Logger::info('SAML2.0 - SP.SingleLogoutService: IdP (' . $idpEntityId . ') is sending logout request to me SP (' . $spEntityId . ') requestid ' . $requestid); SimpleSAML_Logger::stats('saml20-idp-SLO idpinit ' . $spEntityId . ' ' . $idpEntityId); /* Create response. */ $lr = sspmod_saml_Message::buildLogoutResponse($spMetadata, $idpMetadata); $lr->setRelayState($message->getRelayState()); $lr->setInResponseTo($message->getId()); SimpleSAML_Logger::info('SAML2.0 - SP.SingleLogoutService: SP me (' . $spEntityId . ') is sending logout response to IdP (' . $idpEntityId . ')'); /* Send response. */ $binding = new SAML2_HTTPRedirect(); $binding->send($lr); } catch (Exception $exception) { throw new SimpleSAML_Error_Error('LOGOUTREQUEST', $exception); } } elseif ($message instanceof SAML2_LogoutResponse) { SimpleSAML_Logger::stats('saml20-sp-SLO spinit ' . $spEntityId . ' ' . $idpEntityId); $id = $message->getRelayState(); if (empty($id)) { /* For backwardscompatibility. */ $id = $message->getInResponseTo(); } $returnTo = $session->getData('spLogoutReturnTo', $id); if (empty($returnTo)) { throw new SimpleSAML_Error_Error('LOGOUTINFOLOST'); }
/** * This function requests a url with a GET request. * * @param $curl The curl handle which should be used. * @param $url The url which should be requested. * @param $parameters Associative array with parameters which should be appended to the url. * @return The content of the returned page. */ function getURLraw($url, $parameters = array(), $type = 'get', $maxredirs = 10) { if (empty($url)) { throw new Exception('Trying to crawl an empty URL'); } if ($maxredirs < 0) { throw new Exception('Max redirection reached...'); } $p = ''; foreach ($parameters as $k => $v) { if ($p != '') { $p .= '&'; } $p .= urlencode($k) . '=' . urlencode($v); } switch ($type) { case 'post': curl_setopt($this->curl, CURLOPT_POSTFIELDS, $p); curl_setopt($this->curl, CURLOPT_POST, TRUE); break; case 'get': default: if (!empty($parameters)) { if (strpos($url, '?') === FALSE) { $url .= '?' . $p; } else { $url .= '&' . $p; } } curl_setopt($this->curl, CURLOPT_HTTPGET, TRUE); } curl_setopt($this->curl, CURLOPT_URL, $url); $this->log('Contacting URL [' . $url . ']'); $response = curl_exec($this->curl); if ($response === FALSE) { #echo('Failed to get url: ' . $url . "\n"); #echo('Curl error: ' . curl_error($curl) . "\n"); return FALSE; } $header_size = curl_getinfo($this->curl, CURLINFO_HEADER_SIZE); $result['header'] = substr($response, 0, $header_size); $result['body'] = substr($response, $header_size); $result['http_code'] = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); $result['last_url'] = curl_getinfo($this->curl, CURLINFO_EFFECTIVE_URL); $result['headerout'] = curl_getinfo($this->curl, CURLINFO_HEADER_OUT); // $this->log('header out :' . $result['headerout']); $info = curl_getinfo($this->curl); $headers = self::parseHeaders($result['header']); // error_log('headers: ' . var_export($headers, TRUE)); // error_log('headers raw: ' . var_export($result['header'], TRUE)); // error_log('info: ' . var_export($info, TRUE)); if (isset($headers['location'])) { $nexturl = $headers['location']; $this->log('Location header found [' . $nexturl . ']'); if (substr($nexturl, 0, 1) == '/') { if (preg_match('|(http(s)?://.*?)/|', $info['url'], $matches)) { $nexturl = $matches[1] . $nexturl; $this->log('Constructed new URL [' . $nexturl . ']'); } } # $url = $info['url']; $urlp = parse_url($nexturl); # echo '<p>Next url [' . $nexturl . ']'; // If next step is server; then look for AuthnRequest... #error_log('Location header query part: ' . $urlp['query']); $this->log('Next URL host is [' . (string) $urlp['host'] . '] comparing with my host [' . (string) SimpleSAML_Utilities::getSelfHost() . ']'); if (strcmp((string) $urlp['host'], (string) SimpleSAML_Utilities::getSelfHost()) == 0) { #echo "FOUND REQUEST"; #print_r($urlp['query']); $_SERVER['QUERY_STRING'] = $urlp['query']; $samlredir = new SAML2_HTTPRedirect(); if (strstr($urlp['query'], 'SAMLRequest=') || strstr($urlp['query'], 'SAMLResponse=')) { $result['RequestRaw'] = self::getHTTPRedirectMessage(); $result['Request'] = $samlredir->receive(); # $params = parse_str($urlp['query']); $result['RelayState'] = $result['Request']->getRelayState(); # $this->log('Parameters: ' . var_export($params, TRUE)); # if (isset($params['RelayState'])) $result['RelayState'] = $params['RelayState']; } return $result; } // Follow redirects return $this->getURLraw($nexturl, $parameters, $type, $maxredirs - 1); } return $result; }
/** * launchkey_form - login form for wp-login.php * * @since 1.1.0 * * @param string $class A space separated list of classes to set on the "class" attribute of a containing DIV for the login button * @param string $id The value to set on the "id" attribute of a containing DIV for the login button * @param string $style A string of HTML style code tto set on the "style" attribute of a containing DIV for the login button */ public function launchkey_form($class = '', $id = '', $style = '') { if (isset($_GET['launchkey_error'])) { $this->wp_facade->_echo($this->template->render_template('error', array('error' => 'Error!', 'message' => 'The LaunchKey request was denied or an issue was detected during authentication. Please try again.'))); } elseif (isset($_GET['launchkey_ssl_error'])) { $this->wp_facade->_echo($this->template->render_template('error', array('error' => 'Error!', 'message' => 'There was an error trying to request the LaunchKey servers. If this persists you may need to disable SSL verification.'))); } elseif (isset($_GET['launchkey_security'])) { $this->wp_facade->_echo($this->template->render_template('error', array('error' => 'Error!', 'message' => 'There was a security issue detected and you have been logged out for your safety. Log back in to ensure a secure session.'))); } $container = SAML2_Utils::getContainer(); $request = new SAML2_AuthnRequest(); $request->setId($container->generateId()); //$request->setProviderName( parse_url( $this->wp_facade->home_url( '/' ), PHP_URL_HOST ) ); $request->setDestination($this->login_url); $request->setIssuer($this->entity_id); $request->setRelayState($this->wp_facade->admin_url()); $request->setAssertionConsumerServiceURL($this->wp_facade->wp_login_url()); $request->setProtocolBinding(SAML2_Const::BINDING_HTTP_POST); $request->setIsPassive(false); $request->setNameIdPolicy(array('Format' => SAML2_Const::NAMEID_PERSISTENT, 'AllowCreate' => true)); // Send it off using the HTTP-Redirect binding $binding = new SAML2_HTTPRedirect(); $binding->setDestination($this->login_url); $this->wp_facade->_echo($this->template->render_template('launchkey-form', array('class' => $class, 'id' => $id, 'style' => $style, 'login_url' => $binding->getRedirectURL($request), 'login_text' => 'Log in with', 'login_with_app_name' => 'LaunchKey', 'size' => in_array($this->wp_facade->get_locale(), array('fr_FR', 'es_ES')) ? 'small' : 'medium'))); }
/** * 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)'); SimpleSAML_Logger::info('Sending SAML 2.0 LogoutRequest to: ' . var_export($association['saml:entityID'], TRUE)); $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpMetadata = $idp->getConfig(); $spMetadata = $metadata->getMetaDataConfig($association['saml:entityID'], 'saml20-sp-remote'); $bindings = array(SAML2_Const::BINDING_HTTP_REDIRECT, SAML2_Const::BINDING_HTTP_POST); $dst = $spMetadata->getEndpointPrioritizedByBinding('SingleLogoutService', $bindings); if ($dst['Binding'] === SAML2_Const::BINDING_HTTP_POST) { $params = array('association' => $association['id'], 'idp' => $idp->getId()); if ($relayState !== NULL) { $params['RelayState'] = $relayState; } return SimpleSAML_Module::getModuleURL('core/idp/logout-iframe-post.php', $params); } $lr = self::buildLogoutRequest($idpMetadata, $spMetadata, $association, $relayState); $lr->setDestination($dst['Location']); $binding = new SAML2_HTTPRedirect(); return $binding->getRedirectURL($lr); }
$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); } 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); /* * If the user is not logged into any other SPs. */ if (count($sparray) + count($sparrayNoLogout) === 0) { SimpleSAML_Utilities::redirect($relayState); exit; }