Skip to content

Commit

Permalink
Update php-saml to 3.3.1
Browse files Browse the repository at this point in the history
  • Loading branch information
pitbulk committed Nov 6, 2019
1 parent e5bbf9e commit bd9bb1f
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 33 deletions.
41 changes: 36 additions & 5 deletions auth/onelogin_saml/lib/Saml2/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ public function processSLO($keepLocalSession = false, $requestId = null, $retrie
$parameters['Signature'] = $signature;
}

return $this->redirectTo($this->getSLOurl(), $parameters, $stay);
return $this->redirectTo($this->getSLOResponseUrl(), $parameters, $stay);
}
} else {
$this->_errors[] = 'invalid_binding';
Expand Down Expand Up @@ -520,14 +520,15 @@ public function getAttributeWithFriendlyName($friendlyName)
* @param bool $isPassive When true the AuthNRequest will set the Ispassive='true'
* @param bool $stay True if we want to stay (returns the url string) False to redirect
* @param bool $setNameIdPolicy When true the AuthNRequest will set a nameIdPolicy element
* @param string $nameIdValueReq Indicates to the IdP the subject that should be authenticated
*
* @return string|null If $stay is True, it return a string with the SLO URL + LogoutRequest + parameters
*
*
* @throws Error
*/
public function login($returnTo = null, array $parameters = array(), $forceAuthn = false, $isPassive = false, $stay = false, $setNameIdPolicy = true)
public function login($returnTo = null, array $parameters = array(), $forceAuthn = false, $isPassive = false, $stay = false, $setNameIdPolicy = true, $nameIdValueReq = null)
{
$authnRequest = new AuthnRequest($this->_settings, $forceAuthn, $isPassive, $setNameIdPolicy);
$authnRequest = $this->buildAuthnRequest($this->_settings, $forceAuthn, $isPassive, $setNameIdPolicy, $nameIdValueReq);

$this->_lastRequest = $authnRequest->getXML();
$this->_lastRequestID = $authnRequest->getId();
Expand Down Expand Up @@ -632,6 +633,20 @@ public function getSLOurl()
return $url;
}

/**
* Gets the SLO response url.
*
* @return string|null The response url of the Single Logout Service
*/
public function getSLOResponseUrl()
{
$idpData = $this->_settings->getIdPData();
if (isset($idpData['singleLogoutService']) && isset($idpData['singleLogoutService']['responseUrl'])) {
return $idpData['singleLogoutService']['responseUrl'];
}
return $this->getSLOurl();
}

/**
* Gets the ID of the last AuthNRequest or LogoutRequest generated by the Service Provider.
*
Expand All @@ -642,6 +657,22 @@ public function getLastRequestID()
return $this->_lastRequestID;
}

/**
* Creates an AuthnRequest
*
* @param Settings $settings Setting data
* @param bool $forceAuthn When true the AuthNRequest will set the ForceAuthn='true'
* @param bool $isPassive When true the AuthNRequest will set the Ispassive='true'
* @param bool $setNameIdPolicy When true the AuthNRequest will set a nameIdPolicy element
* @param string $nameIdValueReq Indicates to the IdP the subject that should be authenticated
*
* @return AuthnRequest The AuthnRequest object
*/
public function buildAuthnRequest($settings, $forceAuthn, $isPassive, $setNameIdPolicy, $nameIdValueReq = null)
{
return new AuthnRequest($settings, $forceAuthn, $isPassive, $setNameIdPolicy, $nameIdValueReq);
}

/**
* Generates the Signature for a SAML Request
*
Expand Down Expand Up @@ -689,7 +720,7 @@ public function buildResponseSignature($samlResponse, $relayState, $signAlgorith
* @throws Exception
* @throws Error
*/
private function buildMessageSignature($samlMessage, $relayState, $signAlgorithm = XMLSecurityKey::RSA_SHA256, $type="SAMLRequest")
private function buildMessageSignature($samlMessage, $relayState, $signAlgorithm = XMLSecurityKey::RSA_SHA256, $type = "SAMLRequest")
{
$key = $this->_settings->getSPkey();
if (empty($key)) {
Expand Down
37 changes: 27 additions & 10 deletions auth/onelogin_saml/lib/Saml2/AuthnRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ class AuthnRequest
/**
* Constructs the AuthnRequest object.
*
* @param Settings $settings SAML Toolkit Settings
* @param bool $forceAuthn When true the AuthNReuqest will set the ForceAuthn='true'
* @param bool $isPassive When true the AuthNReuqest will set the Ispassive='true'
* @param bool $setNameIdPolicy When true the AuthNReuqest will set a nameIdPolicy
* @param Settings $settings SAML Toolkit Settings
* @param bool $forceAuthn When true the AuthNReuqest will set the ForceAuthn='true'
* @param bool $isPassive When true the AuthNReuqest will set the Ispassive='true'
* @param bool $setNameIdPolicy When true the AuthNReuqest will set a nameIdPolicy
* @param string $nameIdValueReq Indicates to the IdP the subject that should be authenticated
*/
public function __construct(\OneLogin\Saml2\Settings $settings, $forceAuthn = false, $isPassive = false, $setNameIdPolicy = true)
public function __construct(\OneLogin\Saml2\Settings $settings, $forceAuthn = false, $isPassive = false, $setNameIdPolicy = true, $nameIdValueReq = null)
{
$this->_settings = $settings;

Expand All @@ -60,6 +61,17 @@ public function __construct(\OneLogin\Saml2\Settings $settings, $forceAuthn = fa
$id = Utils::generateUniqueID();
$issueInstant = Utils::parseTime2SAML(time());

$subjectStr = "";
if (isset($nameIdValueReq)) {
$subjectStr = <<<SUBJECT
<saml:Subject>
<saml:NameID Format="{$spData['NameIDFormat']}">{$nameIdValueReq}</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"></saml:SubjectConfirmation>
</saml:Subject>
SUBJECT;
}

$nameIdPolicyStr = '';
if ($setNameIdPolicy) {
$nameIDPolicyFormat = $spData['NameIDFormat'];
Expand All @@ -68,6 +80,7 @@ public function __construct(\OneLogin\Saml2\Settings $settings, $forceAuthn = fa
}

$nameIdPolicyStr = <<<NAMEIDPOLICY
<samlp:NameIDPolicy
Format="{$nameIDPolicyFormat}"
AllowCreate="true" />
Expand Down Expand Up @@ -114,14 +127,20 @@ public function __construct(\OneLogin\Saml2\Settings $settings, $forceAuthn = fa
$authnComparison = $security['requestedAuthnContextComparison'];
}

$authnComparisonAttr = '';
if (!empty($authnComparison)) {
$authnComparisonAttr = sprintf('Comparison="%s"', $authnComparison);
}

if ($security['requestedAuthnContext'] === true) {
$requestedAuthnStr = <<<REQUESTEDAUTHN
<samlp:RequestedAuthnContext Comparison="$authnComparison">
<samlp:RequestedAuthnContext $authnComparisonAttr>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</samlp:RequestedAuthnContext>
REQUESTEDAUTHN;
} else {
$requestedAuthnStr .= " <samlp:RequestedAuthnContext Comparison=\"$authnComparison\">\n";
$requestedAuthnStr .= " <samlp:RequestedAuthnContext $authnComparisonAttr>\n";
foreach ($security['requestedAuthnContext'] as $contextValue) {
$requestedAuthnStr .= " <saml:AuthnContextClassRef>".$contextValue."</saml:AuthnContextClassRef>\n";
}
Expand All @@ -142,9 +161,7 @@ public function __construct(\OneLogin\Saml2\Settings $settings, $forceAuthn = fa
Destination="{$idpData['singleSignOnService']['url']}"
ProtocolBinding="{$spData['assertionConsumerService']['binding']}"
AssertionConsumerServiceURL="{$acsUrl}">
<saml:Issuer>{$spEntityId}</saml:Issuer>
{$nameIdPolicyStr}
{$requestedAuthnStr}
<saml:Issuer>{$spEntityId}</saml:Issuer>{$subjectStr}{$nameIdPolicyStr}{$requestedAuthnStr}
</samlp:AuthnRequest>
AUTHNREQUEST;

Expand Down
4 changes: 4 additions & 0 deletions auth/onelogin_saml/lib/Saml2/IdPMetadataParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public static function parseRemoteXML($url, $entityId = null, $desiredNameIdForm
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);

$xml = curl_exec($ch);
Expand All @@ -55,6 +56,7 @@ public static function parseRemoteXML($url, $entityId = null, $desiredNameIdForm
throw new Exception(curl_error($ch), curl_errno($ch));
}
} catch (Exception $e) {
throw new Exception('Error on parseRemoteXML. '.$e->getMessage());
}
return $metadataInfo;
}
Expand Down Expand Up @@ -83,6 +85,7 @@ public static function parseFileXML($filepath, $entityId = null, $desiredNameIdF
$metadataInfo = self::parseXML($data, $entityId, $desiredNameIdFormat, $desiredSSOBinding, $desiredSLOBinding);
}
} catch (Exception $e) {
throw new Exception('Error on parseFileXML. '.$e->getMessage());
}
return $metadataInfo;
}
Expand Down Expand Up @@ -155,6 +158,7 @@ public static function parseXML($xml, $entityId = null, $desiredNameIdFormat = n
if ($sloNodes->length > 0) {
$metadataInfo['idp']['singleLogoutService'] = array(
'url' => $sloNodes->item(0)->getAttribute('Location'),
'responseUrl' => $sloNodes->item(0)->getAttribute('ResponseLocation'),
'binding' => $sloNodes->item(0)->getAttribute('Binding')
);
}
Expand Down
4 changes: 2 additions & 2 deletions auth/onelogin_saml/lib/Saml2/Metadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ public static function builder($sp, $authnsign = false, $wsign = false, $validUn
* @param string $digestAlgorithm Digest algorithm method
*
* @return string Signed Metadata
*
*
* @throws Exception
*/
public static function signMetadata($metadata, $key, $cert, $signAlgorithm = XMLSecurityKey::RSA_SHA256, $digestAlgorithm = XMLSecurityDSig::SHA256)
Expand All @@ -217,7 +217,7 @@ public static function signMetadata($metadata, $key, $cert, $signAlgorithm = XML
* @param bool $wantsEncrypted Whether to include the KeyDescriptor for encryption
*
* @return string Metadata with KeyDescriptors
*
*
* @throws Exception
*/
public static function addX509KeyDescriptors($metadata, $cert, $wantsEncrypted = true)
Expand Down
54 changes: 40 additions & 14 deletions auth/onelogin_saml/lib/Saml2/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class Settings
*
* @var bool
*/
private $_strict = false;
private $_strict = true;

/**
* Activate debug mode
Expand Down Expand Up @@ -520,6 +520,14 @@ public function checkIdPSettings(array $settings)
$errors[] = 'idp_slo_url_invalid';
}

if (isset($idp['singleLogoutService'])
&& isset($idp['singleLogoutService']['responseUrl'])
&& !empty($idp['singleLogoutService']['responseUrl'])
&& !filter_var($idp['singleLogoutService']['responseUrl'], FILTER_VALIDATE_URL)
) {
$errors[] = 'idp_slo_response_url_invalid';
}

if (isset($settings['security'])) {
$security = $settings['security'];

Expand Down Expand Up @@ -588,8 +596,10 @@ public function checkSPSettings(array $settings)
}

if (isset($security['signMetadata']) && is_array($security['signMetadata'])) {
if (!isset($security['signMetadata']['keyFileName'])
|| !isset($security['signMetadata']['certFileName'])
if ((!isset($security['signMetadata']['keyFileName'])
|| !isset($security['signMetadata']['certFileName'])) &&
(!isset($security['signMetadata']['privateKey'])
|| !isset($security['signMetadata']['x509cert']))
) {
$errors[] = 'sp_signMetadata_invalid';
}
Expand Down Expand Up @@ -792,7 +802,7 @@ public function shouldCompressResponses()
*
* @param bool $alwaysPublishEncryptionCert When 'true', the returned
* metadata will always include an 'encryption' KeyDescriptor. Otherwise,
* the 'encryption' KeyDescriptor will only be included if
* the 'encryption' KeyDescriptor will only be included if
* $advancedSettings['security']['wantNameIdEncrypted'] or
* $advancedSettings['security']['wantAssertionsEncrypted'] are enabled.
* @param int|null $validUntil Metadata's valid time
Expand Down Expand Up @@ -825,7 +835,7 @@ public function getSPMetadata($alwaysPublishEncryptionCert = false, $validUntil
}

//Sign Metadata
if (isset($this->_security['signMetadata']) && $this->_security['signMetadata'] !== false) {
if (isset($this->_security['signMetadata']) && $this->_security['signMetadata'] != false) {
if ($this->_security['signMetadata'] === true) {
$keyMetadata = $this->getSPkey();
$certMetadata = $cert;
Expand All @@ -843,15 +853,8 @@ public function getSPMetadata($alwaysPublishEncryptionCert = false, $validUntil
Error::PUBLIC_CERT_FILE_NOT_FOUND
);
}
} else {
if (!isset($this->_security['signMetadata']['keyFileName'])
|| !isset($this->_security['signMetadata']['certFileName'])
) {
throw new Error(
'Invalid Setting: signMetadata value of the sp is not valid',
Error::SETTINGS_INVALID_SYNTAX
);
}
} else if (isset($this->_security['signMetadata']['keyFileName']) &&
isset($this->_security['signMetadata']['certFileName'])) {
$keyFileName = $this->_security['signMetadata']['keyFileName'];
$certFileName = $this->_security['signMetadata']['certFileName'];

Expand All @@ -875,6 +878,29 @@ public function getSPMetadata($alwaysPublishEncryptionCert = false, $validUntil
}
$keyMetadata = file_get_contents($keyMetadataFile);
$certMetadata = file_get_contents($certMetadataFile);
} else if (isset($this->_security['signMetadata']['privateKey']) &&
isset($this->_security['signMetadata']['x509cert'])) {
$keyMetadata = Utils::formatPrivateKey($this->_security['signMetadata']['privateKey']);
$certMetadata = Utils::formatCert($this->_security['signMetadata']['x509cert']);
if (!$keyMetadata) {
throw new Error(
'Private key not found.',
Error::PRIVATE_KEY_FILE_NOT_FOUND
);
}

if (!$certMetadata) {
throw new Error(
'Public cert not found.',
Error::PUBLIC_CERT_FILE_NOT_FOUND
);
}
} else {
throw new Error(
'Invalid Setting: signMetadata value of the sp is not valid',
Error::SETTINGS_INVALID_SYNTAX
);

}

$signatureAlgorithm = $this->_security['signatureAlgorithm'];
Expand Down
4 changes: 2 additions & 2 deletions auth/onelogin_saml/lib/Saml2/version.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"php-saml": {
"version": "3.1.0",
"released": "28/01/2019"
"version": "3.3.1",
"released": "06/11/2019"
}
}

0 comments on commit bd9bb1f

Please sign in to comment.