public static function cacheResponse(EngineBlock_Saml2_AuthnRequestAnnotationDecorator $receivedRequest, EngineBlock_Saml2_ResponseAnnotationDecorator $receivedResponse, $type)
 {
     if ($type !== self::RESPONSE_CACHE_TYPE_IN) {
         throw new EngineBlock_Exception('Unknown response type');
     }
     if (!isset($_SESSION['CachedResponses'])) {
         $_SESSION['CachedResponses'] = array();
     }
     $_SESSION['CachedResponses'][] = array('sp' => $receivedRequest->getIssuer(), 'idp' => $receivedResponse->getIssuer(), 'type' => $type, 'response' => $receivedResponse, 'vo' => $receivedRequest->getVoContext(), 'key' => $receivedRequest->getKeyId());
 }
 /**
  * @param SAML2_Response|EngineBlock_Saml2_ResponseAnnotationDecorator $response
  */
 protected function _sendDebugMail(EngineBlock_Saml2_ResponseAnnotationDecorator $response)
 {
     $layout = EngineBlock_ApplicationSingleton::getInstance()->getLayout();
     $oldLayout = $layout->getLayout();
     $layout->setLayout('empty');
     $wasEnabled = $layout->isEnabled();
     if ($wasEnabled) {
         $layout->disableLayout();
     }
     $identityProvider = $this->_server->getRepository()->fetchIdentityProviderByEntityId($response->getIssuer());
     $attributes = $response->getAssertion()->getAttributes();
     $output = $this->_server->renderTemplate('debugidpmail', array('idp' => $identityProvider, 'response' => $response, 'attributes' => $attributes));
     $emailConfiguration = EngineBlock_ApplicationSingleton::getInstance()->getConfigurationValue('email')->idpDebugging;
     $mailer = new Zend_Mail('UTF-8');
     $mailer->setFrom($emailConfiguration->from->address, $emailConfiguration->from->name);
     $mailer->addTo($emailConfiguration->to->address, $emailConfiguration->to->name);
     $mailer->setSubject(sprintf($emailConfiguration->subject, $identityProvider->nameEn));
     $mailer->setBodyText($output);
     $mailer->send();
     $layout->setLayout($oldLayout);
 }
 /**
  * @param SAML2_AuthnRequest|EngineBlock_Saml2_AuthnRequestAnnotationDecorator $request
  * @param SAML2_Response|EngineBlock_Saml2_ResponseAnnotationDecorator $sourceResponse
  */
 public function createEnhancedResponse(EngineBlock_Saml2_AuthnRequestAnnotationDecorator $request, EngineBlock_Saml2_ResponseAnnotationDecorator $sourceResponse)
 {
     $newResponse = $this->_createBaseResponse($request);
     // We don't support multiple assertions, only use the first one.
     $sourceAssertions = $sourceResponse->getAssertions();
     $sourceAssertion = $sourceAssertions[0];
     // Store the Origin response and issuer (from the IdP)
     $newResponse->setOriginalResponse($sourceResponse->getOriginalResponse() ? $sourceResponse->getOriginalResponse() : $sourceResponse);
     $newResponse->setOriginalIssuer($sourceResponse->getOriginalIssuer() ? $sourceResponse->getOriginalIssuer() : $newResponse->getOriginalResponse()->getIssuer());
     // Copy over the Status (which should be success)
     $newResponse->setStatus($sourceResponse->getStatus());
     // Create a new assertion by us.
     $newAssertion = new SAML2_Assertion();
     $newResponse->setAssertions(array($newAssertion));
     $newAssertion->setId($this->getNewId(IdFrame::ID_USAGE_SAML2_ASSERTION));
     $newAssertion->setIssueInstant(time());
     $newAssertion->setIssuer($newResponse->getIssuer());
     // Unless of course we are in 'stealth' / transparent mode, in which case,
     // pretend to be the Identity Provider.
     $serviceProvider = $this->getRepository()->fetchServiceProviderByEntityId($request->getIssuer());
     $mustProxyTransparently = $request->isTransparent() || $serviceProvider->isTransparentIssuer;
     if (!$this->isInProcessingMode() && $mustProxyTransparently) {
         $newResponse->setIssuer($newResponse->getOriginalIssuer());
         $newAssertion->setIssuer($newResponse->getOriginalIssuer());
     }
     // Copy over the NameID for now...
     // (further on in the filters we'll have more info and set this to something better)
     $sourceNameId = $sourceAssertion->getNameId();
     if (!empty($sourceNameId) && !empty($sourceNameId['Value']) && !empty($sourceNameId['Format'])) {
         $newAssertion->setNameId(array('Value' => $sourceNameId['Value'], 'Format' => $sourceNameId['Format']));
     }
     // Set up the Subject Confirmation element.
     $subjectConfirmation = new SAML2_XML_saml_SubjectConfirmation();
     $subjectConfirmation->Method = SAML2_Const::CM_BEARER;
     $newAssertion->setSubjectConfirmation(array($subjectConfirmation));
     $subjectConfirmationData = new SAML2_XML_saml_SubjectConfirmationData();
     $subjectConfirmation->SubjectConfirmationData = $subjectConfirmationData;
     // Confirm where we are sending it.
     $acs = $this->getRequestAssertionConsumer($request);
     $subjectConfirmationData->Recipient = $acs->location;
     // Confirm that this is in response to their AuthnRequest (unless, you know, it isn't).
     if (!$request->isUnsolicited()) {
         /** @var SAML2_AuthnRequest $request */
         $subjectConfirmationData->InResponseTo = $request->getId();
     }
     // Note that it is valid for some 5 minutes.
     $notOnOrAfter = time() + $this->getConfig('NotOnOrAfter', 300);
     $newAssertion->setNotBefore(time() - 1);
     if ($sourceAssertion->getSessionNotOnOrAfter()) {
         $newAssertion->setSessionNotOnOrAfter($sourceAssertion->getSessionNotOnOrAfter());
     }
     $newAssertion->setNotOnOrAfter($notOnOrAfter);
     $subjectConfirmationData->NotOnOrAfter = $notOnOrAfter;
     // And only valid for the SP that requested it.
     $newAssertion->setValidAudiences(array($request->getIssuer()));
     // Copy over the Authentication information because the IdP did the authentication, not us.
     $newAssertion->setAuthnInstant($sourceAssertion->getAuthnInstant());
     $newAssertion->setSessionIndex($sourceAssertion->getSessionIndex());
     $newAssertion->setAuthnContextClassRef($sourceAssertion->getAuthnContextClassRef());
     $newAssertion->setAuthnContextDeclRef($sourceAssertion->getAuthnContextDeclRef());
     if ($sourceAssertion->getAuthnContextDecl()) {
         $newAssertion->setAuthnContextDecl($sourceAssertion->getAuthnContextDecl());
     }
     // Copy over the Authenticating Authorities and add the EntityId of the Source Response Issuer.
     // Note that because EB generates multiple responses, this will likely result in:
     // "https://engine/../idp/metadata" !== "https://original-idp/../idpmetadata" => true, gets added
     // "https://engine/../idp/metadata" !== "https://engine/../idp/metadata" => false, does not get added
     // "https://engine/../idp/metadata" !== "https://engine/../idp/metadata" => false, does not get added
     // UNLESS the Response is destined for an SP in VO mode, in which case the flow will be:
     // "https://engine/../idp/metadata" !== "https://original-idp/../idpmetadata" => true, gets added
     // "https://engine/../idp/metadata" !== "https://engine/../idp/metadata" => false, does not get added
     // "https://engine/../idp/metadata/vo:void" !== "https://engine/../idp/metadata" => TRUE, gets added!
     // This is a 'bug'/'feature' that we're keeping in for BWC reasons.
     $authenticatingAuthorities = $sourceAssertion->getAuthenticatingAuthority();
     if ($this->getUrl('idpMetadataService') !== $sourceResponse->getIssuer()) {
         $authenticatingAuthorities[] = $sourceResponse->getIssuer();
     }
     $newAssertion->setAuthenticatingAuthority($authenticatingAuthorities);
     // Copy over the attributes
     $newAssertion->setAttributes($sourceAssertion->getAttributes());
     $newAssertion->setAttributeNameFormat(SAML2_Const::NAMEFORMAT_URI);
     return $newResponse;
 }