generateTimestamp() public static method

Deprecation: This method will be removed in SSP 2.0. Please use \SimpleSAML\Utils\Time::generateTimestamp() instead.
public static generateTimestamp ( $instant = null )
 /**
  * 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_Utilities::generateID() . '"' . ' MajorVersion="1" MinorVersion="1"' . ' IssueInstant="' . SimpleSAML_Utilities::generateTimestamp() . '"' . '>';
     foreach ($artifacts as $a) {
         $msg .= '<samlp:AssertionArtifact>' . htmlspecialchars($a) . '</samlp:AssertionArtifact>';
     }
     $msg .= '</samlp:Request>' . '</SOAP-ENV:Body>' . '</SOAP-ENV:Envelope>';
     return $msg;
 }
Example #2
0
    public static function ADFS_GenerateResponse($issuer, $target, $nameid, $attributes)
    {
        #$nameid = '*****@*****.**';
        $issueInstant = SimpleSAML_Utilities::generateTimestamp();
        $notBefore = SimpleSAML_Utilities::generateTimestamp(time() - 30);
        $assertionExpire = SimpleSAML_Utilities::generateTimestamp(time() + 60 * 5);
        $assertionID = SimpleSAML_Utilities::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) or $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;
    }
Example #3
0
 private function setExpiration($metadata)
 {
     if (array_key_exists('expire', $metadata)) {
         if ($metadata['expire'] - time() < $this->maxDuration) {
             $this->maxDuration = $metadata['expire'] - time();
         }
     }
     if ($this->maxCache !== NULL) {
         $this->entityDescriptor->setAttribute('cacheDuration', 'PT' . $this->maxCache . 'S');
     }
     if ($this->maxDuration !== NULL) {
         $this->entityDescriptor->setAttribute('validUntil', SimpleSAML_Utilities::generateTimestamp(time() + $this->maxDuration));
     }
 }
    /**
     * 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_Utilities::generateID();
        $issueInstant = SimpleSAML_Utilities::generateTimestamp();
        // 30 seconds timeskew back in time to allow differing clocks.
        $notBefore = SimpleSAML_Utilities::generateTimestamp(time() - 30);
        $assertionExpire = SimpleSAML_Utilities::generateTimestamp(time() + 60 * 5);
        # 5 minutes
        $assertionid = SimpleSAML_Utilities::generateID();
        $spEntityId = $sp->getString('entityid');
        $audience = $sp->getString('audience', $spEntityId);
        $base64 = $sp->getBoolean('base64attributes', FALSE);
        $namequalifier = $sp->getString('NameQualifier', $spEntityId);
        $nameid = SimpleSAML_Utilities::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;
    }
Example #5
0
    /**
     * 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($idp, $sp, $shire, $attributes)
    {
        assert('is_array($idp)');
        assert('is_array($sp)');
        assert('is_string($shire)');
        assert('$attributes === NULL || is_array($attributes)');
        if (array_key_exists('scopedattributes', $sp)) {
            $scopedAttributes = $sp['scopedattributes'];
            $scopedAttributesSource = 'the shib13-sp-remote sp \'' . $sp['entityid'] . '\'';
        } elseif (array_key_exists('scopedattributes', $idp)) {
            $scopedAttributes = $idp['scopedattributes'];
            $scopedAttributesSource = 'the shib13-idp-hosted idp \'' . $idp['entityid'] . '\'';
        } else {
            $scopedAttributes = array();
        }
        if (!is_array($scopedAttributes)) {
            throw new Exception('The \'scopedattributes\' option in ' . $scopedAttributesSource . ' should be an array of attribute names.');
        }
        foreach ($scopedAttributes as $an) {
            if (!is_string($an)) {
                throw new Exception('Invalid attribute name in the \'scopedattributes\' option in ' . $scopedAttributesSource . ': ' . var_export($an, TRUE));
            }
        }
        $id = SimpleSAML_Utilities::generateID();
        $issueInstant = SimpleSAML_Utilities::generateTimestamp();
        // 30 seconds timeskew back in time to allow differing clocks.
        $notBefore = SimpleSAML_Utilities::generateTimestamp(time() - 30);
        $assertionExpire = SimpleSAML_Utilities::generateTimestamp(time() + 60 * 5);
        # 5 minutes
        $assertionid = SimpleSAML_Utilities::generateID();
        $audience = isset($sp['audience']) ? $sp['audience'] : $sp['entityid'];
        $base64 = isset($sp['base64attributes']) ? $sp['base64attributes'] : false;
        $namequalifier = isset($sp['NameQualifier']) ? $sp['NameQualifier'] : $sp['entityid'];
        $nameid = SimpleSAML_Utilities::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['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;
    }
 /**
  * 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 $set  The set we want to list metadata from.
  * @return 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_Utilities::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;
 }
}
$ssp_metadata = '// Metadata for state "' . $export_state . '"';
// Generate metadata
try {
    $maxCache = $janus_config->getValue('maxCache', NULL);
    $maxDuration = $janus_config->getValue('maxDuration', NULL);
    $entities = $util->getEntitiesByStateType($export_state, $export_type);
    $xml = new DOMDocument();
    $entitiesDescriptor = $xml->createElementNS('urn:oasis:names:tc:SAML:2.0:metadata', 'md:EntitiesDescriptor');
    $entitiesDescriptorName = $janus_config->getString('export.entitiesDescriptorName', 'Federation');
    $entitiesDescriptor->setAttribute('Name', $entitiesDescriptorName);
    if ($maxCache !== NULL) {
        $entitiesDescriptor->setAttribute('cacheDuration', 'PT' . $maxCache . 'S');
    }
    if ($maxDuration !== NULL) {
        $entitiesDescriptor->setAttribute('validUntil', SimpleSAML_Utilities::generateTimestamp(time() + $maxDuration));
    }
    $xml->appendChild($entitiesDescriptor);
    foreach ($entities as $entity) {
        $entityDescriptor = sspmod_janus_MetaExport::getXMLMetadata($entity['eid'], $entity['revisionid'], array('maxCache' => $maxCache, 'maxDuration' => $maxDuration));
        $ssp_metadata = $ssp_metadata . "\n\n" . sspmod_janus_MetaExport::getFlatMetadata($entity['eid'], $entity['revisionid']);
        if (empty($entityDescriptor)) {
            $t = new SimpleSAML_XHTML_Template($config, 'janus:error.php', 'janus:error');
            $t->data['header'] = 'JANUS';
            $t->data['title'] = 'error_required_metadata_missing_header';
            $t->data['error'] = 'error_required_metadata_missing_entity';
            $t->data['error_data'] = array('%ENTITY%' => $entity['entityid']);
            $t->data['extra_data'] = implode("\n", sspmod_janus_MetaExport::getError());
            $t->show();
            exit(0);
        }
    /**
     * This function generates an AuthenticationResponse
     *
     *  @param $idpentityid   entityid of IdP
     *  @param $spentityid    entityid of SP
     *  @param $inresponseto  the ID of the request, that these message is an response to.
     *  @param $nameid        the NameID of the user (an array)
     *  @param $attributes    A two level array of multivalued attributes, where the first level
     *   index is the attribute name.
     *
     *  @return AuthenticationResponse as string
     */
    public function generate($idpentityid, $spentityid, $inresponseto, $nameid, $attributes, $status = 'Success')
    {
        /**
         * Retrieving metadata for the two specific entity IDs.
         */
        $idpmd = $this->metadata->getMetaData($idpentityid, 'saml20-idp-hosted');
        $spmd = $this->metadata->getMetaData($spentityid, 'saml20-sp-remote');
        $issuer = $idpentityid;
        $destination = $spmd['AssertionConsumerService'];
        /**
         * Generating IDs and timestamps.
         */
        $id = SimpleSAML_Utilities::generateID();
        $issueInstant = SimpleSAML_Utilities::generateTimestamp();
        $assertionExpire = SimpleSAML_Utilities::generateTimestamp(time() + 60 * 5);
        # 5 minutes
        $notBefore = SimpleSAML_Utilities::generateTimestamp(time() - 30);
        $assertionid = SimpleSAML_Utilities::generateID();
        $sessionindex = SimpleSAML_Utilities::generateID();
        /**
         * Handling attributes.
         */
        $base64 = isset($spmd['base64attributes']) ? $spmd['base64attributes'] : false;
        $nameidformat = isset($spmd['NameIDFormat']) ? $spmd['NameIDFormat'] : 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient';
        $spnamequalifier = isset($spmd['SPNameQualifier']) ? $spmd['SPNameQualifier'] : $spmd['entityid'];
        // Attribute Name Format handling. Priority is 1) SP metadata 2) IdP metadata 3) default setting
        $attributeNameFormat = 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic';
        if (isset($spmd['AttributeNameFormat'])) {
            $attributeNameFormat = $spmd['AttributeNameFormat'];
        } elseif (isset($idpmd['AttributeNameFormat'])) {
            $attributeNameFormat = $idpmd['AttributeNameFormat'];
        }
        $encodedattributes = '';
        foreach ($attributes as $name => $values) {
            $encodedattributes .= self::enc_attribute($name, $values, $base64, $attributeNameFormat);
        }
        $attributestatement = '<saml:AttributeStatement>' . $encodedattributes . '</saml:AttributeStatement>';
        $sendattributes = isset($spmd['simplesaml.attributes']) ? $spmd['simplesaml.attributes'] : true;
        if (!$sendattributes) {
            $attributestatement = '';
        }
        /**
         * Handling NameID
         */
        $nameid = null;
        if ($nameidformat == self::EMAIL) {
            //print "<pre>SPMD<br>";
            //print_r($spmd);
            //print "<hr>";
            //print_r($spmd['simplesaml.nameidattribute']);
            //print "<hr>ATTRIBUTES<br>";
            //print_r($attributes);
            //print "</pre>";
            //print "<hr>";
            $nameid = $this->generateNameID($nameidformat, $attributes[$spmd['simplesaml.nameidattribute']][0], $spnamequalifier);
        } else {
            $nameid = $this->generateNameID($nameidformat, SimpleSAML_Utilities::generateID(), $spnamequalifier);
        }
        $assertion = "";
        if ($status === 'Success') {
            $assertion = '<saml:Assertion Version="2.0"
		ID="' . $assertionid . '" IssueInstant="' . $issueInstant . '">
		<saml:Issuer>' . htmlspecialchars($issuer) . '</saml:Issuer>
		<saml:Subject>
			' . $nameid . ' 
			<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
				<saml:SubjectConfirmationData NotOnOrAfter="' . $assertionExpire . '"
					InResponseTo="' . htmlspecialchars($inresponseto) . '"
					Recipient="' . htmlspecialchars($destination) . '"/>
			</saml:SubjectConfirmation>
		</saml:Subject>
		<saml:Conditions NotBefore="' . $notBefore . '" NotOnOrAfter="' . $assertionExpire . '">
            <saml:AudienceRestriction>
                <saml:Audience>' . htmlspecialchars($spentityid) . '</saml:Audience>
            </saml:AudienceRestriction>
		</saml:Conditions> 
		<saml:AuthnStatement AuthnInstant="' . $issueInstant . '"
			SessionIndex="' . htmlspecialchars($sessionindex) . '">
			<saml:AuthnContext>
				<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
			</saml:AuthnContext>
        </saml:AuthnStatement>
        ' . $attributestatement . '
    </saml:Assertion>';
        }
        /**
         * Generating the response.
         */
        $authnResponse = '<samlp:Response 
			xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" 
			xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" 
			xmlns:xs="http://www.w3.org/2001/XMLSchema"
			xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
			ID="' . $id . '"
			InResponseTo="' . htmlspecialchars($inresponseto) . '" Version="2.0"
			IssueInstant="' . $issueInstant . '"
			Destination="' . htmlspecialchars($destination) . '">
			<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">' . htmlspecialchars($issuer) . '</saml:Issuer>
			<samlp:Status xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
				<samlp:StatusCode xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
				Value="urn:oasis:names:tc:SAML:2.0:status:' . $status . '" />
			</samlp:Status>' . $assertion . '</samlp:Response>';
        return $authnResponse;
    }
    /**
     * Generate a new SAML 2.0 Authentication Request
     *
     * @param $spentityid SP Entity ID
     * @param $destination SingleSignOnService endpoint
     */
    public function generate($spentityid, $destination)
    {
        $md = $this->metadata->getMetaData($spentityid);
        $id = SimpleSAML_Utilities::generateID();
        $issueInstant = SimpleSAML_Utilities::generateTimestamp();
        $assertionConsumerServiceURL = $this->metadata->getGenerated('AssertionConsumerService', 'saml20-sp-hosted');
        /*
         * Process the SAML 2.0 SP hosted metadata parameter: NameIDFormat
         */
        $nameidformat = 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient';
        $includeNameIDPolicy = true;
        if (array_key_exists('NameIDFormat', $md)) {
            if (is_null($md['NameIDFormat'])) {
                $includeNameIDPolicy = false;
            } elseif (!is_string($md['NameIDFormat'])) {
                throw new Exception('SAML 2.0 SP hosted metadata parameter [NameIDFormat] must be a string.');
            } else {
                $nameidformat = $md['NameIDFormat'];
            }
        }
        if ($includeNameIDPolicy) {
            $nameIDPolicy = $this->generateNameIDPolicy($nameidformat);
        }
        /*
         * Process the SAML 2.0 SP hosted metadata parameter: ForceAuthn
         */
        $forceauthn = 'false';
        if (isset($md['ForceAuthn'])) {
            if (is_bool($md['ForceAuthn'])) {
                $forceauthn = $md['ForceAuthn'] ? 'true' : 'false';
            } else {
                throw new Exception('Illegal format of the ForceAuthn parameter in the SAML 2.0 SP hosted metadata for entity [' . $spentityid . ']. This value should be set to a PHP boolean value.');
            }
        }
        /*
         * Process the SAML 2.0 SP hosted metadata parameter: AuthnContextClassRef
         */
        $requestauthncontext = '';
        if (!empty($md['AuthnContextClassRef'])) {
            if (!is_string($md['AuthnContextClassRef'])) {
                throw new Exception('SAML 2.0 SP hosted metadata parameter [AuthnContextClassRef] must be a string.');
            }
            $requestauthncontext = '<samlp:RequestedAuthnContext Comparison="exact">
		<saml:AuthnContextClassRef>' . $md['AuthnContextClassRef'] . '</saml:AuthnContextClassRef>
	</samlp:RequestedAuthnContext>';
        }
        /* Check the metadata for isPassive if $this->isPassive === NULL. */
        if ($this->isPassive === NULL) {
            /*
             * Process the SAML 2.0 SP hosted metadata parameter: IsPassive
             */
            if (isset($md['IsPassive'])) {
                if (is_bool($md['IsPassive'])) {
                    $this->isPassive = $md['IsPassive'] ? 'true' : 'false';
                } else {
                    throw new Exception('Illegal format of the IsPassive parameter in' . ' the SAML 2.0 SP hosted metadata for entity [' . $spentityid . ']. This value should be set to a PHP boolean value.');
                }
            } else {
                /* The default is off. */
                $this->isPassive = 'false';
            }
        }
        /*
         * Create the complete SAML 2.0 Authentication Request
         */
        $authnRequest = '<samlp:AuthnRequest 
	xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
	ID="' . $id . '" Version="2.0"
	IssueInstant="' . $issueInstant . '" ForceAuthn="' . $forceauthn . '" IsPassive="' . $this->isPassive . '"
	Destination="' . htmlspecialchars($destination) . '"
	ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
	AssertionConsumerServiceURL="' . htmlspecialchars($assertionConsumerServiceURL) . '">
	<saml:Issuer >' . htmlspecialchars($spentityid) . '</saml:Issuer>
	' . $nameIDPolicy . '
	' . $requestauthncontext . '
</samlp:AuthnRequest>
';
        return $authnRequest;
    }
    public function generate($issuer, $receiver, $nameid, $sessionindex, $mode)
    {
        if (!in_array($mode, array('SP', 'IdP'))) {
            throw new Exception('mode parameter of generate() must be either SP or IdP');
        }
        if ($mode == 'IdP') {
            $issuerset = 'saml20-idp-hosted';
            $receiverset = 'saml20-sp-remote';
        } else {
            $issuerset = 'saml20-sp-hosted';
            $receiverset = 'saml20-idp-remote';
        }
        $issuermd = $this->metadata->getMetaData($issuer, $issuerset);
        $receivermd = $this->metadata->getMetaData($receiver, $receiverset);
        if ($mode == 'IdP') {
            $spnamequalifier = isset($receivermd['SPNameQualifier']) ? $receivermd['SPNameQualifier'] : $receivermd['entityid'];
        } else {
            $spnamequalifier = isset($issuermd['SPNameQualifier']) ? $issuermd['SPNameQualifier'] : $issuermd['entityid'];
        }
        $issueInstant = SimpleSAML_Utilities::generateTimestamp();
        $destination = $receivermd['SingleLogoutService'];
        $logoutRequest = '<samlp:LogoutRequest 
    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
    ID="' . $this->id . '" Version="2.0"
    Destination="' . htmlspecialchars($destination) . '"
    IssueInstant="' . $issueInstant . '">
    <saml:Issuer >' . htmlspecialchars($issuer) . '</saml:Issuer>
    <saml:NameID Format="' . htmlspecialchars($nameid['Format']) . '" SPNameQualifier="' . htmlspecialchars($spnamequalifier) . '">' . htmlspecialchars($nameid['value']) . '</saml:NameID>
    <samlp:SessionIndex>' . htmlspecialchars($sessionindex) . '</samlp:SessionIndex>
</samlp:LogoutRequest>
';
        return $logoutRequest;
    }
    public function generate($issuer, $receiver, $inresponseto, $mode)
    {
        if (!in_array($mode, array('SP', 'IdP'))) {
            throw new Exception('mode parameter of generate() must be either SP or IdP');
        }
        if ($mode == 'IdP') {
            $issuerset = 'saml20-idp-hosted';
            $receiverset = 'saml20-sp-remote';
        } else {
            $issuerset = 'saml20-sp-hosted';
            $receiverset = 'saml20-idp-remote';
        }
        //echo 'idp:' . $idpentityid . ' sp:' . $spentityid .' inresponseto:' .  $inresponseto . ' namid:' . $nameid;
        $issuermd = $this->metadata->getMetaData($issuer, $issuerset);
        $receivermd = $this->metadata->getMetaData($receiver, $receiverset);
        $id = SimpleSAML_Utilities::generateID();
        $issueInstant = SimpleSAML_Utilities::generateTimestamp();
        $destination = $receivermd['SingleLogoutService'];
        $samlResponse = '<samlp:LogoutResponse 
    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
    ID="' . $id . '" Version="2.0"
    IssueInstant="' . $issueInstant . '"
    Destination="' . htmlspecialchars($destination) . '"
    InResponseTo="' . htmlspecialchars($inresponseto) . '">
    <saml:Issuer>' . htmlspecialchars($issuer) . '</saml:Issuer>
    <samlp:Status>
        <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"> </samlp:StatusCode>
        <samlp:StatusMessage>Successfully logged out from service ' . htmlspecialchars($issuer) . '</samlp:StatusMessage>
    </samlp:Status>
</samlp:LogoutResponse>
';
        return $samlResponse;
    }