![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/mautic.corals.io/vendor/litesaml/lightsaml/src/Binding/ |
<?php namespace LightSaml\Binding; use LightSaml\Context\Profile\Helper\MessageContextHelper; use LightSaml\Context\Profile\MessageContext; use LightSaml\Error\LightSamlBindingException; use LightSaml\Model\Protocol\AbstractRequest; use LightSaml\Model\Protocol\SamlMessage; use LightSaml\Model\XmlDSig\SignatureStringReader; use LightSaml\Model\XmlDSig\SignatureWriter; use LightSaml\SamlConstants; use RobRichards\XMLSecLibs\XMLSecurityKey; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; class HttpRedirectBinding extends AbstractBinding { /** * @param string|null $destination * * @return \Symfony\Component\HttpFoundation\Response */ public function send(MessageContext $context, $destination = null) { $destination = $context->getMessage()->getDestination() ? $context->getMessage()->getDestination() : $destination; $url = $this->getRedirectURL($context, $destination); return new RedirectResponse($url); } public function receive(Request $request, MessageContext $context) { $data = $this->parseQuery($request); $this->processData($data, $context); } /** * @throws \Exception */ protected function processData(array $data, MessageContext $context) { $msg = $this->getMessageStringFromData($data); $encoding = $this->getEncodingFromData($data); $msg = $this->decodeMessageString($msg, $encoding); $this->dispatchReceive($msg); $deserializationContext = $context->getDeserializationContext(); $message = SamlMessage::fromXML($msg, $deserializationContext); $this->loadRelayState($message, $data); $this->loadSignature($message, $data); $context->setMessage($message); } /** * @return string * * @throws LightSamlBindingException */ protected function getMessageStringFromData(array $data) { if (array_key_exists('SAMLRequest', $data)) { return $data['SAMLRequest']; } elseif (array_key_exists('SAMLResponse', $data)) { return $data['SAMLResponse']; } else { throw new LightSamlBindingException('Missing SAMLRequest or SAMLResponse parameter'); } } /** * @return string */ protected function getEncodingFromData(array $data) { if (array_key_exists('SAMLEncoding', $data)) { return $data['SAMLEncoding']; } else { return SamlConstants::ENCODING_DEFLATE; } } /** * @param string $msg * @param string $encoding * * @throws \LightSaml\Error\LightSamlBindingException * * @return string */ protected function decodeMessageString($msg, $encoding) { $msg = base64_decode($msg); switch ($encoding) { case SamlConstants::ENCODING_DEFLATE: return gzinflate($msg); break; default: throw new LightSamlBindingException(sprintf("Unknown encoding '%s'", $encoding)); } } protected function loadRelayState(SamlMessage $message, array $data) { if (array_key_exists('RelayState', $data)) { $message->setRelayState($data['RelayState']); } } protected function loadSignature(SamlMessage $message, array $data) { if (array_key_exists('Signature', $data)) { if (false == array_key_exists('SigAlg', $data)) { throw new LightSamlBindingException('Missing signature algorithm'); } $message->setSignature( new SignatureStringReader($data['Signature'], $data['SigAlg'], $data['SignedQuery']) ); } } /** * @param string|null $destination * * @return string */ protected function getRedirectURL(MessageContext $context, $destination) { $message = MessageContextHelper::asSamlMessage($context); $signature = $message->getSignature(); if ($signature && false == $signature instanceof SignatureWriter) { throw new LightSamlBindingException('Signature must be SignatureWriter'); } $xml = $this->getMessageEncodedXml($message, $context); $msg = $this->addMessageToUrl($message, $xml); $this->addRelayStateToUrl($msg, $message); $this->addSignatureToUrl($msg, $signature); return $this->getDestinationUrl($msg, $message, $destination); } /** * @return string */ protected function getMessageEncodedXml(SamlMessage $message, MessageContext $context) { $message->setSignature(null); $serializationContext = $context->getSerializationContext(); $message->serialize($serializationContext->getDocument(), $serializationContext); $xml = $serializationContext->getDocument()->saveXML(); $this->dispatchSend($xml); $xml = gzdeflate($xml); $xml = base64_encode($xml); return $xml; } /** * @param string $xml * * @return string */ protected function addMessageToUrl(SamlMessage $message, $xml) { if ($message instanceof AbstractRequest) { $msg = 'SAMLRequest='; } else { $msg = 'SAMLResponse='; } $msg .= urlencode($xml); return $msg; } /** * @param string $msg */ protected function addRelayStateToUrl(&$msg, SamlMessage $message) { if (null !== $message->getRelayState()) { $msg .= '&RelayState=' . urlencode($message->getRelayState()); } } /** * @param string $msg */ protected function addSignatureToUrl(&$msg, SignatureWriter $signature = null) { /** @var $key XMLSecurityKey */ $key = $signature ? $signature->getXmlSecurityKey() : null; if (null != $key) { $msg .= '&SigAlg=' . urlencode($key->type); $signature = $key->signData($msg); $msg .= '&Signature=' . urlencode(base64_encode($signature)); } } /** * @param string $msg * @param string|null $destination * * @return string */ protected function getDestinationUrl($msg, SamlMessage $message, $destination) { $destination = $message->getDestination() ? $message->getDestination() : $destination; if (false === strpos($destination, '?')) { $destination .= '?' . $msg; } else { $destination .= '&' . $msg; } return $destination; } /** * @return array */ protected function parseQuery(Request $request) { /* * Parse the query string. We need to do this ourself, so that we get access * to the raw (urlencoded) values. This is required because different software * can urlencode to different values. */ $sigQuery = $relayState = $sigAlg = ''; $data = $this->parseQueryString($request->server->get('QUERY_STRING')); $result = []; foreach ($data as $name => $value) { $result[$name] = urldecode($value); switch ($name) { case 'SAMLRequest': case 'SAMLResponse': $sigQuery = $name . '=' . $value; break; case 'RelayState': $relayState = '&RelayState=' . $value; break; case 'SigAlg': $sigAlg = '&SigAlg=' . $value; break; } } $result['SignedQuery'] = $sigQuery . $relayState . $sigAlg; return $result; } /** * @param string $queryString * @return array */ protected function parseQueryString($queryString) { $result = []; foreach (explode('&', $queryString ?: '') as $e) { $tmp = explode('=', $e, 2); $name = $tmp[0]; $value = 2 === count($tmp) ? $tmp[1] : ''; $name = urldecode($name); $result[$name] = $value; } return $result; } }