/** * @param SAML2_Message $samlMessage * @return mixed */ public function serialize(SAML2_Message $samlMessage) { if ($samlMessage->getSignatureKey()) { $samlMessageDomElement = $samlMessage->toSignedXML(); } else { $samlMessageDomElement = $samlMessage->toUnsignedXML(); } return $samlMessageDomElement->ownerDocument->saveXML($samlMessageDomElement); }
/** * Receive a SAML 2 message sent using the HTTP-POST binding. * * Throws an exception if it is unable receive the message. * * @return SAML2_Message The received message. */ public function receive() { $postText = file_get_contents('php://input'); if (empty($postText)) { throw new SimpleSAML_Error_BadRequest('Invalid message received to AssertionConsumerService endpoint.'); } $document = new DOMDocument(); $document->loadXML($postText); $xml = $document->firstChild; $results = SAML2_Utils::xpQuery($xml, '/soap-env:Envelope/soap-env:Body/*[1]'); return SAML2_Message::fromXML($results[0]); }
/** * Receive a SAML 2 message sent using the HTTP-POST binding. * * Throws an exception if it is unable receive the message. * * @return SAML2_Message The received message. * @throws Exception */ public function receive() { $postText = file_get_contents('php://input'); if (empty($postText)) { throw new Exception('Invalid message received to AssertionConsumerService endpoint.'); } $document = SAML2_DOMDocumentFactory::fromString($postText); $xml = $document->firstChild; SAML2_Utils::getContainer()->debugMessage($xml, 'in'); $results = SAML2_Utils::xpQuery($xml, '/soap-env:Envelope/soap-env:Body/*[1]'); return SAML2_Message::fromXML($results[0]); }
/** * Receive a SAML 2 message sent using the HTTP-POST binding. * * Throws an exception if it is unable receive the message. * * @return SAML2_Message The received message. * @throws Exception */ public function receive() { if (array_key_exists('SAMLRequest', $_POST)) { $msg = $_POST['SAMLRequest']; } elseif (array_key_exists('SAMLResponse', $_POST)) { $msg = $_POST['SAMLResponse']; } else { throw new Exception('Missing SAMLRequest or SAMLResponse parameter.'); } $msg = base64_decode($msg); SAML2_Utils::getContainer()->debugMessage($msg, 'in'); $document = SAML2_DOMDocumentFactory::fromString($msg); $xml = $document->firstChild; $msg = SAML2_Message::fromXML($xml); if (array_key_exists('RelayState', $_POST)) { $msg->setRelayState($_POST['RelayState']); } return $msg; }
/** * Receive a SAML 2 message sent using the HTTP-POST binding. * * Throws an exception if it is unable receive the message. * * @return SAML2_Message The received message. */ public function receive() { if (array_key_exists('SAMLRequest', $_POST)) { $msg = $_POST['SAMLRequest']; } elseif (array_key_exists('SAMLResponse', $_POST)) { $msg = $_POST['SAMLResponse']; } else { throw new Exception('Missing SAMLRequest or SAMLResponse parameter.'); } $msg = base64_decode($msg); $document = new DOMDocument(); $document->loadXML($msg); $xml = $document->firstChild; $msg = SAML2_Message::fromXML($xml); if (array_key_exists('RelayState', $_POST)) { $msg->setRelayState($_POST['RelayState']); } return $msg; }
/** * Receive a SAML 2 message sent using the HTTP-Artifact binding. * * Throws an exception if it is unable receive the message. * * @return SAML2_Message The received message. * @throws Exception */ public function receive() { if (array_key_exists('SAMLart', $_REQUEST)) { $artifact = base64_decode($_REQUEST['SAMLart']); $endpointIndex = bin2hex(substr($artifact, 2, 2)); $sourceId = bin2hex(substr($artifact, 4, 20)); } else { throw new Exception('Missing SAMLArt parameter.'); } $metadataHandler = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpMetadata = $metadataHandler->getMetaDataConfigForSha1($sourceId, 'saml20-idp-remote'); if ($idpMetadata === NULL) { throw new Exception('No metadata found for remote provider with SHA1 ID: ' . var_export($sourceId, TRUE)); } $endpoint = NULL; foreach ($idpMetadata->getEndpoints('ArtifactResolutionService') as $ep) { if ($ep['index'] === hexdec($endpointIndex)) { $endpoint = $ep; break; } } if ($endpoint === NULL) { throw new Exception('No ArtifactResolutionService with the correct index.'); } SAML2_Utils::getContainer()->getLogger()->debug("ArtifactResolutionService endpoint being used is := " . $endpoint['Location']); //Construct the ArtifactResolve Request $ar = new SAML2_ArtifactResolve(); /* Set the request attributes */ $ar->setIssuer($this->spMetadata->getString('entityid')); $ar->setArtifact($_REQUEST['SAMLart']); $ar->setDestination($endpoint['Location']); /* Sign the request */ sspmod_saml_Message::addSign($this->spMetadata, $idpMetadata, $ar); // Shoaib - moved from the SOAPClient. $soap = new SAML2_SOAPClient(); // Send message through SoapClient /** @var SAML2_ArtifactResponse $artifactResponse */ $artifactResponse = $soap->send($ar, $this->spMetadata); if (!$artifactResponse->isSuccess()) { throw new Exception('Received error from ArtifactResolutionService.'); } $xml = $artifactResponse->getAny(); if ($xml === NULL) { /* Empty ArtifactResponse - possibly because of Artifact replay? */ return NULL; } $samlResponse = SAML2_Message::fromXML($xml); $samlResponse->addValidator(array(get_class($this), 'validateSignature'), $artifactResponse); if (isset($_REQUEST['RelayState'])) { $samlResponse->setRelayState($_REQUEST['RelayState']); } return $samlResponse; }
/** * Convert status response message to an XML element. * * @return DOMElement This status response. */ public function toUnsignedXML() { $root = parent::toUnsignedXML(); if ($this->inResponseTo !== NULL) { $root->setAttribute('InResponseTo', $this->inResponseTo); } if ($this->extensions !== NULL) { if ($this->extensions === TRUE) { $ee = $this->document->createElementNS('http://rnd.feide.no/fedlab-ns', 'UnknownExtension'); } else { $ee = $this->extensions; } $extensions = $this->document->createElementNS(SAML2_Const::NS_SAMLP, 'Extensions'); $extensions->appendChild($ee); $root->appendChild($extensions); } $status = $this->document->createElementNS(SAML2_Const::NS_SAMLP, 'Status'); $root->appendChild($status); $statusCode = $this->document->createElementNS(SAML2_Const::NS_SAMLP, 'StatusCode'); $statusCode->setAttribute('Value', $this->status['Code']); $status->appendChild($statusCode); if (!is_null($this->status['SubCode'])) { $subStatusCode = $this->document->createElementNS(SAML2_Const::NS_SAMLP, 'StatusCode'); $subStatusCode->setAttribute('Value', $this->status['SubCode']); $statusCode->appendChild($subStatusCode); } if (!is_null($this->status['Message'])) { SAML2_Utils::addString($status, SAML2_Const::NS_SAMLP, 'StatusMessage', $this->status['Message']); } return $root; }
/** * Receive a SAML 2 message sent using the HTTP-Redirect binding. * * Throws an exception if it is unable receive the message. * * @return SAML2_Message The received message. */ public function receive() { $data = self::parseQuery(); if (array_key_exists('SAMLRequest', $data)) { $msg = $data['SAMLRequest']; } elseif (array_key_exists('SAMLResponse', $data)) { $msg = $data['SAMLResponse']; } else { throw new Execption('Missing SAMLRequest or SAMLResponse parameter.'); } if (array_key_exists('SAMLEncoding', $data)) { $encoding = $data['SAMLEncoding']; } else { $encoding = self::DEFLATE; } $msg = base64_decode($msg); switch ($encoding) { case self::DEFLATE: $msg = gzinflate($msg); break; default: throw new Exception('Unknown SAMLEncoding: ' . var_export($encoding, TRUE)); } SimpleSAML_Utilities::debugMessage($msg, 'in'); $document = new DOMDocument(); $document->loadXML($msg); $xml = $document->firstChild; $msg = SAML2_Message::fromXML($xml); if (array_key_exists('Signature', $data)) { /* Save the signature validation data until we need it. */ $signatureValidationData = array('Signature' => $data['Signature'], 'Query' => $data['SignedQuery']); } if (array_key_exists('RelayState', $data)) { $msg->setRelayState($data['RelayState']); } if (array_key_exists('Signature', $data)) { if (!array_key_exists('SigAlg', $data)) { throw new Exception('Missing signature algorithm.'); } $signData = array('Signature' => $data['Signature'], 'SigAlg' => $data['SigAlg'], 'Query' => $data['SignedQuery']); $msg->addValidator(array(get_class($this), 'validateSignature'), $signData); } return $msg; }
/** * Add a signature validator based on a SSL context. * * @param SAML2_Message $msg The message we should add a validator to. * @param resource $context The stream context. */ private static function addSSLValidator(SAML2_Message $msg, $context) { $options = stream_context_get_options($context); if (!isset($options['ssl']['peer_certificate'])) { return; } //$out = ''; //openssl_x509_export($options['ssl']['peer_certificate'], $out); $key = openssl_pkey_get_public($options['ssl']['peer_certificate']); if ($key === FALSE) { SimpleSAML_Logger::warning('Unable to get public key from peer certificate.'); return; } $keyInfo = openssl_pkey_get_details($key); if ($keyInfo === FALSE) { SimpleSAML_Logger::warning('Unable to get key details from public key.'); return; } if (!isset($keyInfo['key'])) { SimpleSAML_Logger::warning('Missing key in public key details.'); return; } $msg->addValidator(array('SAML2_SOAPClient', 'validateSSL'), $keyInfo['key']); }
/** * Convert status response message to an XML element. * * @return DOMElement This status response. */ public function toUnsignedXML() { $root = parent::toUnsignedXML(); if ($this->inResponseTo !== NULL) { $root->setAttribute('InResponseTo', $this->inResponseTo); } $status = $this->document->createElementNS(SAML2_Const::NS_SAMLP, 'Status'); $root->appendChild($status); $statusCode = $this->document->createElementNS(SAML2_Const::NS_SAMLP, 'StatusCode'); $statusCode->setAttribute('Value', $this->status['Code']); $status->appendChild($statusCode); if (!is_null($this->status['SubCode'])) { $subStatusCode = $this->document->createElementNS(SAML2_Const::NS_SAMLP, 'StatusCode'); $subStatusCode->setAttribute('Value', $this->status['SubCode']); $statusCode->appendChild($subStatusCode); } if (!is_null($this->status['Message'])) { SAML2_Utils::addString($status, SAML2_Const::NS_SAMLP, 'StatusMessage', $this->status['Message']); } return $root; }
/** * Dump a string representation of this annotated message used for debugging. * * @return string */ public function __toString() { $vars = get_object_vars($this); $vars['sspMessage'] = $this->sspMessage->toUnsignedXML()->ownerDocument->saveXML(); return json_encode($vars); }