/** * Build the request we will send to the IdP. * * @param array $artifacts The artifacts we will request. * @return string The request, as an XML string. */ private static function buildRequest(array $artifacts) { $msg = '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">' . '<SOAP-ENV:Body>' . '<samlp:Request xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol"' . ' RequestID="' . SimpleSAML\Utils\Random::generateID() . '"' . ' MajorVersion="1" MinorVersion="1"' . ' IssueInstant="' . SimpleSAML\Utils\Time::generateTimestamp() . '"' . '>'; foreach ($artifacts as $a) { $msg .= '<samlp:AssertionArtifact>' . htmlspecialchars($a) . '</samlp:AssertionArtifact>'; } $msg .= '</samlp:Request>' . '</SOAP-ENV:Body>' . '</SOAP-ENV:Envelope>'; return $msg; }
public static function ADFS_GenerateResponse($issuer, $target, $nameid, $attributes) { $issueInstant = SimpleSAML\Utils\Time::generateTimestamp(); $notBefore = SimpleSAML\Utils\Time::generateTimestamp(time() - 30); $assertionExpire = SimpleSAML\Utils\Time::generateTimestamp(time() + 60 * 5); $assertionID = SimpleSAML\Utils\Random::generateID(); $nameidFormat = 'http://schemas.xmlsoap.org/claims/UPN'; $result = '<wst:RequestSecurityTokenResponse xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust"> <wst:RequestedSecurityToken> <saml:Assertion Issuer="' . $issuer . '" IssueInstant="' . $issueInstant . '" AssertionID="' . $assertionID . '" MinorVersion="1" MajorVersion="1" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"> <saml:Conditions NotOnOrAfter="' . $assertionExpire . '" NotBefore="' . $notBefore . '"> <saml:AudienceRestrictionCondition> <saml:Audience>' . $target . '</saml:Audience> </saml:AudienceRestrictionCondition> </saml:Conditions> <saml:AuthenticationStatement AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:unspecified" AuthenticationInstant="' . $issueInstant . '"> <saml:Subject> <saml:NameIdentifier Format="' . $nameidFormat . '">' . htmlspecialchars($nameid) . '</saml:NameIdentifier> </saml:Subject> </saml:AuthenticationStatement> <saml:AttributeStatement> <saml:Subject> <saml:NameIdentifier Format="' . $nameidFormat . '">' . htmlspecialchars($nameid) . '</saml:NameIdentifier> </saml:Subject>'; foreach ($attributes as $name => $values) { if (!is_array($values) || count($values) == 0) { continue; } $hasValue = FALSE; $r = '<saml:Attribute AttributeNamespace="http://schemas.xmlsoap.org/claims" AttributeName="' . htmlspecialchars($name) . '">'; foreach ($values as $value) { if (!isset($value) || $value === '') { continue; } $r .= '<saml:AttributeValue>' . htmlspecialchars($value) . '</saml:AttributeValue>'; $hasValue = TRUE; } $r .= '</saml:Attribute>'; if ($hasValue) { $result .= $r; } } $result .= ' </saml:AttributeStatement> </saml:Assertion> </wst:RequestedSecurityToken> <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"><wsa:EndpointReference xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"> <wsa:Address>' . $target . '</wsa:Address> </wsa:EndpointReference></wsp:AppliesTo> </wst:RequestSecurityTokenResponse>'; return $result; }
/** * Build a new logging handler based on files. */ public function __construct() { $config = SimpleSAML_Configuration::getInstance(); assert($config instanceof SimpleSAML_Configuration); // get the metadata handler option from the configuration $this->logFile = $config->getPathValue('loggingdir', 'log/') . $config->getString('logging.logfile', 'simplesamlphp.log'); $this->processname = $config->getString('logging.processname', 'SimpleSAMLphp'); if (@file_exists($this->logFile)) { if (!@is_writeable($this->logFile)) { throw new Exception("Could not write to logfile: " . $this->logFile); } } else { if (!@touch($this->logFile)) { throw new Exception("Could not create logfile: " . $this->logFile . " Loggingdir is not writeable for the webserver user."); } } SimpleSAML\Utils\Time::initTimezone(); }
/** * Build a authentication response. * * @param array $idp Metadata for the IdP the response is sent from. * @param array $sp Metadata for the SP the response is sent to. * @param string $shire The endpoint on the SP the response is sent to. * @param array|NULL $attributes The attributes which should be included in the response. * @return string The response. */ public function generate(SimpleSAML_Configuration $idp, SimpleSAML_Configuration $sp, $shire, $attributes) { assert('is_string($shire)'); assert('$attributes === NULL || is_array($attributes)'); if ($sp->hasValue('scopedattributes')) { $scopedAttributes = $sp->getArray('scopedattributes'); } elseif ($idp->hasValue('scopedattributes')) { $scopedAttributes = $idp->getArray('scopedattributes'); } else { $scopedAttributes = array(); } $id = SimpleSAML\Utils\Random::generateID(); $issueInstant = SimpleSAML\Utils\Time::generateTimestamp(); // 30 seconds timeskew back in time to allow differing clocks. $notBefore = SimpleSAML\Utils\Time::generateTimestamp(time() - 30); $assertionExpire = SimpleSAML\Utils\Time::generateTimestamp(time() + 60 * 5); # 5 minutes $assertionid = SimpleSAML\Utils\Random::generateID(); $spEntityId = $sp->getString('entityid'); $audience = $sp->getString('audience', $spEntityId); $base64 = $sp->getBoolean('base64attributes', FALSE); $namequalifier = $sp->getString('NameQualifier', $spEntityId); $nameid = SimpleSAML\Utils\Random::generateID(); $subjectNode = '<Subject>' . '<NameIdentifier' . ' Format="urn:mace:shibboleth:1.0:nameIdentifier"' . ' NameQualifier="' . htmlspecialchars($namequalifier) . '"' . '>' . htmlspecialchars($nameid) . '</NameIdentifier>' . '<SubjectConfirmation>' . '<ConfirmationMethod>' . 'urn:oasis:names:tc:SAML:1.0:cm:bearer' . '</ConfirmationMethod>' . '</SubjectConfirmation>' . '</Subject>'; $encodedattributes = ''; if (is_array($attributes)) { $encodedattributes .= '<AttributeStatement>'; $encodedattributes .= $subjectNode; foreach ($attributes as $name => $value) { $encodedattributes .= $this->enc_attribute($name, $value, $base64, $scopedAttributes); } $encodedattributes .= '</AttributeStatement>'; } /* * The SAML 1.1 response message */ $response = '<Response xmlns="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" IssueInstant="' . $issueInstant . '" MajorVersion="1" MinorVersion="1" Recipient="' . htmlspecialchars($shire) . '" ResponseID="' . $id . '"> <Status> <StatusCode Value="samlp:Success" /> </Status> <Assertion xmlns="urn:oasis:names:tc:SAML:1.0:assertion" AssertionID="' . $assertionid . '" IssueInstant="' . $issueInstant . '" Issuer="' . htmlspecialchars($idp->getString('entityid')) . '" MajorVersion="1" MinorVersion="1"> <Conditions NotBefore="' . $notBefore . '" NotOnOrAfter="' . $assertionExpire . '"> <AudienceRestrictionCondition> <Audience>' . htmlspecialchars($audience) . '</Audience> </AudienceRestrictionCondition> </Conditions> <AuthenticationStatement AuthenticationInstant="' . $issueInstant . '" AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:unspecified">' . $subjectNode . ' </AuthenticationStatement> ' . $encodedattributes . ' </Assertion> </Response>'; return $response; }
* See PHP bug: https://bugs.php.net/bug.php?id=47987 */ return false; } if ($errno & SimpleSAML_Utilities::$logMask || !($errno & error_reporting())) { // masked error return false; } static $limit = 5; $limit -= 1; if ($limit < 0) { // we have reached the limit in the number of backtraces we will log return false; } // show an error with a full backtrace $e = new SimpleSAML_Error_Exception('Error ' . $errno . ' - ' . $errstr); $e->logError(); // resume normal error processing return false; } set_error_handler('SimpleSAML_error_handler'); $configdir = SimpleSAML\Utils\Config::getConfigDir(); if (!file_exists($configdir . '/config.php')) { header('Content-Type: text/plain'); echo "You have not yet created the simpleSAMLphp configuration files.\n"; echo "See: https://simplesamlphp.org/docs/devel/simplesamlphp-install-repo\n"; exit(1); } // set the timezone SimpleSAML\Utils\Time::initTimezone();
/** * This function lists all known metadata in the given set. It is returned as an associative array * where the key is the entity id. * * @param string $set The set we want to list metadata from. * * @return array An associative array with the metadata from from the given set. */ public function getList($set = 'saml20-idp-remote') { assert('is_string($set)'); $result = array(); foreach ($this->sources as $source) { $srcList = $source->getMetadataSet($set); foreach ($srcList as $key => $le) { if (array_key_exists('expire', $le)) { if ($le['expire'] < time()) { unset($srcList[$key]); SimpleSAML_Logger::warning("Dropping metadata entity " . var_export($key, true) . ", expired " . SimpleSAML\Utils\Time::generateTimestamp($le['expire']) . "."); } } } /* $result is the last argument to array_merge because we want the content already * in $result to have precedence. */ $result = array_merge($srcList, $result); } return $result; }
/** * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Utils\Time::parseDuration() instead. */ public static function parseDuration($duration, $timestamp = NULL) { return SimpleSAML\Utils\Time::parseDuration($duration, $timestamp); }